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】:只需使用RelativeLayout
或FrameLayout
。最后一个子视图将覆盖其他所有内容。
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 之上创建叠加视图