views:

63

answers:

3

I want to start an activity as a dialog, which can be simply done by:

<activity android:theme="@android:style/Theme.Dialog">

But I want to do control the dialog, so I've to do it programmatically. Basically I want to modify this property of dialog:

mCanceledOnTouchOutside = true

This will make the dialog cancel itself when touched outside of it's bounds. (Basically I want to replicate the popup behavior). The issue is I can't simply create a dialog and set it's layout since I need a call to activity (to initialized datasets)

Is this possible ?

A: 

You can define your own style that extends Theme.Dialog in a values/styles.xml file (or whatever you want to call it). Check out http://developer.android.com/guide/topics/ui/themes.html#Inheritance.

I'm not sure if this will work, but maybe try something like:

<style name="DialogCancelOnTouchOutside" parent="@android:style/Theme.Dialog">
    <item name="android:canceledOnTouchOutside">true</item>
</style>
cfei
Unfortunately this won't work since mcanceledOnTouchOutside is private. Any ideas how android loads the activities when we apply Dialog/Transparent theme to it ? It surely must be creating an instance of Dialog class and injecting the view into it after loading the activity. If we can modify that behavior, it could work out.
sazwqa
+1  A: 

This doesn't really make since, because an activity is not a dialog. By setting the theme, all you are doing is causing the activity to visually use the theme of a dialog. It is still an activity, however, will all of the normal activity behavior. In other words, there is no Dialog object with its associated behavior.

hackbod
Thanks a lot, it cleared up my confusion regarding activities started using dialog theme.
sazwqa
+1  A: 

I just wanted to reproduce this cancelOutside Dialog behavior on one of my Dialog style Activity. For this I extracted the Dialog source code (Dialog.java) handling the touch event:

public boolean onTouchEvent(MotionEvent event) {
    if (mCancelable && mCanceledOnTouchOutside && event.getAction() == MotionEvent.ACTION_DOWN && isOutOfBounds(event)) {
        cancel();
        return true;
    }
    return false;
}

private boolean isOutOfBounds(MotionEvent event) {
    final int x = (int) event.getX();
    final int y = (int) event.getY();
    final int slop = ViewConfiguration.get(mContext).getScaledWindowTouchSlop();
    final View decorView = getWindow().getDecorView();
    return (x < -slop) || (y < -slop) || (x > (decorView.getWidth()+slop)) || (y > (decorView.getHeight()+slop));
}

I Copy paste it in my Dialog style activity and changed small things:

public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN && isOutOfBounds(event)) {
        finish();
        return true;
    }
    return false;
}

private boolean isOutOfBounds(MotionEvent event) {
    final int x = (int) event.getX();
    final int y = (int) event.getY();
    final int slop = ViewConfiguration.get(this).getScaledWindowTouchSlop();
    final View decorView = getWindow().getDecorView();
    return (x < -slop) || (y < -slop) || (x > (decorView.getWidth() + slop)) || (y > decorView.getHeight() + slop));
}

It works fine!

ol_v_er
thank you,it save me much time
pengwang