Як вивести погляд перед усім?


130

У мене є активність і багато віджетів на ньому, деякі з них мають анімацію, а через анімацію деякі з віджетів переміщуються (переводяться) один на інший. Наприклад, перегляд тексту переміщується над деякими кнопками. . .

Тепер справа в тому, що я хочу, щоб кнопки були завжди спереду. А коли перегляд тексту рухається, я хочу рухатися за кнопками.

Я не можу цього домогтися, я спробував усе, що знаю, і "doneToFront ()" точно не працює.

Зауважте, я не хочу контролювати z-порядок в порядку розміщення елемента до макета, тому що я просто не можу :), макет складний, і я не можу розміщувати всі кнопки на випробовуванні макета


3
Я використовував RelativeLayoutперегляд "зверху", який останнім виглядає в XML. Див stackoverflow.com/a/31340762/1121497
Ферран Maylinch

будь-хто, будь ласка, скажіть відповідний код у xml «doneToFront»
Shirish Herwade

Спробуйте використовувати висоту bottomView = висота: 1dp і topView = висота: 2dp у вашому xml || ViewCompat.setElevation (View, int)
Tlacaelel Рамон Луїс

Відповіді:


144

Ви можете зателефонувати doneToFront () на подання, яке ви хочете отримати спереду

Це приклад:

    yourView.bringToFront();

4
Несподіваний результат: я використав, що у вертикальній лінійній компоновці і вигляд, виведений на фронт, з'явився внизу ... Наприклад, я мав A / B / Cі хотів вивести Aна передню a.bringToFront()частину , тому після запуску я закінчив такий макет B / C / A.
Ферран Мейлінч

2
Тому я виявив, що LinearLayoutне можна використовувати bringToFront. Я в кінцевому рахунку використовував a RelativeLayout. Дивіться мій коментар до самого питання.
Ферран Мейлінч

1
будь-хто, будь ласка, скажіть відповідний код у xml «doneToFront»
Shirish Herwade

Це призводить до перестановки елемента, з якого я рухаюся на фронт з будь-якої причини. ViewCompat.setTranslationZ(view, 1)прекрасно працює з іншого боку.
Бімде

1
якщо я використовував у manifest android: theme = "@ android: style / Theme.Light.NoTitleBar" у діяльності, ніж yourView.bringToFront (); працює відмінно, але я використовував android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); не працює. Будь-яка підказка про це.
Рахул

42

Я переглядав переповнення стека, щоб знайти гарну відповідь, і коли я не міг знайти його, я переглянув документи.

Ніхто ще не натрапив на цю просту відповідь:

ViewCompat.setTranslationZ(view, translationZ);

за замовчуванням переклад z дорівнює 0,0


Це положення елемента на осі Z у px, також відомому як висота. setTranslationX перемістить подання по осі X (ліворуч / праворуч), встановимоTranslationY по осі Y (верхній / нижній). Вісь Z - 3-та вісь.
xdevs23

Про що setZ()? Якщо я пригадую правильно, то позиція Z - це його висота плюс переклад Z, зрештою.
Gensoukyou1337

2
@ Gensoukyou1337, то ViewCompat.setZ(view, yourValueInPixels); view.setZ()працює лише на API 21 і новіших версій .
Джонні П'ять

1
Перевірено код Java 8 в Android Studio - він перевіряє, чи SDK_INT> = 21, тому для <21 api це не має ефекту.
Вадим

32

Ще простішим рішенням є редагування XML діяльності. Використовуйте

android:translationZ=""

3
Це корисно лише в Android API 21 або вище.
isakbob

25

bringToFront()це правильний шлях, але, ВКАЗАТИ, що ви повинні зателефонувати bringToFront()та скористатися invalidate()методом перегляду найвищого рівня (під кореневим видом), наприклад:

Ієрархія вашого перегляду:

-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6

Отже, коли ви анімуєте свої кнопки назад (1-> 6), ваші кнопки будуть розташовані під (нижче) ImageView. Щоб перенести це (вище), ImageViewви повинні зателефонувати bringToFront()та скористатися invalidate()методом на своєму LinearLayouts. Тоді це спрацює :) ** ПРИМІТКА. Не забудьте встановити android:clipChildren="false"для вашого макета кореня або анонімного перегляду gradparent_layout. Давайте подивимось на мій реальний код:

.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:hw="http://schemas.android.com/apk/res-auto"
    android:id="@+id/layout_parent"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/common_theme_color"
    android:orientation="vertical" >

    <com.binh.helloworld.customviews.HWActionBar
        android:id="@+id/action_bar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dimen_actionbar_height"
        android:layout_alignParentTop="true"
        hw:titleText="@string/app_name" >
    </com.binh.helloworld.customviews.HWActionBar>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/action_bar"
        android:clipChildren="false" >

        <LinearLayout
            android:id="@+id/layout_top"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentTop="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>

        <ImageView
            android:id="@+id/imgv_main"
            android:layout_width="@dimen/common_imgv_height"
            android:layout_height="@dimen/common_imgv_height"
            android:layout_centerInParent="true"
            android:contentDescription="@string/app_name"
            android:src="@drawable/ic_launcher" />

        <LinearLayout
            android:id="@+id/layout_bottom"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:gravity="center_horizontal"
            android:orientation="horizontal" >
        </LinearLayout>
    </RelativeLayout>

