如何创建仍然允许触摸其边界外的本机控件的浮动可触摸 activity?
How to create a floating touchable activity that still allows to touch native controls outside of its borders?
我用 mspaint 制作的方案最好地解释了我想要实现的目标:
我已经尝试设置 FLAG_NOT_TOUCH_MODAL
,根据描述应该正是我想要的,但它根本不起作用。我的 activity 消耗 ALL 触摸事件,甚至在其边界之外。
如果我设置FLAG_NOT_FOCUSABLE
那么当然activity下的原生控件是可触摸的,但是activity在其边界内触摸时完全不可触摸。
我试过在清单中设置 isFloatingWindow=true
,但似乎没有任何区别。
有人能做到吗?我真的很感激一个以这种方式工作的小演示 activity,这样我就可以使用它并从那里开始工作。我已经尝试了 WindowManager 和 Intent 标志的多种排列,但似乎没有任何东西能完全按照我的需要工作。
提前致谢。
更新:
我已经尝试了你的建议,但仍然没有达到预期的效果。
这是我的 activity 布局 xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="385dp"
android:layout_height="300dp"
android:theme="@android:style/Theme.Dialog"
tools:context="com.ui.activities.TestActivity"
android:id="@+id/testLayout"
android:visibility="visible"
android:background="@drawable/abc_ab_solid_light_holo"
android:clickable="true">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me"
android:id="@+id/button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="35dp"
android:clickable="true"
android:enabled="true"
android:onClick="onClick" />
这是 Activity
class:
public class TestActivity extends Activity implements View.OnClickListener {
private String TAG = TestActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
setWindowParams();
}
private void setWindowParams() {
WindowManager.LayoutParams wlp = getWindow().getAttributes();
wlp.dimAmount = 0;
wlp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
getWindow().setAttributes(wlp);
}
不幸的是,这是结果:
我错过了什么?
谢谢。
在清单的 Activity
上设置 Dialog
主题。例如:
android:theme="@android:style/Theme.Dialog"
然后在onCreate()
中设置以下Window
参数:
public void setWindowParams() {
WindowManager.LayoutParams wlp = getWindow().getAttributes();
wlp.dimAmount = 0;
wlp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
getWindow().setAttributes(wlp);
}
您可以在 AndroidManifest 文件中使用具有特殊主题的 activity:
<style name="Theme.Transparent">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowContentOverlay">@null</item>
<!--<item name="android:backgroundDimEnabled">false</item>--> // show/hide background
<item name="android:windowIsFloating">true</item>
</style>
并且不要忘记在 Activity 中设置 mach_parent 属性,例如:
override fun onStart() {
super.onStart()
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}
我用 mspaint 制作的方案最好地解释了我想要实现的目标:
我已经尝试设置 FLAG_NOT_TOUCH_MODAL
,根据描述应该正是我想要的,但它根本不起作用。我的 activity 消耗 ALL 触摸事件,甚至在其边界之外。
如果我设置FLAG_NOT_FOCUSABLE
那么当然activity下的原生控件是可触摸的,但是activity在其边界内触摸时完全不可触摸。
我试过在清单中设置 isFloatingWindow=true
,但似乎没有任何区别。
有人能做到吗?我真的很感激一个以这种方式工作的小演示 activity,这样我就可以使用它并从那里开始工作。我已经尝试了 WindowManager 和 Intent 标志的多种排列,但似乎没有任何东西能完全按照我的需要工作。
提前致谢。
更新:
我已经尝试了你的建议,但仍然没有达到预期的效果。
这是我的 activity 布局 xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="385dp"
android:layout_height="300dp"
android:theme="@android:style/Theme.Dialog"
tools:context="com.ui.activities.TestActivity"
android:id="@+id/testLayout"
android:visibility="visible"
android:background="@drawable/abc_ab_solid_light_holo"
android:clickable="true">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click me"
android:id="@+id/button"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="35dp"
android:clickable="true"
android:enabled="true"
android:onClick="onClick" />
这是 Activity
class:
public class TestActivity extends Activity implements View.OnClickListener {
private String TAG = TestActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
setWindowParams();
}
private void setWindowParams() {
WindowManager.LayoutParams wlp = getWindow().getAttributes();
wlp.dimAmount = 0;
wlp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
getWindow().setAttributes(wlp);
}
不幸的是,这是结果:
我错过了什么?
谢谢。
在清单的 Activity
上设置 Dialog
主题。例如:
android:theme="@android:style/Theme.Dialog"
然后在onCreate()
中设置以下Window
参数:
public void setWindowParams() {
WindowManager.LayoutParams wlp = getWindow().getAttributes();
wlp.dimAmount = 0;
wlp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS |
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
getWindow().setAttributes(wlp);
}
您可以在 AndroidManifest 文件中使用具有特殊主题的 activity:
<style name="Theme.Transparent">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowContentOverlay">@null</item>
<!--<item name="android:backgroundDimEnabled">false</item>--> // show/hide background
<item name="android:windowIsFloating">true</item>
</style>
并且不要忘记在 Activity 中设置 mach_parent 属性,例如:
override fun onStart() {
super.onStart()
window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)
}