1. 程式人生 > >Android中DropEditText帶下拉功能的EditText

Android中DropEditText帶下拉功能的EditText

https://gitee.com/afei_/MyEditText

一 、特點

1.簡單。只有100多行的類,無任何依賴,也沒有自定義屬性

2.沒有用到組合控制元件的實現方法,少了很多佈局檔案等一系列東西

3.點選下拉圖示時隱藏軟鍵盤並彈出popWindow,點選item顯示對應項的文字

4.下拉和上拉的自動切換

5.易用。可見呼叫示例

二、建立一個DropEditText類

public class DropEditText extends EditText implements AdapterView.OnItemClickListener, PopupWindow.OnDismissListener {

    private Drawable mDrawable; // 顯示的圖
    private PopupWindow mPopupWindow; // 點選圖片彈出的popWindow物件
    private ListView mPopListView; // popWindow的佈局
    private int mDropDrawableResId; // 下拉圖示
    private int mRiseDrawableResID; // 上拉圖示

    public DropEditText(Context context) {
        this(context, null);
    }

    public DropEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public DropEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    private void init(Context context) {
        mPopListView = new ListView(context);
        mDropDrawableResId = R.mipmap.drop; // 設定下拉圖示
        mRiseDrawableResID = R.mipmap.rise; // 設定上拉圖示
        showDropDrawable(); // 預設顯示下拉圖示
        mPopListView.setOnItemClickListener(this);
    }

    /**
     * 我們無法直接給EditText設定點選事件,只能通過按下的位置來模擬點選事件
     * 當我們按下的位置在圖示包括圖示到控制元件右邊的間距範圍內均算有效
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (getCompoundDrawables()[2] != null) {
                int start = getWidth() - getTotalPaddingRight() + getPaddingRight(); // 起始位置
                int end = getWidth(); // 結束位置
                boolean available = (event.getX() > start) && (event.getX() < end);
                if (available) {
                    closeSoftInput();
                    showPopWindow();
                    return true;
                }
            }
        }
        return super.onTouchEvent(event);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            mPopupWindow = new PopupWindow(mPopListView, getWidth(), LinearLayout.LayoutParams.WRAP_CONTENT);
            mPopupWindow.setBackgroundDrawable(new ColorDrawable(Color.WHITE)); // 設定popWindow背景顏色
            mPopupWindow.setFocusable(true); // 讓popWindow獲取焦點
            mPopupWindow.setOnDismissListener(this);
        }
    }

    private void showPopWindow() {
        mPopupWindow.showAsDropDown(this, 0, 5);
        showRiseDrawable();
    }

    private void showDropDrawable() {
        mDrawable = getResources().getDrawable(mDropDrawableResId);
        mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
        setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], mDrawable, getCompoundDrawables()[3]);
    }

    private void showRiseDrawable() {
        mDrawable = getResources().getDrawable(mRiseDrawableResID);
        mDrawable.setBounds(0, 0, mDrawable.getIntrinsicWidth(), mDrawable.getIntrinsicHeight());
        setCompoundDrawables(getCompoundDrawables()[0], getCompoundDrawables()[1], mDrawable, getCompoundDrawables()[3]);
    }

    public void setAdapter(BaseAdapter adapter) {
        mPopListView.setAdapter(adapter);
    }

    private void closeSoftInput() {
        InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
        imm.hideSoftInputFromWindow(this.getWindowToken(), 0);
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        this.setText(mPopListView.getAdapter().getItem(position).toString()); // 可能需要你重寫item的toString方法
        mPopupWindow.dismiss();
    }

    @Override
    public void onDismiss() {
        showDropDrawable(); // 當popWindow消失時顯示下拉圖示
    }

}

三、使用

1. 佈局xml

<com.example.mytoolbarmodule.DropEditText
        android:id="@+id/drop_edit_text"
        android:layout_width="300dp"
        android:layout_height="wrap_content" />

2. 程式碼Activity

public class MainActivity extends AppCompatActivity {

    private DropEditText dropEditText;
    private ArrayAdapter<String> adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        init();
    }

    private void init() {
        dropEditText = findViewById(R.id.drop_edit_text);
        String[] strings = new String[10];
        for (int i = 0; i < 10; i++) {
            strings[i] = "美女" + i + "號";
        }
        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, strings);
        dropEditText.setAdapter(adapter);
    }

}

四、注意事項

1.上拉和下拉的圖片我已經指定死了,使用時替換成你需要的圖片就行,你也可以寫在自定義的attr中去。

2.為了使用無腦點(但是這樣就不夠靈活了),不需要再去配置各種引數,很多東西我都寫死了,沒有預留一些方法給外面設定了(懶而已_(:з」∠)_),但是程式碼和註釋都還是比較清楚的。

3.這個DropEditText的理論和上一篇的ClearEditText其實是差不多的,原理都很簡單,也可以拿來練習和研究自定義的View使用(自己改一下之類的)。