【Android】带可输入功能的下拉框EditSpinner,附带Filter功能 |
您所在的位置:网站首页 › 使用下拉列表功能输入数据 › 【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 mSpinnerData; private List mCacheData; private int[] indexs; public SimpleAdapter(Context context, List 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 StringBuilder builder = new StringBuilder(); builder.append("[^\\s]*").append(keyword).append("[^\\s]*"); for (int i = 0; i indexs[mCacheData.size()] = i; mCacheData.add(mSpinnerData.get(i).replaceFirst(keyword, "" + keyword + "")); } } } notifyDataSetChanged(); return mCacheData.size() super(context, attrs); this.mContext = context; initView(attrs); initAnimation(); } public void setItemData(List 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(); } } }5、edit_spinner.xml 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 pindianw = getString(mIs); 获取mIS流中的数据 editspinner_w.setItemData(pindianw); 设置数据 editspinner_w.dismissPopWindow(); 关闭弹窗 } 被调用的函数getString: public static ArrayList getString(InputStream inputStream) { ArrayList 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; } 3、优化(1)修改输入框的类型,点击输入框,弹出来的键盘是数字键盘: (2)修改下拉框条目的间距,原始间距太小了,想换大一点 第3个SimpleAdapter.java中修改: @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); 注释掉上面那句,加上下面这句,其中涉及的spinner_text.xml见下面 textView = (TextView) LayoutInflater.from(mContext).inflate(R.layout.spinner_text, null); } else { textView = (TextView) convertView; } textView.setText(Html.fromHtml(getItem(position))); return textView; }spinner_text.xml (3)智能筛选的颜色是000000黑色,而不让它是aa0000红色,修改第3个SimpleAdapter.java中的onFilter函数中的一句话: @Override public boolean onFilter(String keyword) { mCacheData.clear(); if (TextUtils.isEmpty(keyword)) { mCacheData.addAll(mSpinnerData); for (int i = 0; i StringBuilder builder = new StringBuilder(); builder.append("[^\\s]*").append(keyword).append("[^\\s]*"); for (int i = 0; i indexs[mCacheData.size()] = i; mCacheData.add(mSpinnerData.get(i).replaceFirst(keyword, "" + keyword + ""));//筛选的颜色是黑色,而不让它是aa0000红色 } } } notifyDataSetChanged(); return mCacheData.size()把这里的背景色加上: edit_spinner.xml中 |
今日新闻 |
点击排行 |
|
推荐新闻 |
图片新闻 |
|
专题文章 |
CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭 |