前段时间,做了一个android涂鸦板项目(http://mm.10086.cn/1007/300001153536.html?fw=411130 ),在项目中,用到了一些自定义的对话框,如图所示。

在参考了android提供的ApiDemos程序以后,这里对如何实现自己定义的对话框进行一下总结。
在android 的ApiDemos中的com.example.android.apis.graphics包下,有一个ColorPickerDialog类,是经典 的自定义对话框的例子,我们在去除一些代码,剩下的主框架代码如下(代码中的注释详细注明每个类和方法的用途):
public class ColorPickerDialog extends Dialog {

/**
* 监听接口,通过此接口,可以把自定义Dialog需要向外界传递的信息,传递出去
*/
public interface OnColorChangedListener {
void colorChanged(int color);
}

/**
* 需要在对话框(ColorPickerDialog)上呈现的视图,我们自定义对话框的工作,主要就是构造出一个这样的视图
*/
private static class ColorPickerView extends View {

private OnColorChangedListener mListener;

/**
* ColorPickerView的构造函数,可以在这个构造函数里用android自带的控件,比如说LinearLayout、EditText和SeekBar等,把ColorPickerView构造出来。
* 也可以在onDraw(Canvas canvas)函数中,把ColorPickerView给绘制出来,ColorPickerView采用的就是这种方法。
*/
ColorPickerView(Context c, OnColorChangedListener l, int color) {
super(c);
}

/**
* 在这个函数里把ColorPickerView给绘制出来
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
}

/**
* 通过此方法来设置ColorPickerView的宽度和高度
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(CENTER_X*2, CENTER_Y*2);
}

/**
* 在这个函数里,调用监听接口OnColorChangedListener的方法,把此自定义Dialog需要向外界传递的信息设置进去
*/
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
mListener.colorChanged(mCenterPaint.getColor());//这条语句调用了监听接口的方法,把信息设置了进去
}
return true;
}
}


/**
* 自定义对话框的构造方法
*/
public ColorPickerDialog(Context context,
OnColorChangedListener listener,
int initialColor) {
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OnColorChangedListener l = new OnColorChangedListener() {
public void colorChanged(int color) {
mListener.colorChanged(color);
dismiss();
}
};

/**
* 只要通过ColorPickerDialog的setContentView方法,即可把我们辛苦绘制的ColorPickerView视图在对话框上呈现出来。
*/
setContentView(new ColorPickerView(getContext(), l, mInitialColor));
setTitle("Pick a Color");//这条语句设置对话框的标题
}
}

总的来说,创建自定义Dialog的关键只有两个步骤:
1.创建一个需要在自定义Dialog显示的自定义View,创建这个自定义View时,既可以在这个View的构造方法中用android自带的控件把 自定义View构造出来;也可以在自定义View的@Override protected void onDraw(Canvas canvas)方法中,把自定义View绘制出来
2.在自定义Dialog的@Override protected void onCreate(Bundle savedInstanceState)方法中,通过setContentView(自定义View);方法,把我们的自定义View显示出来
在创建好自定义Dialog后,我们在别的类中,只要调用自定义Dialog的构造函数就可以把自定义Dialog显示出来。对于 ColorPickerDialog这个类,调用语句如下:new ColorPickerDialog(getContext(), listener, mPaint.getColor()).show();


下面提供一个在自定义View的构造函数中把View构造出来的例子:


/**
* 文字对话框
*/
public class TextDialog extends Dialog implements SeekBar.OnSeekBarChangeListener{

private LinearLayout linearLayout;
private EditText etForText;
private SeekBar seekBar;
private TextView tvForSeekBar;
private Button btnOk;
private Button btnCancel;
private LinearLayout topChildLinearLayout;
private LinearLayout bottomChildLinearLayout;

private OnTextInputListener mListener;
/**
* 文字对话框标题
*/
private String title = "请输入文字与选择文字大小";

public interface OnTextInputListener {
void textInput(String text, int textSize);
}

public TextDialog(Context context, OnTextInputListener listener)
{
super(context);
mListener = listener;

linearLayout = new LinearLayout(getContext());
linearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setGravity(Gravity.CENTER);

etForText = new EditText(context);
etForText.setMinLines(5);//设置最大行数

seekBar = new SeekBar(context);
seekBar.setLayoutParams(new LinearLayout.LayoutParams(200, LayoutParams.FILL_PARENT));
seekBar.setMax(100);
seekBar.setProgress(50);
seekBar.setOnSeekBarChangeListener(this);

tvForSeekBar = new TextView(context);
tvForSeekBar.setText("50");

btnOk = new Button(getContext());
btnOk.setText("确定");

btnCancel = new Button(getContext());
btnCancel.setText("取消");

linearLayout.addView(etForText);

topChildLinearLayout = new LinearLayout(getContext());
topChildLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
topChildLinearLayout.setOrientation(LinearLayout.HORIZONTAL);

topChildLinearLayout.addView(seekBar);
topChildLinearLayout.addView(tvForSeekBar);

linearLayout.addView(topChildLinearLayout);

bottomChildLinearLayout = new LinearLayout(getContext());
bottomChildLinearLayout.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
bottomChildLinearLayout.setOrientation(LinearLayout.HORIZONTAL);
bottomChildLinearLayout.setGravity(Gravity.CENTER);

bottomChildLinearLayout.addView(btnOk);
bottomChildLinearLayout.addView(btnCancel);

linearLayout.addView(bottomChildLinearLayout);

btnOk.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
//验证text是否为空
String text = etForText.getText().toString()/*.replace("/n", "")*/;
if(text == null || text.trim().equals(""))
{
Toast.makeText(getContext(), "文字不能为空", Toast.LENGTH_SHORT).show();
return;
}

int textSizeInt = Integer.valueOf(tvForSeekBar.getText().toString());
mListener.textInput(text, textSizeInt);
dismissDialog();
}
});

btnCancel.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
dismissDialog();
}
});
}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(linearLayout);
setTitle(title);
}

public void dismissDialog()
{
this.dismiss();
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
// TODO Auto-generated method stub
tvForSeekBar.setText(progress + "");
}

@Override
public void onStartTrackingTouch(SeekBar seekBar)
{
// TODO Auto-generated method stub
}

@Override
public void onStopTrackingTouch(SeekBar seekBar)
{
// TODO Auto-generated method stub
}
}

此自定义Dialog的效果图如下:

android 自定义对话框_第1张图片

全文结束,谢谢大家。

说到对话框你肯定会想到AlertDialog.Builder。当然这次不是用AlertDialog.Builder来实现的!而是Dialog类

AlertDialog.Builder提供的方法有:
setTitle():给对话框设置title.
setIcon():给对话框设置图标。
setMessage():设置对话框的提示信息
setItems():设置对话框要显示的一个list,一般用于要显示几个命令时
setSingleChoiceItems():设置对话框显示一个单选的List
setMultiChoiceItems():用来设置对话框显示一系列的复选框。
setPositiveButton():给对话框添加”Yes”按钮。
setNegativeButton():给对话框添加”No”按钮。
那么在Dialog类怎样实现的呢?当然是layout啦,你可以自定义一个xml来布置你对话框
看看例子和源码吧
package com.hl;

import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.view.Gravity;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
public class MyDialog extends Activity implements android.view.View.OnClickListener {
Button btn1=null;
Button btn2=null;
Button btn3=null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn1=(Button)findViewById(R.id.b1);
btn2=(Button)findViewById(R.id.b2);
btn3=(Button)findViewById(R.id.b3);
btn1.setOnClickListener(this);
btn2.setOnClickListener(this);
btn3.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch(v.getId()){
case R.id.b1:
break;
case R.id.b2:
case R.id.b3:
new MyDialogs(this).setDisplay();
break;
default:

}
}
class MyDialogs extends Dialog implements android.view.View.OnClickListener{
private Button b1;
private Window window=null;

public MyDialogs(Context context){
super(context);
}
public void setDisplay(){
setContentView(R.layout.dialog);//设置对话框的布局
b1=(Button)findViewById(R.id.clo);
b1.setOnClickListener(this);
setProperty();
setTitle("自定义对话框");//设定对话框的标题
show();//显示对话框
}
//要显示这个对话框,只要创建该类对象.然后调用该函数即可.
public void setProperty(){
window=getWindow();//   得到对话框的窗口.
WindowManager.LayoutParams wl = window.getAttributes();
wl.x =0;//这两句设置了对话框的位置.0为中间
wl.y =180;
wl.alpha=0.6f;//这句设置了对话框的透明度
wl.gravity=Gravity.BOTTOM;
window.setAttributes(wl);
}
@Override
public void onClick(View v) {
dismiss();//取消
}
}
}

附件下载:
MyDialog.rar 40.76KB

自定义Android对话框的显示位置

系统中所有对话框,默认布局方式都是居中显示,如果想自定义显示位置可以考虑如下方式:

  1. ……
  2. Window mWindow = dialog.getWindow();
  3. WindowManager.LayoutParams lp = mWindow.getAttributes();
  4. lp.x= xxx;
  5. lp.y= xxx;
复制代码

缺省居中lp.x=0,lp.y=0

