本文已参与「新人创造礼」活动,一起开启创造之路。
一、载入布局修正款式
这种办法咱们都比较了解,直接在xml 上规划布局的内容,然后创立弹窗时加载这个布局,这个办法能够让咱们更好的自界说款式,比较检测个人的审美和写UI 的才能,假如你很强的话,那么你能够规划各种花里胡哨的的弹窗,下面我简略的介绍一下这个办法的运用。
先界说一个edit_name.xml 的文件,在这个文件中写入下面的代码。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView
android:layout_marginTop="10dp"
android:padding="10dp"
android:layout_width="match_parent"
android:text="@string/please_input_name"
android:textSize="20sp"
android:textAlignment="center"
android:layout_height="wrap_content"
android:gravity="center_horizontal">
</TextView>
<EditText
android:id="@+id/name_edit"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</EditText>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_marginTop="10dp"
android:padding="15dp"
android:layout_height="wrap_content">
<TextView
android:id="@+id/info_n"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/cancel"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.3"
app:layout_constraintRight_toRightOf="parent">
</TextView>
<TextView
android:id="@+id/info_y"
app:layout_constraintTop_toTopOf="parent"
android:text="@string/sure"
android:textSize="18sp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintHorizontal_bias="0.7"
app:layout_constraintRight_toRightOf="parent">
</TextView>
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
上面的布局文件出来的作用是这样的 。
xml 文件写好了,那么咱们看看代码是怎样载入这个布局的。先创立一个 AlertDialog(dialog) 和 View ( dialogView) 目标 , 然后 dialogView 载入上面写好的布局文件, 经过 dialog.setView(dialogView) 设置 dialog 的布局。
private void showDialog1() {
// 创立一个 dialogView 弹窗
AlertDialog.Builder builder = new
AlertDialog.Builder(MainActivity.this);
final AlertDialog dialog = builder.create();
View dialogView = null;
//设置对话框布局
dialogView = View.inflate(MainActivity.this,
R.layout.edit_name, null);
dialog.setView(dialogView);
dialog.show();
// 获取布局控件
editName =(EditText) dialogView.findViewById(R.id.name_edit);
editN= (TextView) dialogView.findViewById(R.id.info_n);
editY = (TextView) dialogView.findViewById(R.id.info_y);
editN.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
editY.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(MainActivity.this,"姓名为:"+editName.getText().toString(),Toast.LENGTH_SHORT).show();
dialog.dismiss();
}
});
}
这种办法的载入布局,后边假如你有需求要改动,或许改变款式,那么你直接修正 xml 文件 , 或许在java 代码中从头设置一个新的布局。
二、载入style款式
载入style 款式呢,这个办法适用于一切Android 布局控件,一切控件都能够经过这个办法去修正款式,当然条件是你得会写 style 款式。当然,我也对这个东西了解不是很深,在这就先布鼓雷门、关公面前舞大刀一下,浅浅的介绍一下这个东西。
首先在values目录下创立一个 styles.xml 文件
在文件中创立一个自界说的款式,如下所示,这个款式特别简略,便是一些基本的界说。这儿的 name=”myDialogStyle” 很重要,下面咱们载入这个款式时,便是依据这个 name 找到这个款式的。
<!--重写系统弹出Dialog -->
<style name="myDialogStyle" parent="android:Theme.Dialog">
<item name="android:windowFrame">@null</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">false</item>
<item name="android:windowNoTitle">true</item><!--除掉title-->
<item name="android:windowContentOverlay">@null</item>
<item name="android:backgroundDimEnabled">false</item>
<item name="android:windowBackground">@null</item><!--除掉布景色-->
</style>
在 java 代码中创立弹窗时载入这个款式。
private void showDialog3() {
AlertDialog mDialog = new AlertDialog.Builder(MainActivity.this, R.style.myDialogStyle)
.setTitle("标题")
.setMessage("这个是什么呢?")
.setPositiveButton(R.string.sure,null)
.setNegativeButton(R.string.cancel, null)
.create();
mDialog.show();
}
额,好吧,我供认有点丑,究竟我不是做UI的,好像这是个很好的托言。。。。。
人都是爱美的,看到这么丑总觉得怪怪的,从头扣了下面的这段款式
<style name="myDialogStyleAlert" parent="@android:style/Theme.Holo.Light.Dialog">
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowMinWidthMajor">@android:dimen/dialog_min_width_major</item>
<item name="android:windowMinWidthMinor">@android:dimen/dialog_min_width_minor</item>
</style>
在代码中引入这个款式后,作用如下所示。好像漂亮点了。
当然这篇文章的首要意图并不是让你弄成一个漂亮的弹窗,这个我也不会,仍是回归主题,咱们怎样修正弹窗的款式,用这种办法呢,也能争对性的修正弹窗的款式,只要你知道款式的内容代表什么,那么都能进行简略的修正。
三、经过反射机制修正弹窗款式
咱们直接看代码,咱们可能会猎奇,哎,这个东西是怎样来的,为什么这么写呢?说起这个,那咱们不得不先看看源码了。
private void showDialog2() {
AlertDialog mDialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("标题")
.setMessage("这个是什么呢?")
.setPositiveButton(R.string.sure,null)
.setNegativeButton(R.string.cancel, null)
.show();
// 修正弹窗的布景色彩
mDialog.getWindow().setBackgroundDrawableResource(R.color.purple_200);
// 修正 确定取消 按钮的字体巨细
mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setTextSize(20);
mDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setTextSize(20);
try {
//获取mAlert目标
Field mAlert = AlertDialog.class.getDeclaredField("mAlert");
mAlert.setAccessible(true);
Object mAlertController = mAlert.get(mDialog);
//获取mTitleView并设置巨细色彩
Field mTitle = mAlertController.getClass().getDeclaredField("mTitleView");
mTitle.setAccessible(true);
TextView mTitleView = (TextView) mTitle.get(mAlertController);
mTitleView.setTextSize(40);
mTitleView.setTextColor(Color.WHITE);
//获取mMessageView并设置巨细色彩
Field mMessage = mAlertController.getClass().getDeclaredField("mMessageView");
mMessage.setAccessible(true);
TextView mMessageView = (TextView) mMessage.get(mAlertController);
mMessageView.setTextColor(Color.RED);
mMessageView.setTextSize(30);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
}
}
在 android studio 中 运用 ctrl + shift + n 的快捷键, 然后查找 AlertDialog 就能够看到源码的文件,咱们翻开这个文件
在 AlertDialog 这个文件中,在最初的方位,很容易就看到 mAlert 这个目标的声明
下面这段代码便是经过放射机制获取 mAlert 这个目标。
//获取mAlert目标
Field mAlert = AlertDialog.class.getDeclaredField("mAlert");
mAlert.setAccessible(true);
Object mAlertController = mAlert.get(mDialog);
经过相同的办法 检查 AlertController.java 这个文件的代码,检查这个代码能够发现这儿声明了一些变量,这些变量便是弹窗的组成,经过变量名能够大概知道它代表着什么东西。
下面这两段便是设置弹窗标题和消息的款式的代码。
//获取mTitleView并设置巨细色彩
Field mTitle = mAlertController.getClass().getDeclaredField("mTitleView");
mTitle.setAccessible(true);
TextView mTitleView = (TextView) mTitle.get(mAlertController);
mTitleView.setTextSize(40);
mTitleView.setTextColor(Color.WHITE);
//获取mMessageView并设置巨细色彩
Field mMessage = mAlertController.getClass().getDeclaredField("mMessageView");
mMessage.setAccessible(true);
TextView mMessageView = (TextView) mMessage.get(mAlertController);
mMessageView.setTextColor(Color.RED);
mMessageView.setTextSize(30);
作用是这样的。仔细的人可能会发现,上面设置的内容好像 跟下面显现的不一样吧,我读书少,你别骗我啊!
的确,上面经过反射的办法并没有让我的弹窗款式修正成功。
我检查了log ,发现有报错,大概便是由于无法经过反射机制找到关于的目标,所以并没有修正款式成功,那是不是说这个办法不可行呢,并不是,我简略查找了一下原因,怀疑是本地的环境有抵触,存在多个AlertDialog.java 这个文件的源码,无法精准的找到对应的变量,导致抵触报错了。
提示: 上面的办法供给一个思想,假如你在实际运用中没有找到别的办法处理,这个办法能够供给参考,当然,可能你得先处理这个报错的问题。
四、设置App style款式
上面讲了怎样设置弹窗的 style款式,这儿再讲讲从 App的层面来修正款式,也便是说设置App 的主题风格来设置弹窗的款式。
先在 styles.xml 文件中声明一个 App 款式,我设置的如下所示。
<style name="myAppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!--<item name="android:windowFullscreen">true</item>-->
<item name="android:windowContentOverlay">@null</item>
<item name="android:windowBackground">@android:color/white</item>
<!-- item name="android:windowIsTranslucent">true</item -->
<item name="android:windowTranslucentNavigation">true</item>
<item name="android:selectableItemBackground">@null</item>
<item name="android:selectableItemBackgroundBorderless">@null</item>
<item name="android:windowEnableSplitTouch">false</item>
<item name="android:splitMotionEvents">false</item>
<item name="android:textColorPrimary">@color/teal_700</item>
<item name="android:colorControlNormal">@android:color/white</item>
<item name="android:textColorAlertDialogListItem">@android:color/white</item>
</style>
然后在 AndroidManifest.xml 运用这个theme 。
下面咱们看看Java 代码
CharSequence[] stringList = new CharSequence[]{"苹果","香蕉","梨"};
private void showDialog4() {
int index = 1;
AlertDialog mDialog = new AlertDialog.Builder(MainActivity.this)
.setTitle("标题")
.setIcon(null)
.setNegativeButton(R.string.cancel, null)
.setPositiveButton(null, null)
.setSingleChoiceItems(stringList, index,null)
.create();
mDialog.show();
// 修正弹窗的布景色彩
mDialog.getWindow().setBackgroundDrawableResource(R.color.dialog_background_color);
}
作用如下所示。
不知道咱们有没有发现,上面的弹窗跟前面几个不一样的,它是动态加载的,里面的内容能够依据需求动态增加,这种动态变化的,假如我要修正苹果、香蕉这些文字的色彩是白色时,前面的几种办法中,第一种是很难进行修正的,这个是动态变化的也不是直接在xml 上写死能处理的。第二种也是能够的,便是载入style款式后,弹窗并没有官方的那么漂亮,假如你能写成一模一样,那当我没说。经过放射机制修正,也是能够,便是我试了一下,没找到怎样改(好吧,是我太菜!)。
好了,说了这么多,首要的需求便是,怎样把上面的苹果、香蕉这些文字的色彩改成白色。其实我已经给了处理方案 , 上面的 style 款式中的最终一行代码, 没错便是下面这行代码。 为什么是这行代码呢,不能别的吗? 额 ,还真不能! 下面听我娓娓道来。
<item name="android:textColorAlertDialogListItem">@android:color/white</item>
查找源码 values.xml 文件,查找 AlertDialog, 查找到下面的的方位。
其间下面赤色的框框是咱们要找的东西,这儿进入这个布局文件
在这个布局文件中,咱们能够发现下面设置 textColor , 这个便是设置选择框文字的色彩,咱们再点进去检查这个设置的资源
点击上面的资源会跳转到下面的方位 ,这儿能够看到一个name 为 textColorAlertDialogListItem 的资源,在这个文件中,查找这个name ,
就能够看到在这儿设置色彩,所以这个 android:textColorAlertDialogListItem 便是咱们要的东西。
在界说的布局文件中,从头界说这个 android:textColorAlertDialogListItem 的变量的色彩。也便是上面我写的这行代码。
<item name="android:textColorAlertDialogListItem">@android:color/white</item>
上面已经讲了一下修正弹窗款式的办法的思想办法,我写的款式很丑并不重要,重要的是这个思想,这种思想办法并不只是适用于弹窗的款式,其他安卓控件也是适用。究竟编程的思想是相通的。
下面我找到的一些常用的款式 仅供参考,具体作用还望实际操作后看作用。
<style name="AppThemeDemo" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- 运用的首要色彩,actionBar默许运用该色彩,Toolbar导航栏的底色 -->
<item name="colorPrimary">@color/white</item>
<!-- 运用的首要暗色彩,statusBarColor 默许运用该色彩 -->
<item name="colorPrimaryDark">@color/white</item>
<!-- 一般控件的选中作用默许采用该色彩,如 CheckBox,RadioButton,SwitchCompat,ProcessBar等-->
<item name="colorAccent">@color/colorAccent</item>
<!-- 状况栏、顶部导航栏 相关-->
<!-- status bar color -->
<item name="android:statusBarColor">#00000000</item>
<!-- activity 是否能在status bar 底部制作 -->
<item name="android:windowOverscan">true</item>
<!-- 让status bar通明,相当于statusBarColor=transparent + windowOverscan=true -->
<item name="android:windowTranslucentStatus">true</item>
<!-- 改变status bar 文字色彩, true黑色, false白色,API23可用-->
<item name="android:windowLightStatusBar">true</item>
<!-- 全屏显现,隐藏状况栏、导航栏、底部导航栏 -->
<item name="android:windowFullscreen">true</item>
<!-- hide title bar -->
<item name="windowNoTitle">true</item>
<!-- 底部虚拟导航栏色彩 -->
<item name="android:navigationBarColor">#E91E63</item>
<!-- 让底部导航栏变半通明灰色,掩盖在Activity之上(默许false,activity会居于底部导航栏顶部),假如设为true,navigationBarColor 失效 -->
<item name="android:windowTranslucentNavigation">true</item>
<!-- WindowBackground,能够设置@drawable,色彩引用(@color),不能设置色彩值(#fffffff),
Window区域阐明:Window涵盖整个屏幕显现区域,包括StatusBar的区域。当windowOverscan=false时,window的区域比Activity多出StatusBar,当windowOverscan=true时,window区域与Activity相同-->
<item name="android:windowBackground">@drawable/ic_launcher_background</item>
<!--<item name="android:windowBackground">@color/light_purple</item>-->
<!-- 控件相关 -->
<!-- button 文字是否全部大写(系统默许开)-->
<item name="android:textAllCaps">false</item>
<!-- 默许 Button,TextView的文字色彩 -->
<item name="android:textColor">#B0C4DE</item>
<!-- 默许 EditView 输入框字体的色彩 -->
<item name="android:editTextColor">#E6E6FA</item>
<!-- RadioButton checkbox等控件的文字 -->
<item name="android:textColorPrimaryDisableOnly">#1C71A9</item>
<!-- 运用的首要文字色彩,actionBar的标题文字默许运用该色彩 -->
<item name="android:textColorPrimary">#FFFFFF</item>
<!-- 辅助的文字色彩,一般比textColorPrimary的色彩弱一点,用于一些弱化的表示 -->
<item name="android:textColorSecondary">#C1C1C1</item>
<!-- 控件选中时的色彩,默许运用colorAccent -->
<item name="android:colorControlActivated">#FF7F50</item>
<!-- 控件按压时的色彩-->
<item name="android:colorControlHighlight">#FF00FF</item>
<!-- CheckBox,RadioButton,SwitchCompat等默许状况的色彩 -->
<item name="android:colorControlNormal">#FFD700</item>
<!-- 默许按钮的布景色彩 -->
<item name="android:colorButtonNormal">#1C71A9</item>
<!-- 【无效】 在theme中设置Activity的属性无效, 请到AndroidManifest中Activity标签下设置 -->
<item name="android:launchMode">singleTop</item>
<item name="android:screenOrientation">landscape</item>
</style>
代码已上传至 gitee :zpeien/AndroidProject – 码云 – 开源中国 (gitee.com)
在该项意图 DialogDemo文件夹中,该项目后期会继续更新!
好啦,这篇文章写到这儿就完毕了,预知后文怎样,请看我下篇文章,感谢您的观看!