Android 自定义Dialog无法Dismiss

写在前面:

Android开发碰到了一个很奇怪的问题,同样的自定义View的Dialog 的Code在一个项目中可以dismiss,在另一个项目中却如何也无法dismiss,真心不知道问题在什么地方,查阅了一下网上的资料,找到了自定义Dialog正确且标准的使用方式,在此Mark一下先。

实例代码

代码so esay,只是用来测试为什么自定义的dialog的不能dismiss。
1.MainActivity.java

public class MainActivity extends Activity 
{

    private Dialog dialog = null;
    private Button testBtn = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initView();

    }

    public void initView()
    {
        testBtn = (Button) this.findViewById(R.id.button1);
        testBtn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View arg0) 
            {
                // TODO Auto-generated method stub
                showCenterDialog();
            }

        });
    }
    public void showCenterDialog()
    {
        //dialog自定义的样式
        dialog = new Dialog(MainActivity.this,R.style.MyDialog);

        dialog.setContentView(R.drawable.dialog_layout);

        dialog.setCancelable(false);


        View vv = LayoutInflater.from(this).inflate(R.drawable.dialog_layout,null);

        Button closeBtn = (Button) vv.findViewById(R.id.closeBtn);
        closeBtn.setOnClickListener(new OnClickListener()
        {

            @Override
            public void onClick(View arg0) 
            {
                // TODO Auto-generated method stub

                dialog.dismiss();

            }

        }); 
        dialog.show();
    }

}

2.dialog_layout_xml 测试用布局文件


<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/TopRel"
    android:layout_width="200dp"
    android:layout_height="150dp"
    >
    <Button
        android:layout_width="150dp"
        android:layout_height="100dp"
        android:text="测试用按钮"
        android:textSize="19sp"
        android:id="@+id/closeBtn"
        android:layout_centerInParent="true"
        >Button>
RelativeLayout>

3.自定义Dialog采用的样式 Style
(style.xml中添加自定义的样式)


    

问题分析

现象:现在点击 Dialog中出现的 ”测试用按钮“,dialog就是无法dismiss。
分析:调试发现,无论你如何点击”测试用按钮“,就是无法触发它的点击响应事件,感觉Dialog在调用setContentView()后显示在界面的Button和

View vv = LayoutInflater.from(this).inflate(R.drawable.dialog_layout,null);

        Button closeBtn = (Button) vv.findViewById(R.id.closeBtn);

上面注册的Button不是同一个Button。
查阅了一下资料,根据有些网友的说法,Dialog在onCreate()的时候,会重新加载布局文件,即是调用下面的代码:


dialog.setContentView(R.drawable.dialog_layout);

重新加载过布局文件的Dialog的Button Id跟注册监听事件时的Button Id不是同一个Id,因此,不会有按键响应。

解决方法

考虑到Dialog在调用setContentView()之后,已经重新加载过布局,则下面的代码:

View vv = dialog.getWindow().getDecorView();

可以捕捉到已经加载到Dialog的布局元素,即是将inflate加载的布局代码替换为上面列出的代码,即可解决自定义样式的Dialog无法Dismiss的问题。

View vv = LayoutInflater.from(this).inflate(R.drawable.dialog_layout,null);

进一步探索

至于为什么使用getWindow().getDecorView()可以解决这种bug,可以参看老罗的博客Android应用程序窗口(Activity)的视图对象(View)的创建过程分析以及decorView和window之间的层级及关系。两篇博客比较深入的解析了Activity和View的关系,带你从源码的层次理解Android的View布局,应该为必看文章,mark一下。

decorView和window之间的层级及关系:http://blog.csdn.net/guxiao1201/article/details/41744107

老罗的博客Android应用程序窗口(Activity)的视图对象(View)的创建过程分析
http://blog.csdn.net/luoshengyang/article/details/8245546

你可能感兴趣的:(Android,开发篇)