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     }
 
时间: 2024-10-19 17:14:50

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

Android 自定义带刻度的seekbar

自定义带刻度的seekbar 1.布局 <span style="font-family:SimHei;font-size:18px;"><com.imibaby.client.views.CustomSeekbar android:id="@+id/myCustomSeekBar" android:layout_width="wrap_content" android:layout_height="wrap_cont

【Android】Android自定义带board的圆角控件

介绍 圆角控件常用于头像,按钮,图标等,用途十分广泛,而且常常配合board使用. 在IOS中,UIVIew的CALayer层已经提供了圆角和board的方法,所以圆角控件的制作非常简单,只需要类似以下简单代码即可实现: view.layer.cornerRadius = 20; view.layer.borderColor = [UIColor yellowColor].CGColor; view.layer.borderWidth = 10; view.clipsToBounds = YES

android 自定义带按钮的Notification及点击事件和伸缩通知栏

1.自定义一个带按钮的Notification布局:layout_notification: 2.创建Notification: RemoteViews views = new RemoteViews(getPackageName(),R.layout.layout_nitification); //自定义的布局视图 //按钮点击事件: PendingIntent homeIntent = PengdingIntent.getBroadcast(this,1,new Intent("action

[Android]实现带显示密码按钮的EditText(无内存泄露)

原理: 通过自定义View绘制显示密码按钮,当点击密码按钮的时候调用setInputType来更改属性. 解决方案: 就直接上代码了 package com.finals.view; import com.example.test.R; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Bitmap; import android.graphics.Bitm

Android自定义带边框的圆形view

由于项目需要,需要做一个圆形的带边框并且里边还有文字的view →_→ ↓↓↓↓这样↓↓↓↓ 如果在布局文件中做的话是非常麻烦的,而且复用性也不高.所以想到用自定义一个view的来实现该功能,这样封装性和复用性就会相对提高,可方便在以后类似的项目中使用.可能也有同学有过这样的需求,所以在这分享出来供大家参考,不足之处还请多多指点. 看代码: 1package com.stock.manage.friend.view;import android.content.Context; 2 import

android 自定义带动画的统计饼图

闲来无事,发现市面上好多app都有饼图统计的功能,得空自己实现以下,菜鸟一只,求指教,轻喷!   基本要求: 在XML布局中可配置控件的属性. 遵守基本的安卓规范 View基本绘制原理: 首先计算View的大小,测量View的大小主要有三个: public final void measure(int widthMeasureSpec, int heightMeasureSpec) protected void onMeasure(int widthMeasureSpec, int height

Android自定义TextView的Shape,修改EditText光标颜色

先看一下效果图: 代码实现: <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 实心 --> <solid android:color="@android:color/white" /> <!-- 边框

Android -- 自定义带进度条的按钮

1. 实现了一个带进度条的按钮,完成后显示提示信息,并设置按钮为不可再次被点击 2. 所需要的图片               3.  代码 MainActivity package com.example.buttondemo; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.view.View;

Android实现带箭头的自定义Progressbar

一.闲话: Android原生的进度条可以根据不同的主题有不同的视觉效果,但任何一种主题下的进度条和应用程序的视觉配合起来都显得格格不入,所以多数时候我们需要自定义Progressbar,最简单的是在布局文件中通过"android:progressDrawable"为Progressbar换背景和进度图片,换图后的效果类似于这样: 但你会发现,进度图片像是被截断了一样,看上去同样不美观,所以现在很多应用都会在进度条上玩花样,做出各种各样的效果,本例介绍的是在进度条的头部加上光晕箭头的效