android Alertdialog 自定义

在开始本章之前,首先要感谢一下几篇文章的作者,本文正是在前人的努力下找出完全重载android alertdialog 的方法

1. AlertDialog基本用法:http://wenku.baidu.com/view/2054551910a6f524ccbf85ba.html

看了该文后,大家第一感觉重写AlertDialog的方法是 setView(View view)

不久你就可以发现一下三个问题:

 1) 一旦设定setMessage和setTitle后,您将不能达到你要的效果

      原因:查看android源码,AlertDialog使用的xml资源文件时alert_dialog.xml,文件位置在framework/base/core/res/value

  您也可以用sourceinsight去搜索。打开文件,AlertDialog是将setView传入的View放到Message所在的view之下,而并不是覆盖原有的布局

      解决方法:不能设定setMessage和setTitle,将对话框所需要的信息,卸载自己定义的view中,当然这种方法仍然不能解决alertdialog的theme和style等的设定。仅仅解决了布局问题。

2)不能有button,即不能设定setPositiveButton相应的响应函数,否则布局失效。这是相当要命的一点。

3)如上所述,不能解决风格设定,即无法贴图

否定之。。。。。。。。(郁闷中。。。。)

2. AlertDialog进阶http://wenku.baidu.com/view/2054551910a6f524ccbf85ba.html

作者通过反射技术拿到view的实例,在通过findviewbyId得到子控件的实例,从而设定Message 和title,甚至可以自己加上button以及响应函数。 解决的上述问题1、2。 但是仍然有两个问题,

1)无法去除边缘的白框,没有完全实现自定义

2)这样的AlertDialog如果加上button的响应将使其变为阻塞式的了,会卡UI,因为他们都在UI主线程做事情

继续否定之。。。。。。(狂躁。。。。)

3. AlertDialog高级http://crazier9527.javaeye.com/blog/729034  和 http://dev.10086.cn/blog/index.php?uid-634946-action-viewspace-itemid-4494

作者通过setContentView实现了完全的 布局和资源的自定应,灵活度相当高。但还是存在问题

1)扩展性不佳。代码集中在一个类中,不利于维护。读者自行思考原因,这里不展开。

2)这样的AlertDialog如果加上button的响应将使其变为阻塞式的了,会卡UI,因为他们都在UI主线程做事情

再次否定之。。。。。。。(我排山倒海。。。。问候android十八辈祖上)

4. AlertDialog精通http://www.blogjava.net/nokiaguy/archive/2010/07/27/327270.html

一看该文,就知道作者非泛泛之辈,该文冲源码入手,的确深入。虽然没有解决我们的问题,但是可以帮助我们开拓思路。

我要的就是这个,重写AlertDialog的button响应行为,并且是多线程,非阻塞式的。 好文。。。。

 

 

看了以上几篇,我来整理一下思路,得出最后的解决方案:

一、 要实现布局资源的完全自定义,android提供的API完全不够用(想起当初搞WPF全无此顾虑)

二、 要实现button行为的自定义,android没有API

三、 要实现非阻塞式的AlertDialog, android更是没有提供框架。

四、 要利用重载和反射技术,拿到AlertDialog的私有变量的访问权限,android没有参考资料

 

以上是难点,也是思路。

方法如下:

第一、采用反射技术,动态拿到View的资源

第二、采用自定义的布局,实现资源,样式的灵活设定和动态加载。getWindow.setContentView实现

第三、通过重载AlertDialog实现自己的主题加载,不懂的可以看看AlertDialog的私有构造函数:两个参数的那个,源码里面有。

第四、重载常用的函数,或者说必须的几个函数,实现,控件的参数化设定。

第五、仿造android 的实现方式,实现布局文件的多分辨率支持

第六、仿造android的实现方式,实现button响应的多线程实现。

 

核心代码:

public class MyAlertDialog extends AlertDialog {

 private final static String TAG = "MyAlertDialog";
 
 protected MyAlertDialog(Context context) {
  super(context); 
 }

 /** 
 * @param context 
 * @param theme 
 */ 
 protected MyAlertDialog(Context context, int theme) {  
  super(context, theme);  
 } 

 

