Android перекрывает вид сверху всего?
Можете ли вы наложить вид поверх всего в Android?
В iPhone я бы получил новый вид, чтобы установить его frame.origin
до (0,0) и его ширина и высота до ширины и высоты self.view
, Добавление его в self.view
затем заставил бы его действовать как наложение, покрывая содержимое позади (или если у него был прозрачный фон, то показывающий вид сзади).
Есть ли подобная техника в андроиде? Я понимаю, что представления немного отличаются (есть три типа (или больше...) относительного, линейного и фреймов), но есть ли способ просто наложить вид поверх всего без разбора?
7 ответов
Просто использовать RelativeLayout
или же FrameLayout
, Последнее дочернее представление будет перекрывать все остальное.
Android поддерживает шаблон, который не поддерживается в Cocoa Touch SDK: управление макетом.
Макет для iPhone означает позиционировать все абсолютно (кроме некоторых факторов). Расположение в Android означает, что дети будут размещены по отношению друг к другу.
Пример (второй EditText будет полностью покрывать первый):
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/root_view">
<EditText
android:layout_width="fill_parent"
android:id="@+id/editText1"
android:layout_height="fill_parent">
</EditText>
<EditText
android:layout_width="fill_parent"
android:id="@+id/editText2"
android:layout_height="fill_parent">
<requestFocus></requestFocus>
</EditText>
</FrameLayout>
FrameLayout
это какой-то вид стека. Сделано для особых случаев.
RelativeLayout
довольно мощный Вы можете определить правила, как View A должен выравнивать родительский макет снизу, View B должен выравнивать A снизу вверх и т.д.
Обновление на основе комментария
Обычно вы устанавливаете контент с помощью setContentView(R.layout.your_layout)
в onCreate
(это раздувает макет для вас). Вы можете сделать это вручную и позвонить setContentView(inflatedView)
Нет никакой разницы
Сам вид может быть одним видом (например, TextView
) или сложная иерархия макетов (вложенные макеты, поскольку все макеты сами являются представлениями).
После звонка setContentView
ваша деятельность знает, как выглядит ее содержимое, и вы можете использовать (FrameLayout) findViewById(R.id.root_view)
для получения любого представления в этой иерархии (общая схема (ClassOfTheViewWithThisId) findViewById(R.id.declared_id_of_view)
).
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<LinearLayout
android:id = "@+id/Everything"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<!-- other actual layout stuff here EVERYTHING HERE -->
</LinearLayout>
<LinearLayout
android:id="@+id/overlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right" >
</LinearLayout>
Теперь любой вид, который вы добавляете в LinearLayout с android:id = "@+id/overlay"
будет отображаться как наложение с гравитацией = прямо на линейной компоновке с android:id="@+id/Everything"
Ты можешь использовать bringToFront
:
View view=findViewById(R.id.btnStartGame);
view.bringToFront();
Наилучшим способом является ViewOverlay. Вы можете добавить любой прорисовываемый объект как оверлей к любому представлению в качестве его оверлея начиная с Android JellyBeanMR2(Api 18).
добавлять mMyDrawable
в mMyView
как его наложение:
mMyDrawable.setBounds(0, 0, mMyView.getMeasuredWidth(), mMyView.getMeasuredHeight())
mMyView.getOverlay().add(mMyDrawable)
Я только что нашел решение. Я сделал для этого библиотеку, чтобы это можно было использовать повторно, поэтому вам не нужно перекодировать свой XML. Вот документация о том, как использовать его в Java и Kotlin. Сначала инициализируйте его из действия, из которого вы хотите показать наложение -
AppWaterMarkBuilder.doConfigure()
.setAppCompatActivity(MainActivity.this)
.setWatermarkProperty(R.layout.layout_water_mark)
.showWatermarkAfterConfig();
Затем вы можете скрыть и показать его из любого места в вашем приложении -
/* For hiding the watermark*/
AppWaterMarkBuilder.hideWatermark()
/* For showing the watermark*/
AppWaterMarkBuilder.showWatermark()
Предварительный просмотр GIF -
Я пробовал awnsers раньше, но это не сработало. Теперь я просто использовал LinearLayout вместо TextureView, теперь он работает без проблем. Надеюсь, что это поможет некоторым другим, у которых есть такая же проблема.:)
view = (LinearLayout) findViewById(R.id.view); //this is initialized in the constructor
openWindowOnButtonClick();
public void openWindowOnButtonClick()
{
view.setAlpha((float)0.5);
FloatingActionButton fb = (FloatingActionButton) findViewById(R.id.floatingActionButton);
final InputMethodManager keyboard = (InputMethodManager) getSystemService(getBaseContext().INPUT_METHOD_SERVICE);
fb.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// check if the Overlay should be visible. If this value is false, it is not shown -> show it.
if(view.getVisibility() == View.INVISIBLE)
{
view.setVisibility(View.VISIBLE);
keyboard.toggleSoftInput(InputMethodManager.SHOW_IMPLICIT, 0);
Log.d("Overlay", "Klick");
}
else if(view.getVisibility() == View.VISIBLE)
{
view.setVisibility(View.INVISIBLE);
keyboard.toggleSoftInput(0, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
Как указано выше, giveToFront() очень проста для программной корректировки. У меня возникли проблемы с тем, чтобы заставить это работать с порядком кнопок z из-за stateListAnimator. Если вам нужно программно настроить наложения представлений, а эти представления являются кнопками, обязательно установите для stateListAnimator значение null в файле макета xml. stateListAnimator - это внутренний процесс Android, позволяющий настроить преобразование Z кнопок при их нажатии, так что нажатая кнопка оказывается видимой сверху. Это не всегда то, что вам нужно ... для полного контроля Z-порядка сделайте следующее: