Размещение / перекрытие (z-index) вида над другим видом в Android
У меня есть линейный макет, который состоит из изображения и текста, один под другим в линейном макете.
<LinearLayout android:orientation="horizontal" ... >
<ImageView
android:id="@+id/thumbnail"
android:layout_weight="0.8"
android:layout_width="0dip"
android:layout_height="fill_parent">
</ImageView>
<TextView
android:id="@+id/description"
android:layout_weight="0.2"
android:layout_width="0dip"
android:layout_height="wrap_content">
</TextView>
Некоторые правила могут отсутствовать, чтобы дать представление о том, как выглядит макет. Я хочу еще одно небольшое текстовое представление, скажем, 50dip по длине и ширине, расположенное над изображением, под словом "над". Я имел в виду z-index больше, чем изображение, я хочу разместить его в центре и выше (перекрывая) изображения.
Я хочу знать, как мы можем разместить одно представление над другим с переменным z-индексом (предпочтительно в линейном расположении)?
13 ответов
Вы не можете использовать LinearLayout для этого, но вы можете использовать FrameLayout
, В FrameLayout
z-индекс определяется порядком, в котором элементы добавляются, например:
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/my_drawable"
android:scaleType="fitCenter"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center"
android:padding="5dp"
android:text="My Label"
/>
</FrameLayout>
В этом случае TextView будет нарисован в верхней части ImageView, вдоль нижнего центра изображения.
Попробуй .bringToFront()
:
http://developer.android.com/reference/android/view/View.html
RelativeLayout работает так же, последнее изображение в относительной компоновке выигрывает.
Изменение порядка розыгрыша
Альтернативой является изменение порядка, в котором представления отрисовываются родителем. Вы можете включить эту функцию из ViewGroup, вызвав setChildrenDrawingOrderEnabled(true) и переопределив getChildDrawingOrder (int childCount, int i).
Пример:
/**
* Example Layout that changes draw order of a FrameLayout
*/
public class OrderLayout extends FrameLayout {
private static final int[][] DRAW_ORDERS = new int[][]{
{0, 1, 2},
{2, 1, 0},
{1, 2, 0}
};
private int currentOrder;
public OrderLayout(Context context) {
super(context);
setChildrenDrawingOrderEnabled(true);
}
public void setDrawOrder(int order) {
currentOrder = order;
invalidate();
}
@Override
protected int getChildDrawingOrder(int childCount, int i) {
return DRAW_ORDERS[currentOrder][i];
}
}
Выход:
призвание OrderLayout#setDrawOrder(int)
с 0-1-2 приводит к:
Я решил ту же проблему, добавив android:elevation="1dp"
на какой вид вы хотите это по другому.
Ты можешь использовать view.setZ(float)
начиная с уровня API 21. Здесь вы можете найти больше информации.
Попробуйте это в RelativeLayout:
ImageView image = new ImageView(this);
image.SetZ(float z);
Меня устраивает.
Есть способ использовать LinearLayout. Просто установите для marginTop вашего предыдущего элемента соответствующее отрицательное значение и убедитесь, что элемент, который вы хотите поместить сверху, находится после элемента, который вы хотите расположить ниже в своем XML.
<linearLayout android:orientation="horizontal" ... >
<ImageView
android:id="@+id/thumbnail"
android:layout_weight="0.8"
android:layout_width="0dip"
android:layout_height="fill_parent"
>
</ImageView>
<TextView
android:id="@+id/description"
android:layout_marginTop="-20dip"
android:layout_weight="0.2"
android:layout_width="0dip"
android:layout_height="wrap_content"
>
</TextView>
AFAIK, вы не можете сделать это с линейными макетами, вам придется пойти на RelativeLayout.
Я использую это, если вы хотите, чтобы при необходимости на передний план выводился только один вид:
containerView.bringChildToFront(topView);
containerView - это контейнер сортируемых представлений, topView - это вид, который я хочу, чтобы он был самым верхним в контейнере.
для упорядочивания нескольких представлений собирается использовать setChildrenDrawingOrderEnabled(true) и переопределить getChildDrawingOrder(int childCount, int i), как указано выше.
Если вы добавляете представление программно, вы можете использовать yourLayout.addView(view, 1);
где 1 is the index
.
Попробуйте это в RelativeLayout:
пример XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:contentDescription="@string/todo"
app:srcCompat="@drawable/ic_offer_close_outline"
app:tint="@color/colorWhite"
android:translationZ="999dp" />
пример джава:
ImageView image = new ImageView(this);
image.SetZ(float z);
Использоватьandroid:transformZ
. Он также работает с LinearLayout.