 @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {      
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onKeyUp(int keyCode, KeyEvent event) {      
     return super.onKeyDown(keyCode, event);
    }

 

public static class Builder extends AlertDialog.Builder {  

 

@Override
  public AlertDialog show(){
   Log.d(TAG, "show");
   this.create();
   dialog.show();   
   installContent();   
   return dialog;
  }

  private void installContent() {   
   Log.d(TAG, "installContent");   
   mDialogInterface = (DialogInterface)dialog;
   if(title != null)
    ((TextView)view.findViewById(R.id.title)).setText(this.title);
   if(title != null)
    ((TextView)view.findViewById(R.id.message)).setText(this.message);
   if(iconId != -1)
    ((ImageView)view.findViewById(R.id.icon)).setImageResource(iconId);   
   if(view != null)    
    dialog.getWindow().setContentView(view);
   
   mButtonPositive = (Button)view.findViewById(R.id.button1);
   mButtonPositive.setOnClickListener(mButtonHandler);
   mButtonPositive.setText(mButtonPositiveText);

   mButtonNegative = (Button)view.findViewById(R.id.button2);
   mButtonNegative.setOnClickListener(mButtonHandler);
   mButtonNegative.setText(mButtonNegativeText);
  }
  
  public void setButton(int whichButton, CharSequence text,
             DialogInterface.OnClickListener listener, Message msg) {

         if (msg == null && listener != null) {
             msg = mHandler.obtainMessage(whichButton, listener);
         }
        
         switch (whichButton) {

             case DialogInterface.BUTTON_POSITIVE:
                 mButtonPositiveText = text;
                 mButtonPositiveMessage = msg;
                 break;
                
             case DialogInterface.BUTTON_NEGATIVE:
                 mButtonNegativeText = text;
                 mButtonNegativeMessage = msg;
                 break;
                
//             case DialogInterface.BUTTON_NEUTRAL:
//                 mButtonNeutralText = text;
//                 mButtonNeutralMessage = msg;
//                 break;
                
             default:
                 throw new IllegalArgumentException("Button does not exist");               
         }
     }
  
  View.OnClickListener mButtonHandler = new View.OnClickListener() {
   public void onClick(View v) {
    Message m = null;
    if (v == mButtonPositive && mButtonPositiveMessage != null) {
     m = Message.obtain(mButtonPositiveMessage);
    } else if (v == mButtonNegative
      && mButtonNegativeMessage != null) {
     m = Message.obtain(mButtonNegativeMessage);
    }
//    else if (v == mButtonNeutral && mButtonNeutralMessage != null) {
//     m = Message.obtain(mButtonNeutralMessage);
//    }
    if (m != null) {
     m.sendToTarget();
    }

    // Post a message so we dismiss after the above handlers are
    // executed
    mHandler.obtainMessage(ButtonHandler.MSG_DISMISS_DIALOG,
      mDialogInterface).sendToTarget();
   }
  };
  
 }
 
 public static final class ButtonHandler extends Handler {
  // Button clicks have Message.what as the BUTTON{1,2,3} constant
  private static final int MSG_DISMISS_DIALOG = 1;

  private WeakReference<DialogInterface> mDialog;

  public ButtonHandler(DialogInterface dialog) {
   mDialog = new WeakReference<DialogInterface>(dialog);
  }

  @Override
  public void handleMessage(Message msg) {
   switch (msg.what) {

   case DialogInterface.BUTTON_POSITIVE:
   case DialogInterface.BUTTON_NEGATIVE:
   case DialogInterface.BUTTON_NEUTRAL:
    ((DialogInterface.OnClickListener) msg.obj).onClick(
      mDialog.get(), msg.what);
    break;

   case MSG_DISMISS_DIALOG:
    ((DialogInterface) msg.obj).dismiss();
   }
  }
 }

 

 调用:

 LayoutInflater factory = LayoutInflater.from(context);
 View view = factory.inflate(R.layout.alertdialoglayout, null);
       
  new MyAlertDialog.Builder(context)
   .setTitle(getString(R.string.warning))  
   .setMessage(message)
   .setView(view)
   .setIcon(R.drawable.dialog_icon)
   .setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialoginterface, int i) {
     。。。。。。。。。。。。

      }
     })
   .setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() {
      public void onClick(DialogInterface dialog, int which) {
      。。。。。。。。。。。。

      }
     })
   .show();


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值