欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

修改AlertDialog各组件颜色、字体等属性、禁止返回键、外框不消失、android9.0不居中显示问题解决

程序员文章站 2022-03-12 19:25:47
修改AlertDialog各组件颜色、字体等属性像下图这种Dialog该怎么实现呢?乍一看视觉效果还可以,但当我们想改变一下标题的文字颜色或者按钮颜色应该怎么做呢?查看源码public class AlertDialog extends Dialog implements DialogInterface { private AlertController mAlert; ......}AlertDialog类中并没有直接定义控件,而是通过AlertControll......

修改AlertDialog各组件颜色、字体等属性

像下图这种Dialog该怎么实现呢?

修改AlertDialog各组件颜色、字体等属性、禁止返回键、外框不消失、android9.0不居中显示问题解决
乍一看视觉效果还可以,但当我们想改变一下标题的文字颜色或者按钮颜色应该怎么做呢?

查看源码

public class AlertDialog extends Dialog implements DialogInterface {
    private AlertController mAlert;
    ......
}


AlertDialog类中并没有直接定义控件,而是通过AlertController类来设置各控件的属性。 
然而在android studio中无法直接查看该类源码,因为部分源码的标签是@hide的,即使文件存在但编辑器也不会显示,所以需要通过另外的软件来查看源码。

这里我使用了Source Insight,大家可从此处下载:Source Insight 4.0 最简单的破解安装

Source Insight的使用教程:使用 Source InSight 阅读 Android 源码

有条件的朋友还可以在AndroidXRef网站上直接查看,里面有各个版本的Android源码,但我因为访问速度太慢就没用这个看。

回到正题,在AlertController类中,可以看到以下变量:

class AlertController {
    ......
    private ImageView mIconView;
    private TextView mTitleView;
    private TextView mMessageView;
    private View mCustomTitleView;
    ......
}


但由于我们无法直接访问这些变量,回想起上学期学习的高级Java,其中学到的反射机制终于可以派上用场了!

修改文字颜色、大小

 AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("标题")
                .setMessage("内容")
                .setPositiveButton("确定",null)
                .setNegativeButton("取消",null)
                .create();
        dialog.show();
        try {
            Field mAlert = AlertDialog.class.getDeclaredField("mAlert");
            mAlert.setAccessible(true);
            Object mAlertController = mAlert.get(dialog);
            Field mMessage = mAlertController.getClass().getDeclaredField("mMessageView");
            mMessage.setAccessible(true);
            TextView mMessageView = (TextView) mMessage.get(mAlertController);
            mMessageView.setTextColor(你要设置的颜色);
            mTitleView.setTextSize(你要设置的文字大小);
            Field mTitle = mAlertController.getClass().getDeclaredField("mTitleView");
            mTitle.setAccessible(true);
            TextView mTitleView = (TextView) mTitle.get(mAlertController);
            mTitleView.setTextColor(你要设置的颜色);
            mTitleView.setTextSize(你要设置的文字大小);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }


修改按钮颜色 
同样,我们可以通过反射机制修改,也可以直接使用AlertDialog类中提供的方法:

/**
     * Gets one of the buttons used in the dialog. Returns null if the specified
     * button does not exist or the dialog has not yet been fully created (for
     * example, via {@link #show()} or {@link #create()}).
     *
     * @param whichButton The identifier of the button that should be returned.
     *            For example, this can be
     *            {@link DialogInterface#BUTTON_POSITIVE}.
     * @return The button from the dialog, or null if a button does not exist.
     */
    public Button getButton(int whichButton) {
        return mAlert.getButton(whichButton);
    }

AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle("标题")
                .setMessage("内容")
                .setPositiveButton("确定",null)
                .setNegativeButton("取消",null)
                .create();
        dialog.show();
        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextColor(你要设置的颜色);
        dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setTextSize(你要设置的文字大小);



附上一张修改后的效果图:

至此,我们就可以用反射机制修改Dialog中各控件的各个属性(又如gravity等,但经过实践发现Title无法设置Gravity属性???Message却又可以???暂留一个未解之谜),需要用到的时候再探索就好了。

注意

反射方法必须在dialog.show()方法后执行,不然会报错。

禁止返回键、外框不消失

android 如何让dialog不消失,即使是用户按了返回键dialog也不消失
解决的问题:软件提示升级的dialog时候,用户有可能按了返回键,但是现在的需求是用户只能按“确定升级”或者“暂时不升级”这两个按钮才能拿dialog消失,按返回键不能使dialog消失 
方案:截取activity的 onkeydown事件,而应该截取dialog的key响应事件,当dialog在前台显示的时候,keylistener首先会派发到dialog里面,在那里面监听就行了。
先申明一个keylistener。

    OnKeyListener keylistener = new DialogInterface.OnKeyListener(){
        public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
            if (keyCode==KeyEvent.KEYCODE_BACK&&event.getRepeatCount()==0)
            {
             return true;
            }
            else
            {
             return false;
            }
        }
    } ;


在把这个listener注册到dialog里面去 当初始化dialog的时候

                builder.setTitle(getText(R.string.XXXX))
                        .setMessage(getText(R.XXXXXX))
                        .setOnKeyListener(key).setCancelable(false)
                        .setPositiveButton(android.R.string.ok, someOKButtonListener)
                        .setNegativeButton(android.R.string.cancel, null);


PS: setCancelable(false),作用是当dialog弹出来的时候,如果触点在dialog外围,按照默认的方式 dialog将消失。如果这个设为false的话 这种情况dialog就不会消失了。  加了这一句就OK了。dialog.setCancelable(false);

 

今天遇到一个问题,如图所示:

修改AlertDialog各组件颜色、字体等属性、禁止返回键、外框不消失、android9.0不居中显示问题解决
    
这个Dialog偏右,在模拟器以及9.0一下的手机上都是正常显示,修复了一下这个小BUG
我们可以设置一下它的宽度,按照屏幕占比去计算。我的Demo设置了他的宽度为屏幕的95%,注意:设置属性的代码要放到show()方法之后,要不然可能会出现设置的属性不生效问题
具体代码如下:

AlertDialog.Builder builder = new AlertDialog.Builder(context);
                builder.setTitle("网络异常");
                builder.setMessage("检测到您的网络断开连接,请检查网络是否连接正常!");
                builder.setCancelable(false);
                builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        ActivityCollector.finishAll();
                        Intent intent = new Intent(context,SplashActivity.class);
                        context.startActivity(intent);
                    }
                });
                AlertDialog dialog = builder.create();
                dialog.show();
                //放在show()之后,不然有些属性是没有效果的,比如height和width
                Window dialogWindow = dialog.getWindow();
                WindowManager m = getWindowManager();
                Display d = m.getDefaultDisplay(); // 获取屏幕宽、高
                WindowManager.LayoutParams p = dialogWindow.getAttributes(); // 获取对话框当前的参数值
                // 设置宽度
                p.width = (int) (d.getWidth() * 0.95); // 宽度设置为屏幕的0.95
                p.gravity = Gravity.CENTER;//设置位置
                //p.alpha = 0.8f;//设置透明度
                dialogWindow.setAttributes(p);

Android9.0 AlertDialog不居中显示问题解决

参考文章原文链接:

https://blog.csdn.net/m0_38025747/article/details/80217116

https://www.cnblogs.com/ldq2016/p/6026490.html

https://blog.csdn.net/qq_38356174/article/details/87856639

 

本文地址:https://blog.csdn.net/u010194538/article/details/107456050