【Android】带可输入功能的下拉框EditSpinner,附带Filter功能

功能实现,分为前期准备+使用。

1、前期准备

在model下建立一个spinner包文件夹,在这个文件夹中添加4个java文件:
1、BaseEditSpinnerAdapter.java

import android.widget.BaseAdapter;

public abstract class BaseEditSpinnerAdapter extends BaseAdapter {
    
    
    /**
     * editText输入监听
     * @return
     */
    public abstract EditSpinnerFilter getEditSpinnerFilter();

    /**
     * 获取需要填入editText的字符串
     * @param position
     * @return
     */
    public abstract String getItemString(int position);

}

2、EditSpinnerFilter.java

public interface EditSpinnerFilter {
    
    
    /**
     * editText输入监听
     * @param keyword
     * @return
     */
    boolean onFilter(String keyword);
}

3、SimpleAdapter.java

import android.content.Context;
import android.text.Html;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class SimpleAdapter extends BaseEditSpinnerAdapter implements EditSpinnerFilter {
    
    
    private Context mContext;
    private List<String> mSpinnerData;
    private List<String> mCacheData;
    private int[] indexs;

    public SimpleAdapter(Context context, List<String> spinnerData) {
    
    
        this.mContext = context;
        this.mSpinnerData = spinnerData;
        mCacheData = new ArrayList<>(spinnerData);
        indexs = new int[mSpinnerData.size()];
    }

    @Override
    public EditSpinnerFilter getEditSpinnerFilter() {
    
    
        return this;
    }

    @Override
    public String getItemString(int position) {
    
    
        return mSpinnerData.get(indexs[position]);
    }

    @Override
    public int getCount() {
    
    
        return mCacheData == null ? 0 : mCacheData.size();
    }

    @Override
    public String getItem(int position) {
    
    
        return mCacheData == null ? "" : mCacheData.get(position) == null ? "" : mCacheData.get(position);
    }

    @Override
    public long getItemId(int position) {
    
    
        return position;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
    
    
        TextView textView = null;
        if (convertView == null) {
    
    
            textView = (TextView) LayoutInflater.from(mContext).inflate(android.R.layout.simple_spinner_item, null);
        } else {
    
    
            textView = (TextView) convertView;
        }
        textView.setText(Html.fromHtml(getItem(position)));
        return textView;
    }

    @Override
    public boolean onFilter(String keyword) {
    
    
        mCacheData.clear();
        if (TextUtils.isEmpty(keyword)) {
    
    
            mCacheData.addAll(mSpinnerData);
            for (int i = 0; i < indexs.length; i++) {
    
    
                indexs[i] = i;
            }
        } else {
    
    
            StringBuilder builder = new StringBuilder();
            builder.append("[^\\s]*").append(keyword).append("[^\\s]*");
            for (int i = 0; i < mSpinnerData.size(); i++) {
    
    
                if (mSpinnerData.get(i).replaceAll("\\s+", "|").matches(builder.toString())) {
    
    
                    indexs[mCacheData.size()] = i;
                    mCacheData.add(mSpinnerData.get(i).replaceFirst(keyword, "<font color=\"#aa0000\">" + keyword + "</font>"));
                }
            }
        }
        notifyDataSetChanged();
        return mCacheData.size() <= 0;
    }
}

4、EditSpinner.java

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.support.annotation.ColorInt;
import android.support.annotation.DrawableRes;
import android.text.Editable;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.ListPopupWindow;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;

import java.util.List;

public class EditSpinner extends RelativeLayout implements View.OnClickListener, AdapterView.OnItemClickListener, TextWatcher {
    
    
    private EditText editText;
    private ImageView mRightIv;
    private View mRightImageTopView;
    private Context mContext;
    private ListPopupWindow popupWindow;
    BaseEditSpinnerAdapter adapter;
    private TypedArray tArray;
    private boolean isPopupWindowShowing;
    private Animation mAnimation;
    private Animation mResetAnimation;

    public EditSpinner(Context context, AttributeSet attrs) {
    
    
        super(context, attrs);
        this.mContext = context;
        initView(attrs);
        initAnimation();
    }

    public void setItemData(List<String> data) {
    
    
        adapter = new SimpleAdapter(mContext, data);
        setAdapter(adapter);
    }

    public void setText(String text) {
    
    
        editText.setText(text);
    }

    public void setTextColor(@ColorInt int color) {
    
    
        editText.setTextColor(color);
    }

    public String getText() {
    
    
        return editText.getText().toString();
    }

    public void setHint(String hint) {
    
    
        editText.setHint(hint);
    }

    public void setRightImageDrawable(Drawable drawable) {
    
    
        mRightIv.setImageDrawable(drawable);
    }

    public void setRightImageResource(@DrawableRes int res) {
    
    
        mRightIv.setImageResource(res);
    }

    public void setAdapter(BaseEditSpinnerAdapter adapter) {
    
    
        this.adapter = adapter;
        setBaseAdapter(this.adapter);
    }

