Android 自定义带回调的Dialog 及EditText相关

 
import android.app.Activity;
import android.content.Context;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;



/**
 * 
 *         ModifyCountDialog ModifyCountDialog = new ModifyCountDialog.Builder(
 *                Activity.this,2030L).build();
 *         ModifyCountDialog.setModifyCountListener(new ModifyCountListener(){
 *            @Override
 *            public void onDelivered(long Count) {
 *                Log.d(TAG, "--------送你"+Count+"朵花");
 *            }
 *            
 *        });
 *        ModifyCountDialog.show();
 * 
 *
 */
public class ModifyCountDialog extends popDialog implements OnClickListener
    ,OnTouchListener{

    private static final String TAG = "ModifyCountDialog";
    private static final int SCORE_PER_ = 10;    // currentScore = totalScore -  Count *  SCORE_PER_

    private Activity mActivity;
    private String title; // title string, have default
                            // R.string.dialog_deliver__title
    private long totalScore; // user total score

    private long mMaxCount = 0;
    private long mCurrentCount = 0;
    private long mCurrentScore;

    private Button mBtnCountSub;
    private Button mBtnCountAdd;

    private TextView mTvScore;
    private EditText mEditCount;
    
//    private boolean isButtonCountChange=false;

    public static class Builder {
        private final Activity mActivity;

        private String title;
        private long score; // user current score

        /**
         * @param context
         * @param score
         */
        public Builder(Activity context, long score) {
            this.mActivity = context;
            this.score = score;
        }

        public Builder title(String title) {
            this.title = title;
            return this;
        }

        public ModifyCountDialog build() {
            return new ModifyCountDialog(this);
        }
    }

    private ModifyCountDialog(Builder builder) {
        super(builder.mActivity);
        this.mActivity = builder.mActivity;
        this.totalScore = builder.score;

        if (this.totalScore > 0) {
            this.mMaxCount = (long) (this.totalScore / SCORE_PER_);
            this.mCurrentScore = this.totalScore;
        }

        if (!TextUtils.isEmpty(builder.title)) {
            this.title = builder.title;
        }

        initDialog();
    }

    private void initDialog() {
        View view = LayoutInflater.from(mActivity).inflate(
                R.layout.dialog_deliver_, null, false);

        
        view.findViewById(R.id.btn_cancle).setOnClickListener(this);
        view.findViewById(R.id.btn_deliver).setOnClickListener(this);

        mBtnCountSub = (Button) view
                .findViewById(R.id.dialog_deliver__count_sub);
        mBtnCountSub.setOnClickListener(this);

        mBtnCountAdd = (Button) view
                .findViewById(R.id.dialog_deliver__count_add);
        mBtnCountAdd.setOnClickListener(this);

        mTvScore = (TextView) view
                .findViewById(R.id.dialog_deliver__score_tv);
        mTvScore.setText(String.valueOf(totalScore));

        mEditCount = (EditText) view
                .findViewById(R.id.dialog_deliver__count);

        mEditCount.setOnTouchListener(this);

  //set keyboard property, the dialog will push up     getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

    this.build(view, true);
  }

  @Override
  public boolean onTouch(View v, MotionEvent event) {
    if(v.getId()==R.id.dialog_deliver_flower_count) {
      mEditFlowerCount.selectAll();    //select all character in EditText
      showKeyboard(mEditFlowerCount);    //without calling this. keyboard hide
      return true;
    }
    return false;
  }




  private boolean isCountLegal(long count){
        return (count >=0)&&(count <= mMaxCount);
    }

    /**
    * EditText text change watcher
    * 
    * when user input is illegal, setText to 0 or MaxCount
    * 
    * warn: call setText() in wrong place, will cause infinite loop and StackOverFlow
    * 
    */
    TextWatcher mTextWatcher = new TextWatcher() {
            private long mCount;
             @Override
            public void onTextChanged(CharSequence s, int start, int before,int count) {

            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,int after) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                    String str = s.toString();
                //    Log.d(TAG, "---myc---afterTextChanged str------" + str);
                if(!TextUtils.isEmpty(str) && TextUtils.isDigitsOnly(str)){
                       mCount = Long.parseLong(str);
                }else{
                        mCount = 0;
                }

                //if user input is illegal, set to legal count
                if(!isCountLegal(mCount)){
                        if(mCount < 0){
                            mCount = 0;
                         }else if(mCount > mMaxFlowerCount){
                            mCount = mMaxFlowerCount;
                        }
                        mEditFlowerCount.setText(String.valueOf(mCount));    //illegal, set to 0 or maxFlowerCount
                             mEditFlowerCount.selectAll();    
                        }
                        setCurrentFlowerCount(mCount);
                        }
                   };



     /**
     * getter
     * 
     * @return
     */
    public long getCurrentCount() {
        return this.mCurrentCount;
    }

    /**
     * setter
     * 
     * @return
     */
    public void setCurrentCount(long Count) {
        if(isCountLegal(Count) && Count!=mCurrentCount){
            Log.d(TAG, "---setCurrentCount------" + Count);
            this.mCurrentCount = Count;
            refreshUI(Count);
        }
    }
    
    ModifyCountListener mModifyCountListener;

    public interface ModifyCountListener { //在Activity里弹框获取用户输入,可以通过回调的方法来获取用户输入值
        void onModified(long Count);
    }

    public void setModifyCountListener(ModifyCountListener listener) {
        mModifyCountListener = listener;
    }

    /**
     * user press "modify" button
     * 
     */
    private void doModifyCount() {
        if (mModifyCountListener != null) {
            mModifyCountListener.onModified(mCurrentCount);    //将值回调给Activity
        }
    }

    /**
     * refresh EditText, current core TextView and so on
     * 
     * @param Count
     */
    private void refreshUI(long Count) {
        mCurrentScore = totalScore - Count * SCORE_PER_;

        if (mCurrentScore >= 0) {
            mTvScore.setText(String.valueOf(mCurrentScore));
        }

        if (Count <= 0) {
            setBtnClickable(false, true);
        } else if (Count >= mMaxCount) {
            setBtnClickable(true, false);
        } else {
            setBtnClickable(true, true);
        }
    }

    /**
     * hide keyboard
     * 
     * @param v
     */
    private void hideKeyboard(View v) {
//        Log.d(TAG, "---hideKeyboard()------");
        if(v == null){
            return;
        }
        InputMethodManager imm = (InputMethodManager) v.getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
    }
    
    
    /**
     * show keyboard
     * 
     * @param v
     */
    private void showKeyboard(View v) {
//        Log.d(TAG, "---showKeyboard()------");
        if(v == null){
            return;
        }
        InputMethodManager imm = (InputMethodManager) v.getContext()
                .getSystemService(Context.INPUT_METHOD_SERVICE);

        imm.showSoftInput(v, 0);
    }
    
    /**
     * set Button Clickable
     * 
     * @param canSub
     *            if true, can sub  count
     * @param canAdd
     *            if true, can add  count
     */
    private void setBtnClickable(boolean canSub, boolean canAdd) {
        mBtnCountSub.setClickable(canSub);
        mBtnCountAdd.setClickable(canAdd);
    }


