Android 在一切之上叠加一个视图?

Posted

技术标签:

【中文标题】Android 在一切之上叠加一个视图?【英文标题】:Android overlay a view ontop of everything? 【发布时间】:2011-11-23 01:35:24 【问题描述】:

你能在 android 的所有东西上叠加一个视图吗?

在 iPhone 中,我会得到新视图,将其 frame.origin 设置为 (0,0),并将其宽度和高度设置为 self.view 的宽度和高度。将其添加到 self.view 会使其充当叠加层,覆盖后面的内容(或者如果它有透明背景,则显示后面的视图)。

在android中有类似的技术吗?我意识到视图略有不同(有三种(或更多...)relativelayout、linearlayout 和 framelayout),但有什么方法可以不加选择地将视图覆盖在所有内容之上?

【问题讨论】:

【参考方案1】:

只需使用RelativeLayoutFrameLayout。最后一个子视图将覆盖其他所有内容。

Android 支持 Cocoa Touch SDK 不支持的模式:布局管理。布局对于 iPhone 意味着绝对定位所有内容(除了一些拉伸因素)。 android中的布局意味着孩子将被放置在彼此的关系中。

示例(第二个 EditText 将完全覆盖第一个):

<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_
    android:layout_
    android:id="@+id/root_view">

    <EditText
        android:layout_
        android:id="@+id/editText1"
        android:layout_>
    </EditText>

    <EditText
        android:layout_
        android:id="@+id/editText2"
        android:layout_>
        <requestFocus></requestFocus>
    </EditText>

</FrameLayout>

FrameLayout 是某种视图堆栈。专为特殊情况而设计。

RelativeLayout 非常强大。您可以定义诸如视图 A 必须对齐父布局底部视图 B 必须对齐 A 底部到顶部等规则

根据评论更新

通常您在onCreate 中使用setContentView(R.layout.your_layout) 设置内容(它会为您膨胀布局)。你可以手动调用setContentView(inflatedView),没有区别。

视图本身可能是单个视图(如TextView)或复杂的布局层次结构(嵌套布局,因为所有布局本身都是视图)。

调用setContentView 后,您的活动知道其内容是什么样的,您可以使用(FrameLayout) findViewById(R.id.root_view) 检索此层次结构中的任何视图(通用模式(ClassOfTheViewWithThisId) findViewById(R.id.declared_id_of_view))。

【讨论】:

啊,谢谢你的例子。所以我猜在一个活动中,内容视图可能是一个框架布局?如果我使用layoutinflater 从布局 xml 文件中获取relativelayout,如何将其添加到内容视图中?有没有办法获得对内容视图的引用?谢谢 我更新了我的答案,因此它解释了活动的内容是什么以及如何与之交互。 太棒了。非常感谢。 :) 我想指出,虽然我更喜欢FrameLayout,因为它的轻量级特性,它无法将最大测量高度(也就是它自己的结果高度)传播给它的孩子,以防@ 987654338@高度,see here。因此,当支持 Android 2 并使用 match_parent 时,RelativeLayout 是唯一的工作选项;例如see here. JFYI:在 Android 4.4.4 对我来说,放置一个片段作为覆盖就足够了。从 Android 5.0 开始,一些元素(如按钮和卡片视图)位于顶部。有了答案中的解决方案,它就像一个魅力。【参考方案2】:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_view"
android:layout_
android:layout_
android:orientation="vertical" >

<LinearLayout
    android:id = "@+id/Everything"
    android:layout_
    android:layout_
    android:orientation="vertical" >
    <!-- other actual layout stuff here EVERYTHING HERE -->

   </LinearLayout>

<LinearLayout
    android:id="@+id/overlay"
    android:layout_
    android:layout_
    android:layout_gravity="right" >
</LinearLayout>

现在,您使用 android:id = "@+id/overlay" 在 LinearLayout 下添加的任何视图都将显示为具有 gravity = right 的叠加层,使用 android:id="@+id/Everything" 在 LinearLayout 上

【讨论】:

希望我能在下午早些时候看到这个。非常感谢!!【参考方案3】:

你可以使用bringToFront:

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

【讨论】:

【参考方案4】:

最好的方法是 ViewOverlay ,您可以将任何可绘制对象作为叠加层添加到自 Android JellyBeanMR2(Api 18) 以来的任何视图作为其叠加层。

mMyDrawable 添加到mMyView 作为其叠加层:

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

【讨论】:

错字:mMyDrawable.setBounds 感谢您的解决方案。但是您可以从图像访问视图组件。例如,如果您的视图中有一个按钮,如果您单击图像,则会自动单击原始视图按钮。 @RanjithSubramaniam 是的,因为它只是覆盖在视图上绘制的。 但是如果一个视图必须放在另一个视图之上,它就不起作用了,因为drawable只是一个图形【参考方案5】:

我刚刚为它制定了解决方案。我为此创建了一个library,以便以可重用的方式执行此操作,这就是您不需要在 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 预览 -

【讨论】:

【参考方案6】:

我之前尝试过遮阳篷,但这没有用。 现在我只使用了 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);
            

【讨论】:

我认为为了使这个答案真正有用,您应该添加更多内容。示例代码、截图、...【参考方案7】:

bringToFront() 非常容易进行程序化调整,如上所述。由于 stateListAnimator,我在使用按钮 z 顺序时遇到了一些麻烦。如果您最终需要以编程方式调整视图叠加层,而这些视图恰好是按钮,请确保在您的 xml 布局文件中将 stateListAnimator 设置为 null。 stateListAnimator 是 android 的底层调整过程按钮被点击时的translationZ,所以被点击的按钮最终在顶部可见。这并不总是您想要的...对于完整的 Z 顺序控制,请执行以下操作:

【讨论】:

以上是关于Android 在一切之上叠加一个视图?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Storyboard 在 UIImagePickerController 之上创建叠加视图

观察 SwiftUI 中的帧变化

将子视图置于一切之上,但低于另一个 UIView

Android 浮动视图(在其他视图之上)

在 customView 中的 ImageView 上叠加许多图像视图

在所有其他 Android 应用之上显示应用视图