功能实现,分为前期准备+使用。
在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();
}
}
}
5、edit_spinner.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<EditText
android:id="@+id/edit_sipnner_edit"
style="@style/edit_main_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:inputType="number"/>
<ImageView
android:id="@+id/edit_spinner_expand"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/edit_sipnner_edit"
android:layout_alignEnd="@+id/edit_sipnner_edit"
android:layout_alignRight="@+id/edit_sipnner_edit"
android:layout_alignTop="@+id/edit_sipnner_edit"
android:padding="8dp"
android:src="@drawable/ic_expand_more_black"/>
<View
android:id="@+id/edit_spinner_expand_above"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/edit_sipnner_edit"
android:layout_alignLeft="@id/edit_spinner_expand"
android:layout_alignRight="@id/edit_spinner_expand"
android:layout_alignTop="@+id/edit_sipnner_edit"
android:padding="8dp"/>
</RelativeLayout>
前期定义:
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;
}
(1)修改输入框的类型,点击输入框,弹出来的键盘是数字键盘:
<EditText
android:id="@+id/edit_sipnner_edit"
style="@style/edit_main_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:inputType="number" <---只需要这里加上这句话
android:maxLength="5" 添加了额这句话只能输入最多5个字符
/>
(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
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:textColor="@color/black"
android:textSize="16sp" />
(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 < 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=\"#000000\">" + keyword + "</font>"));//筛选的颜色是黑色,而不让它是aa0000红色
}
}
}
notifyDataSetChanged();
return mCacheData.size() <= 0;
}
(4)修改输入框的背景色
把这里的背景色去掉:
<android.support.design.widget.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="50dp"
android:background="?attr/colorPrimary"
app:theme="@style/toolbarTheme"
app:titleTextAppearance="@style/titleTheme"
app:logo="@drawable/logo_32"
app:titleMarginStart="30dp"
app:popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
把这里的背景色加上:
edit_spinner.xml中
<EditText
android:id="@+id/edit_sipnner_edit"
style="@style/edit_main_bg"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:inputType="number"/>