当前位置: 代码迷 >> Android >> 实现
  详细解决方案

实现

热度:53   发布时间:2016-05-01 11:43:55.0
【android开发记录片】2.自定义/定制 Dialog组件

写在前面

好久没有更新android方面的博客,因为一直没搞,最近做一个小项目,用到了Dialog作弹出菜单 和 确认/输入框。这里跟大家分享一下我定制Dialog的方法。
下面是截图:

1.弹出菜单

   

2.确认框

 

3.输入框

 

4.颜色选择框

 

文件结构

包含dialog的封装类,layout文件,drawable文件。

 

 

 

 

 

实现

1.弹出菜单

首先定义对话框的事件接口:

	public interface MenuListener{		/**		 * @方法名称 :onClick		 * @功能描述 :		 * @param position 菜单项的下标		 * @return :void		 */		public void onMenuClick(int code, int position);	}		public interface ConfirmListener{				/**		 * @方法名称 :onConfirmClick		 * @功能描述 :当confirm对话框中的按钮被点击时		 * @param position		 * @return :void		 */		public void onConfirmClick(int position, Object obj);	}


然后定义一个layout,里面放一个GridView就好,还定义GridView 的Item的布局:

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"	android:id="@+id/RelativeLayout_Item"	android:layout_width="fill_parent" android:layout_height="wrap_content"	android:paddingBottom="1dip">		<ImageView android:id="@+id/item_image"		android:layout_centerHorizontal="true" 		android:layout_width="wrap_content"		android:layout_height="wrap_content"		android:contentDescription="@string/nothing" />		<TextView android:layout_below="@id/item_image" android:id="@+id/item_text"		android:layout_centerHorizontal="true" android:layout_width="wrap_content"		android:layout_height="wrap_content" android:text="@string/nothing" /></RelativeLayout>


接着是MenuDialog.java,内部有一个Dialog实例,对外提供show()方法:

