`
ssrc0604hx
  • 浏览: 8992 次
文章分类
社区版块
存档分类
最新评论

【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 是菜单文字
 * @创建者 :集成显卡	1053214511@qq.com
 * @创建日期 :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
 * @功能描述 :
 *	确定对话框,显示标题,内容,还有确定和取消按钮
 * @创建者 :集成显卡	1053214511@qq.com
 * @创建日期 :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 被设置为了:请输入
 * @创建者 :集成显卡	1053214511@qq.com
 * @创建日期 :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

分享到:
评论

相关推荐

    Jquery.blockUI.Demo //// dialog.js

    而dialog.js则是jQuery.blockUI插件中的一个关键组件,它负责构建和管理对话框。本文将深入探讨这两个组件的工作原理和应用。 首先,我们来看jQuery.blockUI。这个插件是由Mike Alsup创建的,它的主要作用是阻止...

    Android自定义loading Dialog

    在Android开发中,自定义组件是一项常见的需求,特别是在创建用户界面时,为了提供更好的用户体验,开发者经常需要定制一些特殊的对话框(Dialog)。本教程将详细讲解如何实现一个自定义的加载对话框(Loading ...

    自定义dialog弹出框

    在Android开发中,自定义Dialog是一种常见的需求,它允许开发者根据应用的设计风格和功能需求创建具有独特外观和交互效果的对话框。本教程将深入探讨如何实现自定义Dialog,包括利用Shape和Selector来定制样式,以及...

    Android 自定义dialog

    在Android开发中,自定义Dialog是一种常见的需求,它允许开发者根据项目需求定制Dialog的样式、功能和交互方式,以提供更符合用户体验的界面。本文将深入探讨如何在Android中实现自定义Dialog,包括封装点击事件、...

    自定义Android Dialog EditText 密码输入框

    在Android开发中,自定义Dialog是一项常见的需求,它允许开发者根据应用的UI风格和功能需求进行个性化设计。本文将深入探讨如何自定义一个Android Dialog,特别是实现一个类似于支付密码输入框的功能,其中EditText...

    自定义对话框LoadingDialog和Toast

    在Android开发中,自定义对话框(Dialog)和Toast是两个常见的用户界面组件,用于向用户提供临时信息或在执行操作时显示加载状态。本篇将详细介绍如何创建具有Gif动画功能的自定义LoadingDialog和Toast。 一、...

    Android代码-自定义底部dialog

    Bottom Dialog ...A sample dialog... private BottomDialog dialog; dialog = new BottomDialog(MainActivity.this); dialog.title(R.string.app_name); dialog.canceledOnTouchOutside(true);

    Android Dialog中加载GIF

    2. **创建自定义Dialog**:创建一个继承自`android.app.Dialog`的自定义Dialog类,以便我们可以在其中添加自定义布局。例如,可以创建一个名为`MyLoadingDialog`的类: ```java public class MyLoadingDialog ...

    Android支付底部弹窗自定义dialog

    在Android应用开发中,自定义对话框(Dialog)是一种常见的用户交互方式,特别是在涉及到支付功能时,为了提供更好的用户体验,通常会使用底部弹窗来显示支付选项。本篇将详细介绍如何在Android中实现一个自定义的...

    Android自定义dialog

    在Android开发中,自定义Dialog是一种常见的需求,它允许开发者根据应用的设计风格和功能需求创建出独具特色的对话框。本文将深入探讨如何在Android中实现自定义Dialog,并提供相关实践步骤。 首先,我们来理解一下...

    自定义右上角带叉号Dialog Android 自定义layout Dialog

    在Android开发中,创建自定义对话框(Dialog)是一种常见的需求,这允许开发者根据应用的UI风格和功能需求定制对话框的布局和交互方式。本文将深入探讨如何创建一个自定义右上角带有关闭叉号的Dialog,并实现点击...

    android-styled-dialogs 可自定义样式的dialog Demo.zip

    在Android开发中,Dialog是一种常见的用户交互元素,用于在用户执行主要操作时提供额外信息或进行确认。"android-styled-dialogs 可自定义样式的dialog Demo.zip" 是一个示例项目,它展示了如何在Android应用程序中...

    Android界面之几种常用的自定义Dialog

    在Android开发中,自定义Dialog是一种常见的用户交互方式,它能提供比系统默认Dialog更为丰富的功能和视觉效果。本文将深入探讨几种常用的自定义Dialog的实现方法,以及如何通过自定义来满足各种复杂的UI需求。 ...

    各种自定义Dialog 以及Dialog加载动画

    在Android开发中,自定义Dialog和Dialog加载动画是提升应用用户体验的重要手段。默认的Dialog样式虽然功能齐全,但在追求个性化和美观的今天,往往显得过于简单甚至有些过时。因此,开发者常常需要根据应用的设计...

    android自定义精美的dialog

    在Android开发中,自定义对话框(Dialog)是提升用户体验和增强应用个性化的重要手段。一个精美的自定义Dialog不仅能够提供必要的信息,还能通过各种显示动画效果吸引用户的注意力,增加应用的趣味性和专业性。本篇...

    LoadingDialog

    "LoadingDialog"是一种在Android应用开发中常见的用户界面元素,用于在执行耗时操作(如数据加载、网络请求等)时向用户提供反馈,通常显示一个旋转的菊花图标和简短的文字提示,告知用户系统正在处理任务。...

    android 自定义右上角关闭按钮X的dialog

    在Android开发中,自定义对话框(Dialog)是一种常见的需求,它可以提供更加个性化的用户体验。本文将详细讲解如何实现一个自定义的右上角带有“X”文字按钮的Dialog,这个按钮可以用来关闭Dialog。 首先,我们需要...

    android自定义全屏dialog

    在Android开发中,自定义全屏Dialog是一种常见的需求,它能提供更为丰富的用户体验,比如用于展示大图或者视频预览。本篇文章将深入探讨如何在Android中实现一个自定义的全屏Dialog,以及如何实现全屏显示图片的功能...

    Android Dialog更改样式及显示位置

    在Android开发中,Dialog是一种常见的用户交互界面,用于在主线程中显示临时信息或进行简单的用户操作。默认情况下,Dialog会出现在屏幕中央,但开发者可以根据需求自定义其样式和显示位置。本文将深入探讨如何在...

Global site tag (gtag.js) - Google Analytics