简体   繁体   English

Android 在所有内容上叠加一个视图?

[英]Android overlay a view ontop of everything?

Can you overlay a view on top of everything in android?你能在 android 中的所有东西上叠加一个视图吗?

In iPhone I would get the new view set its frame.origin to (0,0) and its width and height to the width and height of self.view .在iPhone我会得到新的视图设置其frame.origin到(0,0),其宽度和高度与宽度和高度self.view Adding it to self.view would then cause it to act as an overlay, covering the content behind (or if it had a transparent background then showing the view behind).将它添加到self.view会导致它作为一个覆盖层,覆盖后面的内容(或者如果它有一个透明的背景然后显示后面的视图)。

Is there a similar technique in android? android中是否有类似的技术? I realise that the views are slightly different (there are three types (or more...) relativelayout, linearlayout and framelayout) but is there any way to just overlay a view on top of everything indiscriminately?我意识到视图略有不同(有三种类型(或更多......)相对布局、线性布局和框架布局)但是有什么方法可以不加选择地将视图覆盖在所有内容之上?

Simply use RelativeLayout or FrameLayout .只需使用RelativeLayoutFrameLayout The last child view will overlay everything else.最后一个子视图将覆盖其他所有内容。

Android supports a pattern which Cocoa Touch SDK doesn't: Layout management. Android 支持 Cocoa Touch SDK 不支持的模式:布局管理。
Layout for iPhone means to position everything absolute (besides some strech factors). iPhone布局意味着将所有内容绝对定位(除了一些拉伸因素)。 Layout in android means that children will be placed in relation to eachother. android 中的布局意味着孩子们将相对于彼此放置。

Example (second EditText will completely cover the first one):示例(第二个 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 is some kind of view stack. FrameLayout是某种视图堆栈。 Made for special cases.专为特殊情况而设计。

RelativeLayout is pretty powerful. RelativeLayout非常强大。 You can define rules like View A has to align parent layout bottom , View B has to align A bottom to top , etc您可以定义规则,例如视图 A 必须对齐父布局底部视图 B 必须对齐 A 底部到顶部

Update based on comment根据评论更新

Usually you set the content with setContentView(R.layout.your_layout) in onCreate (it will inflate the layout for you).通常你在onCreate使用setContentView(R.layout.your_layout)设置内容(它会为你增加布局)。 You can do that manually and call setContentView(inflatedView) , there's no difference.您可以手动执行此操作并调用setContentView(inflatedView) ,没有区别。

The view itself might be a single view (like TextView ) or a complex layout hierarchy (nested layouts, since all layouts are views themselves).视图本身可能是单个视图(如TextView )或复杂的布局层次结构(嵌套布局,因为所有布局本身都是视图)。

After calling setContentView your activity knows what its content looks like and you can use (FrameLayout) findViewById(R.id.root_view) to retrieve any view int this hierarchy (General pattern (ClassOfTheViewWithThisId) findViewById(R.id.declared_id_of_view) ).调用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>

Now any view you add under LinearLayout with android:id = "@+id/overlay" will appear as overlay with gravity = right on Linear Layout with android:id="@+id/Everything"现在,您在 LinearLayout 下使用android:id = "@+id/overlay"添加的任何视图都将显示为叠加, gravity = right在 LinearLayout with android:id="@+id/Everything"

You can use bringToFront :您可以使用bringToFront

    View view=findViewById(R.id.btnStartGame);
    view.bringToFront();

The best way is ViewOverlay , You can add any drawable as overlay to any view as its overlay since Android JellyBeanMR2(Api 18).最好的方法是ViewOverlay ,您可以将任何可绘制对象作为覆盖添加到任何视图作为其覆盖自 Android JellyBeanMR2(Api 18) 以来。

Add mMyDrawable to mMyView as its overlay:mMyDrawable添加到mMyView作为其叠加层:

mMyDrawable.setBounds(0, 0, mMyView.getMeasuredWidth(), mMyView.getMeasuredHeight())
mMyView.getOverlay().add(mMyDrawable)

I have just made a solution for it.我刚刚为此做了一个解决方案。 I made a library for this to do that in a reusable way that's why you don't need to recode in your XML.我为此创建了一个,以可重用的方式执行此操作,这就是您无需在 XML 中重新编码的原因。 Here is documentation on how to use it in Java and Kotlin .这是有关如何在JavaKotlin 中使用它的文档。 First, initialize it from an activity from where you want to show the overlay-首先,从要显示叠加层的活动中对其进行初始化-

AppWaterMarkBuilder.doConfigure()
                .setAppCompatActivity(MainActivity.this)
                .setWatermarkProperty(R.layout.layout_water_mark)
                .showWatermarkAfterConfig();

Then you can hide and show it from anywhere in your app -然后你可以在你的应用程序的任何地方隐藏和显示它 -

  /* For hiding the watermark*/
  AppWaterMarkBuilder.hideWatermark() 

  /* For showing the watermark*/
  AppWaterMarkBuilder.showWatermark() 

Gif preview - Gif 预览 -

预习

I have tried the awnsers before but this did not work.我之前尝试过 awnsers,但这不起作用。 Now I jsut used a LinearLayout instead of a TextureView, now it is working without any problem.现在我使用了 LinearLayout 而不是 TextureView,现在它可以正常工作了。 Hope it helps some others who have the same problem.希望它可以帮助其他有同样问题的人。 :) :)

    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);
            }

bringToFront() is super easy for programmatic adjustments, as stated above.如上所述,behindToFront() 对于程序化调整非常容易。 I had some trouble getting that to work with button z order because of stateListAnimator.由于 stateListAnimator,我在使用按钮 z 顺序时遇到了一些麻烦。 If you end up needing to programmatically adjust view overlays, and those views happen to be buttons, make sure to set stateListAnimator to null in your xml layout file.如果您最终需要以编程方式调整视图叠加层,而这些视图恰好是按钮,请确保在您的 xml 布局文件中将 stateListAnimator 设置为 null。 stateListAnimator is android's under-the-hood process to adjust translationZ of buttons when they are clicked, so the button that is clicked ends up visible on top. stateListAnimator 是 android 的底层过程,用于在单击按钮时调整按钮的 translationZ,因此单击的按钮最终会显示在顶部。 This is not always what you want... for full Z order control, do this:这并不总是您想要的......对于完整的 Z 顺序控制,请执行以下操作:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM