Ale*_*lex 44 android dialog touch android-activity
我有一个带有Dialog主题的活动,当有人在此活动窗口外的任何地方触摸屏幕时,我想关闭(完成)此活动?我怎样才能做到这一点 ?
小智 98
只是想指出,有是一种方式来获得对话式"触摸外,取消"从主题的对话的活动的行为,虽然我还没有完全调查它是否有不必要的副作用.
在Activity的onCreate()方法中,在创建视图之前,您将在窗口上设置两个标志:一个用于使其"非模态",以允许除活动视图之外的视图接收事件.第二个是接收其中一个事件发生的通知,它将向您发送ACTION_OUTSDIE移动事件.
如果将活动上的主题设置为对话框主题,您将获得所需的行为.
它看起来像这样:
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make us non-modal, so that others can receive touch events.
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
// Note that flag changes must happen *before* the content view is set.
setContentView(R.layout.my_dialog_view);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// If we've received a touch notification that the user has touched
// outside the app, finish the activity.
if (MotionEvent.ACTION_OUTSIDE == event.getAction()) {
finish();
return true;
}
// Delegate everything else to Activity.
return super.onTouchEvent(event);
}
}
Run Code Online (Sandbox Code Playgroud)
小智 70
我找到了一个更简单的答案,对我来说非常有效.如果您正在使用具有对话框主题的活动,则可以应用于this.setFinishOnTouchOutside(true);
活动的onCreate()方法.
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_yoptions);
this.setFinishOnTouchOutside(true);
}
Run Code Online (Sandbox Code Playgroud)
小智 29
这很简单,只需设置属性即可canceledOnTouchOutside = true
.看一下这个例子:
Dialog dialog = new Dialog(context)
dialog.setCanceledOnTouchOutside(true);
Run Code Online (Sandbox Code Playgroud)
ale*_*rik 18
很容易:
首先在style.xml中定义自己的主题:
<style name="DialogSlideAnim" parent="@android:style/Theme.Holo.Dialog">
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowCloseOnTouchOutside">true</item>
</style>
Run Code Online (Sandbox Code Playgroud)
然后在您的清单中将此主题应用于活动:
<activity
android:label="@string/app_name"
android:name=".MiniModeActivity"
android:theme="@style/DialogSlideAnim" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Run Code Online (Sandbox Code Playgroud)
Gregory和Matt的答案组合对我来说最有效(对于Honeycomb和大概是其他人).这样,当用户尝试触摸外部取消对话框时,外部视图将不会获得触摸事件.
在主Activity中,在onCreate()中创建触摸拦截器:
touchInterceptor = new FrameLayout(this);
touchInterceptor.setClickable(true); // otherwise clicks will fall through
Run Code Online (Sandbox Code Playgroud)
在onPause()中添加它:
if (touchInterceptor.getParent() == null) {
rootViewGroup.addView(touchInterceptor);
}
Run Code Online (Sandbox Code Playgroud)
(rootViewGroup可能必须是FrameLayout或RelativeLayout.LinearLayout可能无效.)
在onResume()中,将其删除:
rootViewGroup.removeView(touchInterceptor);
Run Code Online (Sandbox Code Playgroud)
然后,对于以对话框为主题的Activity,使用Gregory提供的代码(为方便起见,在此处复制):
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Make us non-modal, so that others can receive touch events.
getWindow().setFlags(LayoutParams.FLAG_NOT_TOUCH_MODAL, LayoutParams.FLAG_NOT_TOUCH_MODAL);
// ...but notify us that it happened.
getWindow().setFlags(LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH, LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
// Note that flag changes must happen *before* the content view is set.
setContentView(R.layout.my_dialog_view);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// If we've received a touch notification that the user has touched
// outside the app, finish the activity.
if (MotionEvent.ACTION_OUTSIDE == event.getAction()) {
finish();
return true;
}
// Delegate everything else to Activity.
return super.onTouchEvent(event);
}
}
Run Code Online (Sandbox Code Playgroud)
如果使用对话框主题android:theme="@style/Theme.AppCompat.Dialog"
或任何其他对话框主题.在API 11和我们可以使用之后
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
setFinishOnTouchOutside(false);
}
Run Code Online (Sandbox Code Playgroud)
onCreate
在活动内部调用此方法.
Mat*_*att -2
如果没有 API 支持,您应该只使用 FrameLayout 来填充屏幕,然后手动构建弹出窗口。然后,您可以在屏幕上的任何位置接收焦点并相应地显示/隐藏视图。