赞
踩
我们自己清楚,android的原生控件实在是不堪入目,在很多时候无法满足项目需求,所以在项目进行的过程中,我们很多时候就需要自定义控件,继承重写从而实现我们的需求。并且自定义控件将体现代码的复用,分层的架构学管理,妙用无穷。本文将详细介绍自定义Dialog的多种思路以及给出如何进行自定义控件的指南。
1.复用率不高的,而且在dialog进行的逻辑处理较多的情况下,建议使用将dialog封装成一个类,继承基本的Dialog类实现。(在这里的后面会详细说明自定义样式的问题喔!)
2.复用率高,而且每个dialog都要求有固定的布局格式的话,建议使用一个BaseDialog类作为你实际实现dialog的父类
先上图: 就是这种仿谷歌风格的自定义dialog啦!!
首先当然是你想要的dialog布局,这里你自己想怎么折腾就怎么折腾随你。由于这里使用了radiobutton的多向运用,可在此不详细解析,欲想看明radiobutton的多向运用请看我的另一篇博客: Android之RadioButton和RadioGroup结合Dialog的多种运用详解
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="360dp" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:layout_height="30dp" android:layout_gravity="center" android:layout_marginTop="20dp" android:orientation="horizontal"> <ImageView android:id="@+id/icon_title" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginLeft="18dp" android:gravity="center" android:src="@drawable/setting" /> <TextView android:id="@+id/title" android:layout_width="match_parent" android:layout_height="30dp" android:layout_marginLeft="20dp" android:gravity="center_vertical" android:text="广播周期设定" android:textSize="17sp" /> </LinearLayout> <RadioGroup android:id="@+id/groupBroadcast" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="18dp" android:layout_marginTop="10dp" android:orientation="vertical"> <RadioButton android:id="@+id/rbtn_BroadcastClose" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:button="@null" android:checked="true" android:drawableLeft="@drawable/settingbroadst_checked_style" android:drawablePadding="20dp" android:paddingLeft="18dp" android:text="关闭" android:textColor="@android:color/black" android:textSize="17sp" /> <RadioButton android:id="@+id/rbtn_BroadcastFifteen" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_weight="1" android:button="@null" android:drawableLeft="@drawable/settingbroadst_checked_style" android:drawablePadding="20dp" android:paddingLeft="18dp" android:text="15秒" android:textColor="@android:color/black" android:textSize="17sp" /> <RadioButton android:id="@+id/rbtn_BroadcastThirty" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_weight="1" android:button="@null" android:drawableLeft="@drawable/settingbroadst_checked_style" android:drawablePadding="20dp" android:paddingLeft="18dp" android:text="30秒" android:textColor="@android:color/black" android:textSize="17sp" /> <RadioButton android:id="@+id/rbtn_BroadcastFourty" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:layout_weight="1" android:button="@null" android:drawableLeft="@drawable/settingbroadst_checked_style" android:drawablePadding="20dp" android:paddingLeft="18dp" android:text="45秒" android:textColor="@android:color/black" android:textSize="17sp" /> <RadioButton android:id="@+id/rbtn_BroadcastMinute" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="10dp" android:layout_marginTop="10dp" android:layout_weight="1" android:button="@null" android:drawableLeft="@drawable/settingbroadst_checked_style" android:drawablePadding="20dp" android:paddingLeft="18dp" android:text="60秒" android:textColor="@android:color/black" android:textSize="17sp" /> </RadioGroup> </LinearLayout>
然后就是封装的dialog的类啦
package org.fishDroneGCS.view; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.os.Bundle; import android.view.Display; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.widget.AdapterView; import android.widget.RadioButton; import android.widget.RadioGroup; import org.fishDroneGCS.android.R; /** * Created by 符柱成on 2016/8/7. */ public class RadioButtonDialog extends Dialog { private Context context; private String title; //这里定义个title,一会可以看到是指向上面xml文件的控件title的,也就是我们可以通过这个进行动态修改title private AdapterView.OnItemClickListener onItemClickListener; //这里定义了一个监听是为了实现内部的监听接口处理,从而实现代码分层管理 //可以看到两个构造器,想自定义样式的就用第二个啦 public RadioButtonDialog(Context context) { super(context); this.context = context; } public RadioButtonDialog(Context context, int theme) { super(context, theme); this.context = context; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); } public void setTitle(String title) { this.title = title; } public String getTitle() { return title; } public void setOnItemClickListener(AdapterView.OnItemClickListener onItemClickListener) { if (onItemClickListener != null) this.onItemClickListener = onItemClickListener; } //控件的声明 RadioButton rbtn_BroadcastClose; RadioButton rbtn_BroadcastFifteen; RadioButton rbtn_BroadcastThirty; RadioButton rbtn_BroadcastFourty; RadioButton rbtn_BroadcastMinute; private void init() { //以view的方式引入,然后回调activity方法,setContentView,实现自定义布局 View view = LayoutInflater.from(context).inflate(R.layout.dialog_broadcast, null); setContentView(view); //radiobutton的初始化 RadioGroup groupBroadcast = (RadioGroup) view.findViewById(R.id.groupBroadcast); rbtn_BroadcastClose = (RadioButton) view.findViewById(R.id.rbtn_BroadcastClose); rbtn_BroadcastFifteen = (RadioButton) view.findViewById(R.id.rbtn_BroadcastFifteen); rbtn_BroadcastThirty = (RadioButton) view.findViewById(R.id.rbtn_BroadcastThirty); rbtn_BroadcastFourty = (RadioButton) view.findViewById(R.id.rbtn_BroadcastFourty); rbtn_BroadcastMinute = (RadioButton) view.findViewById(R.id.rbtn_BroadcastMinute); groupBroadcast.setOnCheckedChangeListener(listener); //设置dialog大小,这里是一个小赠送,模块好的控件大小设置 Window dialogWindow = getWindow(); WindowManager manager = ((Activity) context).getWindowManager(); WindowManager.LayoutParams params = dialogWindow.getAttributes(); // 获取对话框当前的参数值 dialogWindow.setGravity(Gravity.CENTER);//设置对话框位置 Display d = manager.getDefaultDisplay(); // 获取屏幕宽、高度 params.width = (int) (d.getWidth() * 0.8); // 宽度设置为屏幕的0.65,根据实际情况调整 dialogWindow.setAttributes(params); } //监听接口 private RadioGroup.OnCheckedChangeListener listener = new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { if (checkedId == rbtn_BroadcastClose.getId()) { } else if (checkedId == rbtn_BroadcastFifteen.getId()) { } else if (checkedId == rbtn_BroadcastThirty.getId()) { } else if (checkedId == rbtn_BroadcastFourty.getId()) { } else if (checkedId == rbtn_BroadcastMinute.getId()) { } } }; }
调用:
RadioButtonDialog radioButtonDialog=new RadioButtonDialog(getActivity(),R.style.Dialog);
radioButtonDialog.setTitle("广播周期设定");
radioButtonDialog.create();
radioButtonDialog.show();
就是这么简单的调用,使其代码的简约,逻辑分层管理的实现了。此外,大家注意到那个我们这里使用的是自定义样式。
在style文件里面定义以下:
<style name="Dialog" parent="android:style/Theme.Dialog">
<!-- 第一个是dialog的背景色,当然你可以设置图片,不拦大家 -->
<item name="android:background">@color/white</item>
<!-- 第二个就是弹出dialog后,下面的activity层的颜色啦-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--这里设置为没有标题栏,如果这里不设置的话,你会发现无论布局怎么改都会出现多一栏白色 -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">@null</item><!--边框-->
</style>
好了第一种思路的实现就是这样啦。这里补充一些关于自定义dialog样式的style标签
<item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">false</item><!--半透明-->
<item name="android:backgroundDimEnabled">false</item><!--模糊-->
父类dialog的封装:BaseDialog.java
public abstract class BaseDialog extends Dialog { private Context context; //下面三个定义的跟上面讲得就是一样的啦 private String title; private OnItemCheckListener onItemCheckListener; protected View view; //看到这里我们定义的就清楚,我们也是借用view这个父类来引入布局的 public BaseDialog(Context context) { super(context); } public BaseDialog(Context context, int themeResId) { super(context, themeResId); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); init(); } public void setTitle(String title) { this.title = title; } public String getTitle() { return title; } public void setOnItemCheckListener(OnItemCheckListener onItemCheckListener) { if (onItemCheckListener != null) this.onItemCheckListener = onItemCheckListener; } protected void init() { //以view来引入布局 View view = LayoutInflater.from(context).inflate(getLayoutId(), null); this.view=view; setContentView(view); //设置dialog大小 Window dialogWindow = getWindow(); WindowManager manager = ((Activity) context).getWindowManager(); WindowManager.LayoutParams params = dialogWindow.getAttributes(); // 获取对话框当前的参数值 dialogWindow.setGravity(Gravity.CENTER); Display d = manager.getDefaultDisplay(); // 获取屏幕宽、高度 params.width = (int) (d.getWidth() * 0.8); // 宽度设置为屏幕的0.65,根据实际情况调整 dialogWindow.setAttributes(params); } //可以看到这里定义了一个抽象方法,这个将交由子类去实现 public abstract int getLayoutId(); //为了逻辑分层管理,接口的管理实现方式 public interface OnItemCheckListener { void onItemCheck(int checkedId); } }
public class RadioButtonDialog extends BaseDialog { private Context context; private String title; private OnItemCheckListener onItemCheckListener; public RadioButtonDialog(Context context) { super(context); this.context = context; } public RadioButtonDialog(Context context, int theme) { super(context, theme); } //回调这个方法啦 @Override public int getLayoutId() { return 0; } //也回调了父类的init,利用getLayoutId传入了布局的id @Override protected void init() { super.init(); RadioGroup groupBroadcast = (RadioGroup) view.findViewById(R.id.groupBroadcast); groupBroadcast.setOnCheckedChangeListener(listener); } private RadioGroup.OnCheckedChangeListener listener = new RadioGroup.OnCheckedChangeListener() { @Override public void onCheckedChanged(RadioGroup group, int checkedId) { onItemCheckListener.onItemCheck(checkedId); } }; public interface OnItemCheckListener { void onItemCheck(int checkedId); } }
比如:标题和确定键以及取消键都要求固定格式,实现:
1.子类要设置布局,所以要在父类留一个设置内容的方法,就像上面父类那样,写一个抽象方法,然后dialog中间布局就写一个布局并且附上id,在父类方法addView,像getLayoutId那样,然后子类回调这个方法,在addView里面,set上我们自定义的dialog内容布局就可以实现啦!!!
欢迎在下方指出错误,共同学习!
转载请表明【JackFrost的博客】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。