public MenuDialog(Context context, int id) {		this.context = context;		this.id = id;	}		/**	 * @方法名称 :creatDialog	 * @功能描述 :创建一个菜单Dialog,需要有数据才得,否则 menuDialog 为null	 * @param menuDialog	 * @param data	 * @return :void	 */	public void creatDialog(final MenuData data){		if(data == null)			return ;		if(data.icons.length > 0){			View view = View.inflate(context, getMenuLayout(), null);						//优先使用图片作为背景			if(data.bgResource != -1){				view.setBackgroundDrawable(						UIFactory.getRepeatBG(context,data.bgResource)						);			}else if(data.bgColor != -1){				Log.i("CellNote", "set bgColor---------");				view.setBackgroundColor(data.bgColor);			}						GridView gView = (GridView)view.findViewById(GRID_ID);			gView.setAdapter(getMenuAdapter(data));						dialog = new Dialog(context);			dialog.show();			Window win = dialog.getWindow();			//将dialog的背景透明化			win.setBackgroundDrawable(new ColorDrawable(0));			win.setGravity(getGravity());			win.setContentView(view);						if(data.listener != null){				//注册菜单事件				gView.setOnItemClickListener(new OnItemClickListener() {					@Override					public void onItemClick(AdapterView<?> arg0, View arg1,							int arg2, long arg3) {						data.listener.onMenuClick(id,arg2);						if(data.onlyOneTime)							dialog.dismiss();					}				});			}						registerKey();						this.hasMenu = true;		}	}		/**	 * @方法名称 :show	 * @功能描述 :显示对话框	 * @return :void	 */	public void show(){		dialog.show();	}


在Activity中如此调用:

@Override	public boolean onCreateOptionsMenu(Menu menu) {		menu.add("danting");		return super.onCreateOptionsMenu(menu);	}	@Override	public boolean onMenuOpened(int featureId, Menu menu) {		hideKeyboard();				if (menuDialog == null) {			menuDialog = new MenuDialog(this, MENU_OPTION);			menuDialog.creatDialog(getMenuData());			Log.i("CellNote","menuDialog create!!");		}		if(menuDialog.hasMenu)			menuDialog.show();				// 返回false 阻止系统的菜单		return false;	}


上面是一个父类Activity通用的产生弹出菜单的方法(在onCreateOptionsMenu()方法,menu.add("");是一定要的,不要的话不会弹出对话框,这个不解=.=),子类只需要重写 getMenuData()方法就可以产生菜单,如:

/**	 * 产生菜单	 */	@Override	public MenuData getMenuData() {		MenuData data = new MenuData();		data.icons = new int[]{				R.drawable.ic_menu_color_home,				R.drawable.ic_menu_color_category,				R.drawable.ic_menu_color_note,				R.drawable.ic_menu_color_search,				R.drawable.ic_menu_color_setting,				R.drawable.ic_menu_color_bag,				R.drawable.ic_menu_color_help,				R.drawable.ic_menu_color_about			};		data.labels = new String[]{"首页","新分类","新便签","内容搜索","设置","备份/还原","帮助","关于我们"};		data.listener = this;		data.bgResource = R.drawable.bg_green_32x32;				return data;	}


上面用到了一个MenuData类,如下:

/** * @项目名称 :CellNote * @文件名称 :MenuDialog.java * @所在包 :org.nerve.cellnote.view * @功能描述 : *	菜单数据体,其中 icons 是菜单的图像引用,labels 是菜单文字 * @创建者 :集成显卡	[email protected] * @创建日期 :2013-1-23 * @修改记录 : */public static class MenuData{	/**背景的drawable,如果为-1,则使用默认的背景*/	public int bgResource = -1;	/**背景颜色*/	public int bgColor = -1;		/**菜单点击监听器*/	public MenuListener listener;	/**为true时,菜单被点击后后自动消失*/	public boolean onlyOneTime;		public int[] icons = new int[0];	public String[] labels;		public MenuData(){		this.onlyOneTime = true;	}		public MenuData(int [] is,String[] ls){		this();		this.icons = is;		this.labels = ls;	}}

 

 

2.确认对话框

定义layout:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="wrap_content"    android:background="@drawable/shape_dialog"    >      <TextView         android:id="@+id/dialog_title"        android:layout_width="fill_parent"        android:layout_height="35dp"        android:textSize="18sp"        android:textColor="#000000"        android:gravity="center"        />        <TextView         android:id="@+id/dialog_message"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:padding="20dp"        android:paddingBottom="2dp"        android:textColor="#000000"        />        <!-- 这个可以自由添加视图 -->    <LinearLayout         android:id="@+id/dialog_live"        android:orientation="vertical"        android:layout_width="fill_parent"        android:layout_height="wrap_content"       >           </LinearLayout>        <LinearLayout         android:id="@+id/dialog_button_group"        android:orientation="horizontal"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:paddingLeft="20dp"        android:paddingRight="20dp"        android:paddingBottom="15dp">                <Button             android:id="@+id/dialog_ok"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="@string/dialog_ok"            android:padding="3dp"            android:background="@drawable/shape_dialog_button_ok"            android:textColor="@color/black"            android:layout_marginRight="10dp"/>                 <Button             android:id="@+id/dialog_cannel"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_weight="1"            android:text="@string/dialog_cannel"            android:layout_marginLeft="10dp"            android:textColor="@color/black"            android:background="@drawable/shape_dialog_button_cannel"/>            </LinearLayout></LinearLayout> 


然后是ConfirmDialog.java:

package org.nerve.cellnote.view.dialog;import org.nerve.cellnote.R;import org.nerve.cellnote.view.dialog.DialogHelper.ConfirmListener;import android.app.Dialog;import android.content.Context;import android.graphics.drawable.ColorDrawable;import android.view.Gravity;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.WindowManager.LayoutParams;import android.widget.Button;import android.widget.LinearLayout;import android.widget.TextView;/** * @项目名称 :CellNote * @文件名称 :ConfirmDialog.java * @所在包 :org.nerve.cellnote.view.dialog * @功能描述 : *	确定对话框,显示标题,内容,还有确定和取消按钮 * @创建者 :集成显卡	[email protected] * @创建日期 :2013-1-28 * @修改记录 : */public class ConfirmDialog {	/**默认的对话框视图*/	public static int DIALOG_UI = R.layout.dialog_main;		/**默认的对话框占主屏幕多宽度的比例*/	public static float WIDTH_SCALE = 0.8F;		/**OK按钮被点击*/	public static final int OK = 0;	/**取消按钮点击*/	public static final int CANNEL = 1;		protected Context context;	protected Dialog dialog;	protected Button okBtn;	protected Button cannelBtn;		protected int id;	protected String title;	protected String message;		protected ConfirmListener listener;		public ConfirmDialog(Context context){		this.context = context;	}	public ConfirmDialog(Context context, String t, String m){		this(context);		this.title = t;		this.message = m;	}		public void setTitle(String t){		this.title = t;	}	public void setMessage(String m){		this.message = m;	}	public void setConfirmListener(ConfirmListener listener){		this.listener = listener;	}		protected void createDialog(){		View view = View.inflate(context, getMainXML(), null);				((TextView)view.findViewById(R.id.dialog_title)).setText(title);				//如果message为null,不显示		TextView messageTV = (TextView)view.findViewById(R.id.dialog_message);		if(message == null)			((LinearLayout)view).removeView(messageTV);		else			messageTV.setText(message);				dialog = new Dialog(context);		dialog.show();		Window win = dialog.getWindow();		//将dialog的背景透明化		win.setBackgroundDrawable(new ColorDrawable(0));		win.setGravity(getGravity());				LinearLayout ll = (LinearLayout)view.findViewById(R.id.dialog_live);		View liveView = getLiveView();		if(liveView != null){			ll.addView(liveView);		}				win.setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);		win.setContentView(view);				initButton(view);	}		public void show(){		if(dialog == null)			createDialog();		else			dialog.show();	}		/**	 * @方法名称 :initButton	 * @功能描述 :初始化按钮	 * 		 * @param view	 * @return :void	 */	protected void initButton(View view){		if(isButtonShow()){			okBtn = (Button)view.findViewById(R.id.dialog_ok);			cannelBtn = (Button)view.findViewById(R.id.dialog_cannel);			okBtn.setOnClickListener(new OnClickListener() {				@Override				public void onClick(View v) {					dialog.dismiss();					afterClickOK();				}			});						cannelBtn.setOnClickListener(new OnClickListener() {				@Override				public void onClick(View v) {					dialog.dismiss();				}			});		}else{			View v = view.findViewById(R.id.dialog_button_group);			((LinearLayout)view).removeView(v);		}	}		/**	 * @方法名称 :isButtonShow	 * @功能描述 :如果子类不需要显示按钮,可以重写这个方法。	 * @return	 * @return :boolean	 */	protected boolean isButtonShow(){		return true;	}		/**	 * @方法名称 :getMainXML	 * @功能描述 :获得主视图id	 * @return	 * @return :int	 */	public int getMainXML(){		return DIALOG_UI;	}		public int getGravity(){		return Gravity.CENTER;	}		/**	 * @方法名称 :afterClickOK	 * @功能描述 :确认按钮点击后触发,子类可以重写这个方法达到不同的效果	 * @return :void	 */	public void afterClickOK(){		if(listener != null)			listener.onConfirmClick(OK, null);	}	/**	 * @方法名称 :getLiveView	 * @功能描述 :得到一个扩展的视图,可以产生不同组合的对话框,子类可以重写这个方法	 * @return	 * @return :View	 */	public View getLiveView(){		return null;	}}


子类可以通过重写一些方法再定义对话框。

调用方法:

ConfirmDialog cd = new ConfirmDialog(this);cd.setTitle("关于我们");		StringBuilder about = new StringBuilder();about.append("名称:"+getString(R.string.app_name));about.append("\n版本:" + getString(R.string.app_version));about.append("\n作者:" + getString(R.string.app_author));about.append("\n简介:" + getString(R.string.app_information));about.append("\n邮箱:" + getString(R.string.app_email));		cd.setMessage(about.toString());cd.show();


 

3.输入对话框

dialog_single_input.xml:

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"        android:layout_width="fill_parent"        android:layout_height="wrap_content"      	android:paddingLeft="20dp"	    android:paddingRight="20dp"       >          <EditText 	    android:id="@+id/dialog_single_input"	    android:layout_width="fill_parent"	    android:layout_height="wrap_content"	    android:hint="@null" /></LinearLayout>


然后 SingleInputDialog 继承自 ConfirmDialog,重写getView() 方法,返回 上面的布局:

package org.nerve.cellnote.view.dialog;import org.nerve.cellnote.R;import android.content.Context;import android.view.View;import android.widget.EditText;/** * @项目名称 :CellNote * @文件名称 :SingleInputDialog.java * @所在包 :org.nerve.cellnote.view.dialog * @功能描述 : *	只有一个输入的对话框,在这里,message 被设置为了:请输入 * @创建者 :集成显卡	[email protected] * @创建日期 :2013-1-28 * @修改记录 : */public class SingleInputDialog extends ConfirmDialog{	protected EditText singleInput;		protected String defaultText;		public SingleInputDialog(Context context) {		super(context);	}		@Override	public View getLiveView() {		View lv = View.inflate(context, R.layout.dialog_single_input, null);		this.singleInput = (EditText)lv.findViewById(R.id.dialog_single_input);		this.singleInput.setText(defaultText);		return lv;	}		@Override	public void afterClickOK() {		listener.onConfirmClick(OK, singleInput.getText().toString());	}		public void setDefaultText(String t){		this.defaultText = t;	}}


调用方法:

SingleInputDialog sd = new SingleInputDialog(this);				String title = getString(R.string.category_input);		sd.setTitle(title);		sd.setMessage(title + ":");				sd.setConfirmListener(new ConfirmListener() {			@Override			public void onConfirmClick(int position, Object obj) {				String name = (String)obj;				newCategoryDo(name);			}		});		sd.show();



恩,帖了好多代码,这里就源文件打包给大家下载,下载导入到自己的工程里便可以看到效果:http://download.csdn.net/detail/ssrc0604hx/5062435

  相关解决方案