Android实例-手机安全卫士(四十一)-选择自定义Toast背景
一、目标
通过对话框选择并保存自定义的Toast背景
二、代码实现
1、复制layout文件夹中的model_setting_item.xml文件,以其为模板进行修改(取名为model_choise_item),标题和内容为两个TextView对象、箭头为ImageView对象、直线为View对象,并根据设计进行布局;
model_choise_item布局代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <?xml version="1.0" encoding="utf-8"?> 2 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:layout_marginLeft="10dip" 6 android:layout_marginRight="10dip" > 7 8 <TextView 9 android:text="标题" 10 android:id="@+id/choise_item_title" 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content" 13 android:layout_marginTop="10dip" 14 android:textColor="#000000" 15 android:textSize="22dip" /> 16 17 <TextView 18 android:text="描述信息" 19 android:id="@+id/choise_item_content" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content" 22 android:layout_below="@id/choise_item_title" 23 android:textColor="#88000000" 24 android:textSize="18dip" /> 25 26 <ImageView 27 android:src="@drawable/ic_btn_search_go" 28 android:id="@+id/choise_item_imageview" 29 android:layout_width="wrap_content" 30 android:layout_height="wrap_content" 31 android:layout_alignParentRight="true" 32 android:layout_centerVertical="true" /> 33 34 <View 35 android:layout_width="match_parent" 36 android:layout_height="0.1dip" 37 android:layout_below="@id/choise_item_content" 38 android:layout_marginTop="2dip" 39 android:background="#70000000" /> 40 41 </RelativeLayout>
2、在src文件夹中的ui包(com.example.mobilesafe.ui)中,以名为SettingItemView的UI类为模板进行修改(取名ChoiseItemView),并通过View对象的inflate(Context context, int resource, ViewGroup root)方法将1中的布局文件加载至新建的UI类(ChoiseItemView)中。
(以上步骤可参照第七节自定义组合控件的介绍)
3、在“设置中心”的布局文件(activity_setting)的最后新增一个第1、2步中自定义的组合控件(com.example.mobilesafe.ui.ChoiseItemView),
4、在“设置中心”页面中定义组合控件ChoiseItemView的成员变量(取名set_toast_bg)和SharedPreferences对象(取名sp,用于保存已选择的风格);
5、实例化一个String数组(取名toastStyles),用于Toast风格的命名;
6、通过findViewById(int id)方法实例化组合控件成员变量(set_toast_bg),并设置其标题文本为要求的文本(归属地信息显示风格);
7、通过getSharedPreferences(String name, int mode)方法实例化SharedPreferences对象(sp),参数name为配置文件(config),类型为私有(MODE_PRIVATE);
8、通过SharedPreferences对象(sp)的getInt(String key, int defValue)方法获取配置文件中保存的风格名称(在配置文件中风格参数名称为ToastStyle,保存的值即为风格数组对应角标),key即为风格参数ToastStyle,defValue为当参数找不到时返回的默认值(此时为0)。该方法返回值Int类型的值(取名为toastStyle);
9、通过定义组合控件ChoiseItemView(set_toast_bg)中定义的设置显示内容的方法setContent(String content),将8中返回风格角标值(即toastStyle)对应的风格数组中的文本显示值控件中;
第5至9步代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 public class ChoiseItemView extends RelativeLayout { 2 3 private TextView choise_item_title,choise_item_content; 4 private String title,content; 5 6 private void iniView(Context context) { 7 View.inflate(context, R.layout.model_choise_item, ChoiseItemView.this); 8 choise_item_title = (TextView) this.findViewById(R.id.choise_item_title); 9 choise_item_content = (TextView) this.findViewById(R.id.choise_item_content); 10 } 11 12 /** 13 * 带有三个参数的构造方法在需要传入样式时调用 14 */ 15 public ChoiseItemView(Context context, AttributeSet attrs, int defStyle) { 16 super(context, attrs, defStyle); 17 iniView(context); 18 } 19 20 /** 21 * 带有两个参数的构造方法在布局文件中放置控件的时候调用 22 */ 23 public ChoiseItemView(Context context, AttributeSet attrs) { 24 super(context, attrs); 25 iniView(context); 26 title = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.mobilesafe", "title"); 27 content = attrs.getAttributeValue("http://schemas.android.com/apk/res/com.example.mobilesafe", "content"); 28 choise_item_title.setText(title); 29 choise_item_content.setText(content); 30 } 31 32 /** 33 * 带有一个参数的构造方法在new的时候调用 34 */ 35 public ChoiseItemView(Context context) { 36 super(context); 37 iniView(context); 38 } 39 40 /** 41 * 设置组合控件显示的标题 42 * @param Title:要显示的标题 43 */ 44 public void setTitle(String Title){ 45 choise_item_title.setText(Title); 46 } 47 48 /** 49 * 设置组合控件显示的内容 50 * @param content:要显示的内容 51 */ 52 public void setContent(String content){ 53 choise_item_content.setText(content); 54 } 55 }
10、通过自定义控件(set_toast_bg)的setOnClickListener(OnClickListener l)为其设置点击事件监听器,参数OnClickListener 通过new OnClickListener()实例化,并实现未实现的onClick方法
在onClick方法中
(1)通过SharedPreferences对象(sp)的getInt(String key, int defValue)方法获取已经在配置文件中保存的样式风格(ToastStyle),该方法返回值为int类型(取名toastStyleSaved);
(2)通过new Builder(Context context)实例化一个AlertDialog.Builder对象(取名toastStylesDialog,用于创建一个选择风格的对话框),参数context为对话框创建时的上下文(此时为SettingActivity.this);
(3)通过Builder对象(toastStylesDialog)的setTitle(CharSequence title)方法按要求设置对话框的标题;
(4)通过Builder对象(toastStylesDialog)的setSingleChoiceItems(CharSequence[] items, int checkedItem, OnClickListener listener)方法为对话框确定单项选中时的执行语句,参数items为对话框中要显示的数组(此时即为5中的风格名称数组),参数checkedItem为选中的条目所在的位置序号(此时为0),参数listener为选中单项时的监听器,该监听器通过new实例化,实例化时由于该监听器是接口类型,所以需要在其前面指出其父类(即new DialogInterface.OnClickListener()),并且需要实现其未实现的onClick方法,在onClick方法中:
①通过SharedPreferences对象(sp)的edit()方法获取一个Editor对象(取名editer);
②通过Editor对象(editer)的putInt(String key, int value)方法将选中的风格序号(也是风格名称数组的角标,即onClick方法里传入的第二个Int类型参数which);
③通过Editor对象(editer)的commit()方法提交;
④通过自定义控件(set_toast_bg)的setContent(String content)方法将选中的风格名称(即角标对应的风格序号的内容)显示至控件里;
⑤通过onClick方法传入的第一个参数对话框接口(dialog)的dismiss()方法使对话框消失;
(5)通过Builder对象(toastStylesDialog)的setNegativeButton(CharSequence text, OnClickListener listener)方法设置对话框消极按钮,参数text即为显示的文本(此时为取消),参数listener为点击事件监听器(此时不需要为Null);
(6)通过Builder对象(toastStylesDialog)的show()方法将对话框显示出来。
自定义的归属地Toast背景代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 //设置自定义的归属地Toast背景,并以SharedPreferences对象保存设置 2 final String[] toastStyles = {"天空蓝","草木绿","金属灰","土豪金","半透明"}; 3 set_toast_bg = (ChoiseItemView) findViewById(R.id.setting_toast_bg_style); 4 set_toast_bg.setTitle("归属地信息显示风格");//设置控件标题 5 sp = getSharedPreferences("config", MODE_PRIVATE); 6 int toastStyle = sp.getInt("ToastStyle", 0);//获取已保存的风格对应的角标,默认返回为0 7 set_toast_bg.setContent(toastStyles[toastStyle]);//将已保存的风格名称显示到内容文本中 8 //设置点击事件,弹出选择对话框 9 set_toast_bg.setOnClickListener(new OnClickListener() { 10 11 @Override 12 public void onClick(View v) { 13 int toastStyleSaved = sp.getInt("ToastStyle", 0);//获取配置文件中已保存的样式风格 14 //弹出对话框 15 AlertDialog.Builder toastStylesDialog = new Builder(SettingActivity.this); 16 toastStylesDialog.setTitle("归属地信息显示风格"); 17 toastStylesDialog.setSingleChoiceItems(toastStyles,toastStyleSaved, new DialogInterface.OnClickListener() { 18 19 @Override 20 public void onClick(DialogInterface dialog, int which) { 21 22 //以SharedPreferences对象保存选择的风格 23 Editor editer = sp.edit(); 24 editer.putInt("ToastStyle", which); 25 editer.commit(); 26 //设置自定义组合控件(set_toast_bg)的显示内容为选择的风格名称 27 set_toast_bg.setContent(toastStyles[which]); 28 //对话框消失 29 dialog.dismiss(); 30 } 31 }); 32 toastStylesDialog.setNegativeButton("取消", null); 33 toastStylesDialog.show(); 34 } 35 });
11、实现各个自定义Toast背景。在“号码归属地显示”服务(ShowPhoneAddService)中的自定义吐司方法(myToast)
(1)根据“设置中心”(SettingActivity)页面的自定义Toast背景类型数组的顺序,将各个自定义的Toast背景的资源id加载至新建的Int数组(取名toastBGs)中,其中由于“半透明”样式无对应的图片资源,因此只能通过改变Toast背景的透明度来实现;
(2)通过View对象的inflate()方法将资源加载进来后,通过SharedPreferences对象获取已经设置保存的自定义Toast样式;
(3)判断保存的样式是不是特殊的“半透明”样式,如是则通过View对象(view)的setBackgroundColor(int color)方法将其透明度设为一半(值color.transparent),如不是则通过View对象(view)的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 int[] toastBGs = {R.drawable.toast_bg_blue,R.drawable.toast_bg_green,R.drawable.toast_bg_gray,R.drawable.toast_bg_gold,5};//加载各个自定义Toast背景样式,最后的5是半透明,无样式则通过修改背景透明度实现 2 view = View.inflate(this, R.layout.phone_add_toast, null); 3 SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE); 4 int toastStyleSaved = sp.getInt("ToastStyle", 0);//通过SharedPreferences对象获取已经设置保存的自定义Toast样式 5 if(toastStyleSaved == 4)//判断保存的Toast样式是不是特殊样式(半透明) 6 view.setBackgroundColor(color.transparent);//如果是半透明,则改变Toast样式背景为半透明 7 else { 8 view.setBackgroundResource(toastBGs[toastStyleSaved]);//如果不是则根据样式的索引加载资源 9 }