Как поставить взгляд перед всем?


131

У меня есть активность и много виджетов, некоторые из них имеют анимацию, а из-за анимации некоторые виджеты перемещаются (переводятся) один над другим. Например, текстовое представление перемещается по некоторым кнопкам. , ,

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

Я не могу этого добиться. Я перепробовал все, что знаю, и "giveToFront ()" определенно не работает.

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


3
Я использовал, RelativeLayoutчтобы "вид сверху" появлялся последним в XML. См stackoverflow.com/a/31340762/1121497
Ферран Maylinch

может кто-нибудь, пожалуйста, сообщите соответствующий код в xml «принесетТоФронт»
Шириш Хервэйд

1
Попробуйте использовать высоту bottomView = elevation: 1dp и topView = elevation: 2dp в вашем xml || ViewCompat.setElevation (View, int)
Tlacaelel Ramon Luis

Ответы:


144

Вы можете вызвать callToFront () в представлении, которое хотите разместить на переднем плане.

Это пример:

    yourView.bringToFront();

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

2
Итак, я обнаружил, что LinearLayoutнельзя использовать с bringToFront. В итоге я использовал RelativeLayout. См. Мой комментарий к самому вопросу.
Ферран Мэйлинч

1
может кто-нибудь, пожалуйста, сообщите соответствующий код в xml файла 'giveToFront'
Шириш Хервэйд

Это приводит к перемещению элемента, который я перемещаю вперед по какой-либо причине. ViewCompat.setTranslationZ(view, 1)с другой стороны работает отлично.
Bimde

1
если я использовал в манифесте android: theme = "@ android: style / Theme.Light.NoTitleBar" в действии, чем yourView.bringToFront (); работает отлично, но я использовал android: theme = "@ android: style / Theme.AppCompat.Light.NoActionBar" yourView.bringToFront (); не работает. Любая подсказка по этому поводу.
Рахул

43

Я просматривал переполнение стека, чтобы найти хороший ответ, и когда мне не удалось его найти, я просмотрел документы.

На этот простой ответ, кажется, еще никто не наткнулся:

ViewCompat.setTranslationZ(view, translationZ);

перевод по умолчанию z равен 0,0


Это положение элемента по оси Z в пикселях, также известное как высота. setTranslationX перемещает представление по оси X (влево / вправо), setTranslationY - по оси Y (сверху / снизу). Ось Z - это 3-я ось.
xdevs23

О чем setZ()? Если я правильно помню, в конце концов, положение Z вида - это его высота плюс его перенос Z.
Gensoukyou1337,

2
@ Gensoukyou1337, то ViewCompat.setZ(view, yourValueInPixels); view.setZ()работает только с API 21 и выше.
Johnny Five

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: Я думаю, вы должны реорганизовать их в кулак другого уровня. Затем сделайте это на своем пути.
Джастин

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

Я использовал то же самое. Он отлично работает с одной проблемой, что он скрывает панель инструментов.
user2980181

Это работает с несколькими уровнями? Скажем, у меня есть a, ConstraintLayoutкоторый содержит a RelativeLayout, а другой RelativeLayout- того же размера, что и его root ConstraintLayout( match_parent). Первый RelativeLayoutимеет a Button, а также находится позади (в z-порядке) второго RelativeLayout. Могу ли я сделать так, чтобы элемент Buttonв первом RelativeLayoutотображался поверх всего, чтобы он был видимым и интерактивным, используя View::bringToFront()?
oaskamay

25

С этим кодом в xml

 android:translationZ="90dp"

3
Откуда 90dpвзялось?
Sudhir Khanger

1
это ручной ввод. Вы можете попробовать, исходя из ваших требований. либо 45dp, либо 135dp, либо 180dp или 270dp
Кришна

Не могли бы вы просто использовать 1dp?
Тайлер Тернбулл,

требуется API 21+
Мухаммад Сакиб

18

Попробуйте FrameLayout, это дает вам возможность размещать просмотры один над другим. Вы можете создать два LinearLayouts: один с фоновыми представлениями и один с представлениями переднего плана, и объединить их с помощью FrameLayout. Надеюсь это поможет.


1
Как мы можем вывести его наверх, как диалог?
Gaurav Arora

@Infinity, вы можете создать FragmentDialog для этой цели или просто использовать Theme.Dialog для своей Activity.
Егор

Я не могу использовать FragmentDialog, так как он несовместим с API 10. Во-вторых, я уже использую тему для своего приложения. Есть ли другой путь ? Я использовал FrameLayout, как вы и сказали!
Gaurav Arora

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

8

Если вы используете ConstraintLayout, просто поместите элемент после других элементов, чтобы он был впереди остальных.



3

Может быть другой способ, который спасет положение. Просто создайте новый диалог с желаемым макетом и просто покажите его. Мне он нужен для отображения loadView поверх DialogFragment, и это был единственный способ добиться успеха.

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

В некоторых случаях, например в моем, принестиТоФронт () может не работать. Но содержимое макета dialog_top должно переопределять что-либо на уровне пользовательского интерфейса. Но в любом случае это уродливый обходной путь.


3

я столкнулся с той же проблемой. следующее решение сработало для меня.

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

2-е решение - использовать 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

Если вы используете, LinearLayoutвы должны вызвать, myView.bringToFront()а после вы должны позвонить parentView.requestLayout()и parentView.invalidate()заставить родительский элемент перерисовать с новым дочерним порядком.


0

Благодаря пользователю Stack за это объяснение, у меня это работает даже на Android 4.1.1.

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

В моем динамическом использовании, например, я сделал

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

И БАММ!


-1

Попробуйте использовать на нем высоту, например yourview.setElevation(5);


-2

Расставьте их в том порядке, в котором хотите показывать. Предположим, вы хотите показать представление 1 поверх представления 2. Затем напишите код представления 2, затем напишите код представления 1. Если вы не можете выполнить это упорядочение, вызовите функцию takeToFront () для корневого представления макета, который вы хотите вывести на передний план.


-32

Вы можете установить значение false для других представлений.

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

или

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

и установить

viewN.setVisibility(View.VISIBLE);

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