Как донести взгляд до всего?
У меня есть активность и много виджетов, некоторые из них имеют анимацию, и из-за анимации некоторые виджеты перемещаются (переводятся) друг на друга. Например, текстовое представление перемещается по некоторым кнопкам.,,
Теперь я хочу, чтобы кнопки всегда были спереди. И когда текстовое представление движется, я хочу двигаться за кнопками.
Я не могу достичь этого, я перепробовал все, что я знаю, и "takeToFront()" определенно не работает.
примечание: я не хочу управлять z-порядком по порядку размещения элемента в макете, потому что я просто не могу:), макет сложный, и я не могу разместить все кнопки в начале макета
20 ответов
Вы можете вызвать метод takeToFront() для представления, которое вы хотите получить впереди.
Это пример:
yourView.bringToFront();
Я искал переполнение стека, чтобы найти хороший ответ, и когда я не смог найти его, я просмотрел документы.
никто, кажется, еще не наткнулся на этот простой ответ:
ViewCompat.setTranslationZ(view, translationZ);
перевод по умолчанию z равен 0.0
Еще более простым решением является редактирование XML-кода активности. использование
android:translationZ=""
bringToFront()
это правильный путь, но, ОБРАТИТЕ ВНИМАНИЕ, что вы должны позвонить bringToFront()
а также invalidate()
метод в представлении высшего уровня (под вашим корневым представлением), например:
Иерархия вашего представления:
-RelativeLayout
|--LinearLayout1
|------Button1
|------Button2
|------Button3
|--ImageView
|--LinearLayout2
|------Button4
|------Button5
|------Button6
Таким образом, когда вы анимируете назад свои кнопки (1->6), ваши кнопки будут под (ниже) ImageView
, Чтобы привести это (выше) ImageView
ты должен позвонить bringToFront()
а также invalidate()
метод на вашем LinearLayout
s. Тогда это будет работать:)
** ПРИМЕЧАНИЕ: не забудьте установить 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);
Глюк!
Если вы используете ConstraintLayout
, просто поместите элемент после других элементов, чтобы сделать его впереди, чем другие
Пытаться FrameLayout
, это дает вам возможность поставить взгляды друг над другом. Вы можете создать два LinearLayouts
: один с фоновым видом, другой с передним планом, и объедините их, используя FrameLayout
, Надеюсь это поможет.
Я столкнулся с той же проблемой. следующее решение сработало для меня.
FrameLayout glFrame=(FrameLayout) findViewById(R.id.animatedView);
glFrame.addView(yourView);
glFrame.bringToFront();
glFrame.invalidate();
Вы можете попробовать использовать bringChildToFront
Вы можете проверить, полезна ли эта документация на странице разработчиков Android.
Может быть другой способ, который спасет день. Просто запустите новый диалог с нужным макетом и просто покажите его. Мне нужно это для отображения loadView поверх DialogFragment, и это был единственный способ, которым я добился успеха.
Dialog topDialog = new Dialog(this, android.R.style.Theme_Translucent_NoTitleBar);
topDialog.setContentView(R.layout.dialog_top);
topDialog.show();
Метод takeToFront() может не работать в некоторых случаях, например, у меня. Но содержимое макета dialog_top должно переопределять все на уровне пользовательского интерфейса. Но в любом случае, это уродливый обходной путь.
Вы можете использовать BindingAdapter следующим образом:
@BindingAdapter("bringToFront")
public static void bringToFront(View view, Boolean flag) {
if (flag) {
view.bringToFront();
}
}
<ImageView
...
app:bringToFront="@{true}"/>
Порядок перекрывающихся видов действительно зависит от 4 вещей:
- Атрибут
android:elevation
который измеряется в dp/sp - Атрибут
android:translationZ
который также измеряется в dp/sp. - В Constraint Layout порядок, в котором вы размещаете представления в дереве компонентов, также является порядком отображения.
- Программный порядок, который вы устанавливаете с помощью таких методов, как
view.bringToFront()
в вашем коде kotlin/java.
Цифры 1 и 2 конкурируют друг с другом и имеют преимущество над точками 3 и 4: если вы установите
elevation="4dp"
для вида 1 и
translationZ="2dp"
для вида 2 вид 1 всегда будет сверху, независимо от цифр 3 и 4.
Ты можешь использовать
elevation
атрибут, если ваш минимальный уровень API равен 21.
Благодаря Lena Bru Stack за это объяснение, у меня это работает даже на Android 4.1.1.
((View)myView.getParent()).requestLayout();
myView.bringToFront();
Например, при моем динамическом использовании я сделал
public void onMyClick(View v)
{
((View)v.getParent()).requestLayout();
v.bringToFront();
}
И БАММ!
Если вы используете LinearLayout
ты должен позвонить myView.bringToFront()
и после того, как вы должны позвонить parentView.requestLayout()
а также parentView.invalidate()
заставить родителя перерисовать новый дочерний порядок.
Вам нужно использовать framelayout. И лучший способ сделать это - сделать представление невидимым, когда оно не требуется. Также вам нужно установить позицию для каждого вида, чтобы они двигались в соответствии с соответствующей позицией.
Просто добавьте android:elevation="2dp" в ваш XML-файл. Это работает для меня..
Попробуйте использовать на нем высоту, например yourview.setElevation(5);
Вы можете установить видимость false других представлений.
view1.setVisibility(View.GONE);
view2.setVisibility(View.GONE);
...
или же
view1.setVisibility(View.INVISIBLE);
view2.setVisibility(View.INVISIBLE);
...
и установить
viewN.setVisibility(View.VISIBLE);