@Override
public void onClick(View view) {
    if(!view.equals(R.id.dialog_deliver__count))      
    {
        hideKeyboard(mEditCount);
    }
   switch (view.getId()) {
        case R.id.btn_cancle:
            this.dismiss();
            break;
        case R.id.btn_deliver:
            doModifyCount();
            this.dismiss();
            break;
        case R.id.count_sub:
            if (mCurrentCount > 0) {
                setCurrentCount(mCurrentCount - 1);
                mEditCount.setText(String.valueOf(mCurrentCount));
            }
            break;
        case R.id.count_add:
            if (getCurrentCount() < mMaxCount) {
                setCurrentCount(getCurrentCount() + 1);
                mEditCount.setText(String.valueOf(mCurrentCount));
            }
            break;
        default:
            break;
        }
    }
}                    

包括

(1)隐藏  和 弹出键盘

 1     /**
 2      * hide keyboard
 3      * 
 4      * @param v
 5      */
 6     private void hideKeyboard(View v) {
 7 //        Log.d(TAG, "---hideKeyboard()------");
 8         if(v == null){
 9             return;
10         }
11         InputMethodManager imm = (InputMethodManager) v.getContext()
12                 .getSystemService(Context.INPUT_METHOD_SERVICE);
13 
14         imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
15     }
16     
17     
18     /**
19      * show keyboard
20      * 
21      * @param v
22      */
23     private void showKeyboard(View v) {
24 //        Log.d(TAG, "---showKeyboard()------");
25         if(v == null){
26             return;
27         }
28         InputMethodManager imm = (InputMethodManager) v.getContext()
29                 .getSystemService(Context.INPUT_METHOD_SERVICE);
30 
31         imm.showSoftInput(v, 0);
32     }