</RelativeLayout>

Деякий код у .java

private LinearLayout layoutTop, layoutBottom;
...
layoutTop = (LinearLayout) rootView.findViewById(R.id.layout_top);
layoutBottom = (LinearLayout) rootView.findViewById(R.id.layout_bottom);
...
//when animate back
//dragedView is my layoutTop's child view (i added programmatically) (like buttons in above example) 
dragedView.setVisibility(View.GONE);
layoutTop.bringToFront();
layoutTop.invalidate();
dragedView.startAnimation(animation); // TranslateAnimation
dragedView.setVisibility(View.VISIBLE);

ГЛЮК!


що робити, якщо ви хочете лише навести кнопку 6 над зображенням зображення, а не інші кнопки?
Адам Кац

@AdamKatz: Я думаю, ви повинні переорганізувати їх у кулак іншого рівня. Потім принесіть це на своєму шляху.
Джастін

спасибі, я намагаюсь лише один предмет рециркулятора переглянути над переглядом, але залишити інші елементи під ним, досить застряг!
Адам Кац

Я використовував те саме. Це добре працює з єдиною проблемою, яку він приховує на панелі інструментів.
користувач2980181

Чи працює це з декількома рівнями? Скажімо, у мене є a, ConstraintLayoutщо містить a RelativeLayout, і інше RelativeLayout, обидва мають однаковий розмір, як і його root ConstraintLayout( match_parent). Перший RelativeLayoutмає a Button, а також позаду (z-порядку) другий RelativeLayout. Чи можу я зробити так, щоб Buttonперший RelativeLayoutз’явився так, ніби він був поверх усього, таким, що його можна побачити і натискати, використовуючи View::bringToFront()?
oaskamay


18

Спробуйте FrameLayout, це дає можливість ставити погляди один над одним. Ви можете створити два LinearLayouts: один із поданнями фону та один із видом переднього плану та об'єднати їх за допомогою FrameLayout. Сподіваюся, це допомагає.


1
Як ми можемо довести його до вершини так само, як діалог?
Гаурав Арора

@ Infinity, Ви можете створити FragmentDialog для цієї мети або просто використовувати Theme.Dialog для своєї діяльності.
Єгор

Я не можу використовувати FragmentDialog, оскільки його несумісний з API 10. По-друге, я вже використовую тему для свого застосування. Чи є інший спосіб? Я використовував його FrameLayout так, як ви сказали!
Гаурав Арора

@Infinity, Ви можете використовувати сумісність бібліотеки версії FragmentDialog, яка доступна з API 4.
Єгор

8

Якщо ви використовуєте ConstraintLayout, просто покладіть елемент за іншими елементами, щоб зробити його спереду, ніж інші



3

Існує й інший спосіб, який економить день. Просто запустіть новий Діалог із потрібним макетом та просто покажіть його. Мені це потрібно для показу loadingView через DialogFragment, і це був єдиний спосіб досягти успіху.

Dialog topDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
topDialog.setContentView(R.layout.dialog_top);
topDialog.show();

doneToFront () може не працювати в деяких випадках, як у мене. Але вміст макета dialog_top повинно перевищувати що-небудь на шарі ui. Але все одно це потворне вирішення.


3

я зіткнувся з тією ж проблемою. наступне рішення спрацювало для мене.

 FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
        glFrame.addView(yourView);
        glFrame.bringToFront();
        glFrame.invalidate();

Другим рішенням є використання xml, додавши цей атрибут до подання xml

android:translationZ=""

2

Ви можете використовувати BindingAdapter так:

@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) {
    if (flag) {
        view.bringToFront();
    }
}


  <ImageView
        ...
        app:bringToFront="@{true}"/>

0

Вам потрібно використовувати framelayout. І кращий спосіб зробити це - зробити погляд невидимим, коли цього не потрібно. Також вам потрібно встановити положення для кожного перегляду, щоб вони рухалися відповідно до відповідної позиції


0

Якщо ви використовуєте a, LinearLayoutвам слід зателефонувати, myView.bringToFront()а після дзвонити parentView.requestLayout()та parentView.invalidate()змусити батька перемальовуватися з новим розпорядженням про дитину.


0

Спробуйте використовувати на ній висоту, щось подібне yourview.setElevation(5);


0

Завдяки користувачу Stack над цим поясненням, я працював навіть на Android 4.1.1

((View)myView.getParent()).requestLayout();
myView.bringToFront();

Наприклад, на моєму динамічному використанні я це зробив

public void onMyClick(View v)
     {
     ((View)v.getParent()).requestLayout();
     v.bringToFront();
     }

І Бам!


-2

Впорядкуйте їх у порядку, який ви хочете показати. Припустимо, ви хочете показати перегляд 1 зверху перегляду 2. Потім записуйте код перегляду 2, потім записуйте код перегляду 1. Якщо ви не можете зробити це впорядкування, то зателефонуйте doneToFront () на кореневий вигляд макета, який ви хочете вивести попереду.


-32

Ви можете встановити видимість на хибну для інших поглядів.

view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...

або

view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...

і встановити

viewN.setVisibility(View.VISIBLE);

4
Мені потрібно, щоб все було видно, це не проблема, проблема - це z-порядок. якби життєздатність була проблемою, це було б легко вирішити. . .
Лукап
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.