Android 修改AlertDialog内容样式
最近接到一个反馈 AlertDialog框里的按钮间距太小了 向调大一点,我一口回绝 不能 没有这个方法 等过后一想 虽然表面上没提供 其实是可以通过反射实现 反射可是号称能拿到任何一个类的任何方法
本文分为两部分
- AlertDialog基本使用
- 通过反射修改AlertDialog样式
以上就是alert的基本用法 先是new一个AlertDialog对象 然后使用建造者模式构建你想要的数据 我们来看下上述代码的效果图
可以看到 效果图中有有我们在代码里设置的数据,基本使用差不多就是这样了 那如果我们想要修改弹框里面的布局格式应该怎么办呢
我们看到AlertDialog提供给我们的方法中好像都是一些设置文字或者是点击事件的方法 并没有给我们提供修改布局样式的方法怎么办呢,,接下来开始重头戏 通过反射修改AlertDialog样式
-
反射机制
- 反射是什么
简单来说,反射可以帮助我们在动态运行的时候,对于任意一个类,可以获得其所有的方法(包括 public protected private 默认状态的),所有的变量 (包括 public protected private 默认状态的)
- 反射有什么用
看了上面的描述应该就可以知道 反射可以得到任意一个类中的任意方法,比如Button的 TextView的 等等
-
通过反射修改AlertDialog样式
很简单 我们看一下AlertDialog的源码,在AlertController中找到如下控件
看到这里是不是感觉熟悉了好多了呢 这里咱们可以利用反射拿到这些组件 ,修改样式自然就不成问题了,利用反射拿到控件代码如下
最后附上一张修过过后的效果图
最后附上完整代码
package com.example.administrator.practice;
import android.app.AlertDialog;
import android.graphics.Color;
import android.content.DialogInterface;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;
import java.lang.reflect.Field;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button1).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
initDialog();
}
});
}
private void initDialog(){
//创建dialog对象
AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle("警告")
//设置图标
.setIcon(ContextCompat.getDrawable(this, R.mipmap.ic_launcher))
//设置消息内容
.setMessage("您已经过完了2019年所有的法定假期,是否继续工作")
//设置按钮
.setNegativeButton("睡觉",null)
//设置按钮
.setPositiveButton("跑路",null)
//设置按钮
.setNeutralButton("继续工作",null)
//完成构建
.create();
//召唤弹窗
alertDialog.show();
buildDialogStyle(alertDialog);
}
/**
* 构建样式
* @param dialog 弹窗
*/
private static void buildDialogStyle(AlertDialog dialog){
try {
//TODO mMessageView mTitleView等名称是对应AlertController类中的控件命名
Field mAlert = AlertDialog.class.getDeclaredField("mAlert");
mAlert.setAccessible(true);
Object mController = mAlert.get(dialog);
//获取到内容的Text
Field mMessage = mController.getClass().getDeclaredField("mMessageView");
mMessage.setAccessible(true);
TextView mMessageView = (TextView) mMessage.get(mController);
mMessageView.setTextSize(18);
mMessageView.setTextColor(Color.GREEN);//title样式修改成``色
//获取到标题的View并设置大小颜色
Field mTitle = mController.getClass().getDeclaredField("mTitleView");
mTitle.setAccessible(true);
TextView mTitleView = (TextView) mTitle.get(mController);
mTitleView.setTextSize(18);
mTitleView.setTextColor(Color.RED);
//获取到按钮
Button pButton = dialog.getButton(AlertDialog.BUTTON_POSITIVE);//确认按键
pButton.setTextColor(Color.GREEN);
//获取按钮
Button nButton = dialog.getButton(DialogInterface.BUTTON_NEGATIVE);//取消
nButton.setTextColor(Color.BLUE);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
}