自定义View之 自动完成文本AutoCompleteTextv

2020-05-22  本文已影响0人  不会弹钢琴de大叔

实现了edittext自动带出提示类似AutoCompleteTextview功能,及点击edittext实现弹出dialog选择数据类似Spinner得功能

这个自定义View就是AutoCompleteTextview+Spinner的组合实现

```

使用方法:

List list =new ArrayList<>();

list.add("xxx");

list.add("xxx1");

list.add("xxx2");

list.add("xxssx");

list.add("xqqqxx");

//设置初始数据

autoName.setPromptata(list);

//设置文字内容 切记不要使用setText

autoName.setNewText("");

//设置只读-不可点击操作

autoName.setReadOnly(true);

//设置是否可以输入上述list内容之外的数据

autoName.setCanInputOther(true);

```

如果对你有帮助点个赞吧

icon_arrow_down

```


import android.annotation.SuppressLint;

import android.app.AlertDialog;

import android.content.Context;

import android.graphics.drawable.ColorDrawable;

import android.graphics.drawable.Drawable;

import android.os.Handler;

import android.text.Editable;

import android.text.TextUtils;

import android.text.TextWatcher;

import android.util.AttributeSet;

import android.view.LayoutInflater;

import android.view.MotionEvent;

import android.view.View;

import android.view.ViewGroup;

import android.view.WindowManager;

import android.widget.ArrayAdapter;

import android.widget.ListView;

import android.widget.PopupWindow;

import androidx.appcompat.widget.AppCompatEditText;

import androidx.core.content.ContextCompat;

import com.hzy.modulebase.R;

import java.util.ArrayList;

import java.util.List;

/**

* 自定义可自动完成文本并提示的,可以进行直接选择的edittext

*

* @author zhangjian

* date:2020/5/20.

*/

public class MyAutoCompleteEdittext extends AppCompatEditText {

private static final int TEMP_CLICK =50;

private Context mContext;

/**

    * 赋值的操作

    */

    private boolean isSel;

Handler myCarhandler =new Handler();

private PopupWindow mPopWindow;

/**

    * 筛选的全部数据

    */

    private List<String> mDatas;

/**

    * 筛选出的数据

    */

    private List<String> tempData;

private ArrayAdapter mAdapter;

/**

    * edittext得宽度

    */

    private int width;

/**

    * 是否可以输入其他数据

    */

    private boolean canInputOther;

public MyAutoCompleteEdittext(Context context) {

super(context);

init(context);

}

public MyAutoCompleteEdittext(Context context, AttributeSet attrs) {

super(context, attrs);

init(context);

}

public MyAutoCompleteEdittext(Context context, AttributeSet attrs,int defStyleAttr) {

super(context, attrs, defStyleAttr);

init(context);

}

@Override

    protected void onMeasure(int widthMeasureSpec,int heightMeasureSpec) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec);

width = MeasureSpec.getSize(widthMeasureSpec);

if (mPopWindow !=null) {

mPopWindow.setWidth(width);

}

}

@Override

    @SuppressLint("ClickableViewAccessibility")

public boolean onTouchEvent(MotionEvent event) {

if (event.getAction() == MotionEvent.ACTION_DOWN) {

Drawable rightDrawable = getCompoundDrawables()[2];

if (rightDrawable !=null && event.getRawX() >= (getRight() -rightDrawable.getBounds().width() -TEMP_CLICK)) {

showNameSelect();

return false;

}

}

return super.onTouchEvent(event);

}

private void init(Context context) {

mContext = context;

canInputOther =false;

addTextChangedListener(mTextWatcher);

tempData =new ArrayList<>();

Drawable drawable = ContextCompat.getDrawable(mContext, R.mipmap.icon_arrows_down);

drawable.setBounds(0,0,drawable.getMinimumWidth(),drawable.getMinimumHeight());

setCompoundDrawables(null,null,drawable,null);

setCompoundDrawablePadding(10);

initPopuWindow();

}

/**

    * 初始化PopupWindow  关键代码

    */

    private void initPopuWindow() {

LayoutInflater inflater = (LayoutInflater)mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

View view =inflater.inflate(R.layout.popup_option,null);

mPopWindow =new PopupWindow(mContext);

mPopWindow.setContentView(view);

mPopWindow.setWidth(width);

mPopWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);

mPopWindow.setBackgroundDrawable(new ColorDrawable(0xb0000000));

mPopWindow.setFocusable(false);

mPopWindow.setOutsideTouchable(true);

mPopWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED);

mPopWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);

mPopWindow.setOnDismissListener(() -> {

if (!checkDataQualified()) {

setNewText("");

}

});

ListView listView =view.findViewById(R.id.lv_data);

mAdapter =new ArrayAdapter<>(mContext, android.R.layout.simple_list_item_1,tempData);

listView.setAdapter(mAdapter);

listView.setOnItemClickListener((parent, view1, position, id) -> {

mPopWindow.dismiss();

setNewText(mAdapter.getItem(position));

});

}

private TextWatcher mTextWatcher =new TextWatcher() {

@Override

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

}

@Override

        public void onTextChanged(CharSequence s,int start,int before,int count) {

}

@Override

        public void afterTextChanged(Editable s) {

if (isSel) {

isSel =false;

return;

}

if (mDatas ==null) {

return;

}

myCarhandler.post(carChangeRunnable);

}

};

private Runnable carChangeRunnable = () -> {

String data = getText().toString().trim();

getNewData(data);

};

/**

    * 获取筛选数据

    *

    * @param msg

    */

    private void getNewData(String msg) {

tempData.clear();

if (TextUtils.isEmpty(msg)) {

if (mPopWindow !=null) {

mPopWindow.dismiss();

}

return;

}else {

for (String data :mDatas) {

if (data.contains(msg)) {

tempData.add(data);

}

}

}

if (tempData.size() ==0) {

if (canInputOther) {

if (mPopWindow !=null) {

mPopWindow.dismiss();

}

return;

}else {

//不能输入其他默认有一项显示位置

                tempData.add("");

}

}

if (mPopWindow !=null && !mPopWindow.isShowing()) {

mPopWindow.showAsDropDown(this);

}

mAdapter.notifyDataSetChanged();

}

/**

    * 检测数据是否是list中数据

    *

    * @return true (未给定集合)存在 false不存在

    */

    private boolean checkDataQualified() {

if (!canInputOther &&mDatas !=null) {

Stringmsg = getText().toString().trim();

return mDatas.contains(msg);

}

return true;

}

/**

    * 显示选择

    */

    private void showNameSelect() {

if (mDatas ==null) {

return;

}

ArrayAdapter userAdapter = new ArrayAdapter<>(mContext, android.R.layout.simple_expandable_list_item_1,mDatas);

AlertDialog.Builder builder =new AlertDialog.Builder(mContext);

builder.setAdapter(userAdapter, (dialog, which) -> {

dialog.dismiss();

setNewText(userAdapter.getItem(which));

});

builder.create().show();

}

/**

    * 设置自动提示数据

    *

    * @param datas datas.

*/

    public void setPromptata(List datas) {

mDatas = datas;

}

/**

    * 设置text

*

    * @param text 内容

    */

    public void setNewText(String text) {

isSel =true;

setText(text);

if (!TextUtils.isEmpty(text)) {

setSelection(text.length());

}

}

/**

    * 设置只读

    */

    public void setReadOnly(boolean canEdit) {

if (!canEdit) {

setEnabled(false);

setCompoundDrawables(null,null,null,null);

}

}

/**

    * 设置是否可以输入列表之外数据

    * 默认不可以

    *

    * @param canInput 可以输入

    */

    public void setCanInputOther(boolean canInput) {

canInputOther = canInput;

}

/**

    * 销毁

    */

    public void onDestroy() {

myCarhandler.removeCallbacksAndMessages(null);

if (mPopWindow !=null) {

mPopWindow.dismiss();

}

removeTextChangedListener(mTextWatcher);

}

}

```


popup_option.xml

```

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:background="#E7E7E7"

android:orientation="vertical">

<ListView android:id="@+id/lv_data"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:listSelector="@color/float_transparent"/>

</LinearLayout>

```

上一篇 下一篇

猜你喜欢

热点阅读