(2)防止键盘挡住输入框

1         //set keyboard property, the dialog will push up  防止EditText被挡住, 往上推Dialog
2         getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE |  
3                 WindowManager.LayoutParams.SOFT_INPUT_STATE_HIDDEN);

(3)点击EditText以外的区域,隐藏键盘,注意父view要设置onClickListener

parentView.setOnClickListener(this); 


@Override public void onClick(View view) { if(!view.equals(R.id.dialog_deliver__count))       { hideKeyboard(mEditCount); } }

本来想在 EditText OnFocusListener()里监听, 失去焦点后,隐藏键盘. 不起作用

因为对话框弹出的时候, EditText的isFocused是true的。除非点击按钮等,才会失去焦点。但是现在是想点击任何区域都失去焦点。

所以需要通过监听整个父控件

(4) 监听EditText输入     

官方文档也指出:千万注意别在三个方法里随意重复调用setText,会死循环

mEditCount.addTextChangedListener(mTextWatcher);        //先给EditText设置监听
 1    /**
 2      * EditText text change watcher                   
 3      * 
 4      * when user input is illegal, setText to 0 or MaxCount    
 5      * 
 6      * warn: call setText() in wrong place, will cause infinite loop and StackOverFlow  
 7      * 
 8      */
 9     TextWatcher mTextWatcher = new TextWatcher() {
10         private long mCount;
11         @Override
12         public void onTextChanged(CharSequence s, int start, int before,
13                 int count) {
14             
15         }
16 
17         @Override
18         public void beforeTextChanged(CharSequence s, int start, int count,
19                 int after) {
20             
21         }
22 
23         @Override
24         public void afterTextChanged(Editable s) {
25             String str = s.toString();
26 //            Log.d(TAG, "---afterTextChanged str------" + str);
27             
28             if(!TextUtils.isEmpty(str) && TextUtils.isDigitsOnly(str)){
29                 mCount = Long.parseLong(str);
30             }else{
31                 mCount = 0;
32             }
33             
34             //if user input is illegal, set to legal count
35             if(!isCountLegal(mCount)){
36                 if(mCount < 0){
37                     mCount = 0;
38                 }else if(mCount > mMaxCount){
39                     mCount = mMaxCount;
40                 }
41                 mEditCount.setText(String.valueOf(mCount));    //illegal, set to 0 or maxCount
42                 mEditCount.selectAll();   //如果设置成最大值以后不全选,再点一个数字.s比最大值还大,EditText没反                                          //应,看起来就像失去焦点了. 但事实上调用 isFocused判断时, 还是有焦点的
43             }
44             setCurrentCount(mCount);
45         }
46     };

(5)全选一个输入框的内容
1     @Override
2      public boolean onTouch(View v, MotionEvent event) {
3         if(v.getId()==R.id.dialog_deliver__count) {
4             mEditCount.selectAll();              //全选EditText的内容
5             showKeyboard(mEditCount);            //全选完如果不调用这个,不弹出键盘
6             return true;
7         }
8         return false;
9     }
 
原文地址:https://www.cnblogs.com/maxiaodoubao/p/4729883.html