新坐标 x小于0左移,大于0右移;y小于0上移,大于0下移

  1. @Override
  2. protected void onDestroy() {
  3. super.onDestroy();
  4. android.os.Process.killProcess(android.os.Process.myPid());
  5. }
  6. public static String wrap(String str, int wrapLength, String newLineStr, boolean wrapLongWords) {
  7. if (str == null) {
  8. return null;
  9. }
  10. if (newLineStr == null) {
  11. newLineStr = System.getProperty("line.separator");
  12. }
  13. if (wrapLength < 1) {
  14. wrapLength = 1;
  15. }
  16. int inputLineLength = str.length();
  17. int offset = 0;
  18. StringBuffer wrappedLine = new StringBuffer(inputLineLength + 32);
  19. while ((inputLineLength - offset) > wrapLength) {
  20. if (str.charAt(offset) == ' ') {
  21. offset++;
  22. continue;
  23. }
  24. int spaceToWrapAt = str.lastIndexOf(' ', wrapLength + offset);
  25. if (spaceToWrapAt >= offset) {
  26. // normal case
  27. wrappedLine.append(str.substring(offset, spaceToWrapAt));
  28. wrappedLine.append(newLineStr);
  29. offset = spaceToWrapAt + 1;
  30. } else {
  31. // really long word or URL
  32. if (wrapLongWords) {
  33. // wrap really long word one line at a time
  34. wrappedLine.append(str.substring(offset, wrapLength + offset));
  35. wrappedLine.append(newLineStr);
  36. offset += wrapLength;
  37. } else {
  38. // do not wrap really long word, just extend beyond limit
  39. spaceToWrapAt = str.indexOf(' ', wrapLength + offset);
  40. if (spaceToWrapAt >= 0) {
  41. wrappedLine.append(str.substring(offset, spaceToWrapAt));
  42. wrappedLine.append(newLineStr);
  43. offset = spaceToWrapAt + 1;
  44. } else {
  45. wrappedLine.append(str.substring(offset));
  46. offset = inputLineLength;
  47. }
  48. }
  49. }
  50. }
  51. // Whatever is left in line is short enough to just pass through
  52. wrappedLine.append(str.substring(offset));
  53. return wrappedLine.toString();
  54. }

Android自定义对话框(Dialog)

实现的效果是:

“长按图标可移动位置或删除

下次不再提示

确定 取消

Acitivity

view source print ?
01LayoutInflater inflater = LayoutInflater.from(this );
02 checkView = inflater.inflate(R.layout.dialog, null);
03
04 //实例化复选框
05 cb = (CheckBox)checkView.findViewById(R.id.cb1);
06 //对复选框设置事件监听
07 cb.setOnCheckedChangeListener( new CheckBox.OnCheckedChangeListener(){
08 @Override
09 public void onCheckedChanged(CompoundButton arg0,boolean arg1) {
10 if (cb.isChecked()){
11 //设置为不显示提示
12 editor.putBoolean( "showMoveTip" , false );
13 }
14 else {
15 //设置为显示提示
16 editor.putBoolean( "showMoveTip" , true );
17 }
18 }
19 });
20
21 final AlertDialog dialog= new AlertDialog.Builder( this )
22 .setTitle( "提示" )
23 .setView(checkView)
24 .setPositiveButton( "确定" ,new DialogInterface.OnClickListener() {
25 @Override
26 public void onClick(DialogInterface dialog,int which) {
27 editor.commit();
28 }
29 })
30 .setNegativeButton( "取消" ,new DialogInterface.OnClickListener() {
31 @Override
32 public void onClick(DialogInterface dialog,int which) {
33
34 }
35 }).create();
36 dialog.show();

更多相关文章

  1. C语言函数以及函数的使用
  2. 【Android】Android SDK下载和更新失败的解决方法!!!
  3. 彻底解决Android 应用方法数不能超过65K的问题
  4. Android jni系统变量、函数、接口定义汇总
  5. android 获取路径目录方法以及判断目录是否存在,创建目录
  6. 【Android 开发】:Android五种布局的使用方法
  7. sscanf函数引起android 5.0卡死,C++中慎用C库函数
  8. Android中的gen文件为空或者不存在的处理方法
  9. android 对话框集合

随机推荐

  1. 简述mysql监控组复制
  2. MySQL查询语法汇总
  3. 详解mysql的备份与恢复
  4. 详解MySQL分区表
  5. 详解mysql DML语句的使用
  6. 深入了解mysql长事务
  7. mysql如何查询日期与时间
  8. MySQL8.0内存相关参数总结
  9. mysql解决时区相关问题
  10. 详细分析mysql视图的原理及使用方法