    private void initAnimation() {
    
    
        mAnimation = new RotateAnimation(0, 180, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        mAnimation.setDuration(300);
        mAnimation.setFillAfter(true);
        mResetAnimation = new RotateAnimation(180, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
        mResetAnimation.setDuration(300);
        mResetAnimation.setFillAfter(true);
    }

    private void initView(AttributeSet attrs) {
    
    
        LayoutInflater.from(mContext).inflate(R.layout.edit_spinner, this);
        editText = (EditText) findViewById(R.id.edit_sipnner_edit);
        mRightIv = (ImageView) findViewById(R.id.edit_spinner_expand);
        mRightIv.setOnClickListener(this);

        mRightImageTopView = findViewById(R.id.edit_spinner_expand_above);
        mRightImageTopView.setOnClickListener(this);
        mRightImageTopView.setClickable(false);
        //mRightIv.setRotation(90);
        editText.addTextChangedListener(this);
        tArray = mContext.obtainStyledAttributes(attrs,
                R.styleable.EditSpinner);
        editText.setHint(tArray.getString(R.styleable.EditSpinner_hint));
        editText.setTextSize(18);

        int imageId = tArray.getResourceId(R.styleable.EditSpinner_rightImage, 0);
        if (imageId != 0) {
    
    
            mRightIv.setImageResource(imageId);
        }
        int bg = tArray.getResourceId(R.styleable.EditSpinner_Background, 0);
        if (bg != 0) {
    
    
            editText.setBackgroundResource(bg);
        }
        tArray.recycle();
    }

    private final void setBaseAdapter(BaseAdapter adapter) {
    
    
        if (popupWindow == null) {
    
    
            initPopupWindow();
        }
        popupWindow.setAdapter(adapter);
    }

    private void initPopupWindow() {
    
    
        popupWindow = new ListPopupWindow(mContext) {
    
    
            @Override
            public boolean isShowing() {
    
    
                return isPopupWindowShowing;
            }

            @Override
            public void show() {
    
    
                super.show();
                isPopupWindowShowing = true;
                mRightImageTopView.setClickable(true);
                mRightIv.startAnimation(mAnimation);
            }
        };
        popupWindow.setOnItemClickListener(this);
        popupWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        popupWindow.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
        popupWindow.setWidth(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
        popupWindow.setAnchorView(editText);
        popupWindow.setOnDismissListener(new PopupWindow.OnDismissListener() {
    
    
            @Override
            public void onDismiss() {
    
    
                isPopupWindowShowing = false;
                mRightIv.startAnimation(mResetAnimation);
            }
        });
    }


    @Override
    public final void onClick(View v) {
    
    
        if (adapter == null || popupWindow == null) {
    
    
            return;
        }
        if (v.getId() == R.id.edit_spinner_expand_above) {
    
    
            v.setClickable(false);
            return;
        }
        if (popupWindow.isShowing()) {
    
    
            popupWindow.dismiss();
        } else {
    
    
            showFilterData("");
        }
    }

    @Override
    public final void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    
    
        editText.setText(((BaseEditSpinnerAdapter) parent.getAdapter()).getItemString(position));
        mRightImageTopView.setClickable(false);
        popupWindow.dismiss();
    }

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

    }

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

    }

    @Override
    public final void afterTextChanged(Editable s) {
    
    
        String key = s.toString();
        editText.setSelection(key.length());
        if (!TextUtils.isEmpty(key)) {
    
    
            showFilterData(key);
        } else {
    
    
            popupWindow.dismiss();
        }
    }

    private void showFilterData(String key) {
    
    
        if (popupWindow == null || adapter == null || adapter.getEditSpinnerFilter() == null) {
    
    
            if (popupWindow != null) {
    
    
                popupWindow.dismiss();
            }
            return;
        }
        if (adapter.getEditSpinnerFilter().onFilter(key)) {
    
    
            popupWindow.dismiss();
        } else {
    
    
            popupWindow.show();
        }
    }

    // 关闭弹窗
    public void dismissPopWindow(){
    
    
        if (popupWindow != null) {
    
    
            popupWindow.dismiss();
        }
    }
}

2、使用

前期定义:
private InputStream mIs;
private EditSpinner editspinner_w;

调用函数:
loadData();

被调用的函数loadData:
private void loadData() {
    
    
	mIs = this.getResources().openRawResource(R.raw.w);  获取raw下的w.txt中的数据,得到mIS流
    editspinner_w.setText("123");  设置显示字符串123
    ArrayList<String> pindianw = getString(mIs);  获取mIS流中的数据
    editspinner_w.setItemData(pindianw);  设置数据
    editspinner_w.dismissPopWindow(); 关闭弹窗
}

被调用的函数getString:
public static ArrayList<String> getString(InputStream inputStream) {
    
    
    ArrayList<String> res = new ArrayList<>();
    try {
    
    
        InputStreamReader inputStreamReader = new InputStreamReader(inputStream,"UTF-8");
        BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
        String line = "";
        while((line = bufferedReader.readLine()) != null){
    
    
            res.add(line);
        }
    } catch (IOException e) {
    
    
        e.printStackTrace();
    }
    return res;
}

猜你喜欢

转载自blog.csdn.net/qq_30885821/article/details/109094021