如何创建一个浮动的可触摸活动,同时仍然允许触摸其边界外的本地控件?

8
我希望实现的功能可以通过我用MSPaint制作的示意图来解释:

enter image description here

我尝试设置FLAG_NOT_TOUCH_MODAL,根据描述,这应该是我想要的,但它根本不起作用。我的Activity会接收所有触摸事件,甚至在其边界之外。

如果我设置 FLAG_NOT_FOCUSABLE,那么活动窗口下面的原生控件就可以被触摸,但是当在其边界内触摸时,该活动窗口完全不可见。

我尝试在清单文件中设置isFloatingWindow=true,但似乎没有任何区别。

有人能够实现这个吗?我会非常感激一个小的演示活动,以便我可以从中获取并进行开发。我已经尝试了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类:
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);
}

很不幸,这就是结果: Does not look like a dialog 我错过了什么?
谢谢。

你好,当应用程序未运行时,你是如何使活动保持活跃的? - famfamfam
嗨,虽然已经过去了很多年,但我记得我们使用了一个前台服务。 - Nom1fan
2个回答

10
在您的清单文件中,为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);     
}

1
非常感谢回复!我一有机会就会尝试,并且会及时汇报。 - Nom1fan
1
android:theme="@android:style/Theme.Dialog" 应该放在你的清单文件中的 <activity> 标签中,而不是布局中。 - Mike M.
1
诚实的错误 =] 定义在任何地方看起来都一样,而且当我设置它时也没有警告/错误。谢谢,现在它似乎工作得很好! - Nom1fan
1
是的,视图初始化的方式会忽略与其无关的内容,因此它不会因此崩溃。由于自定义 XML 命名空间和属性是可行的,因此您的 IDE 并不聪明到知道这些属性不适合在那里。很酷,很高兴你搞定了。干杯! - Mike M.
1
哦,我刚意识到,你可能不需要 FLAG_LAYOUT_NO_LIMITS,除非你想让你的 Activity 能够延伸到屏幕之外。我从我的一个项目中复制了那段代码,并忘记移除那个标志。如果你保留它,它不会造成任何伤害。 - Mike M.
显示剩余3条评论

0

您可以在AndroidManifest文件中使用特殊主题的活动:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接