AutoCompleteTextView源码解析及使用

一、AutoCompleteTextView源码

1.1 设置适配器
...
//该适配器必须继承ListAdapter并且实现Filterable接口
public <T extends ListAdapter & Filterable> void setAdapter(T adapter) {
        if (mObserver == null) {
            mObserver = new PopupDataSetObserver(this);
        } else if (mAdapter != null) {
            mAdapter.unregisterDataSetObserver(mObserver);
        }
        mAdapter = adapter;
        if (mAdapter != null) {
            //获取适配器中的过滤器
            mFilter = ((Filterable) mAdapter).getFilter();
            adapter.registerDataSetObserver(mObserver);
        } else {
            mFilter = null;
        }

        mPopup.setAdapter(mAdapter);
    }
    ...
1.2 构造函数
public AutoCompleteTextView(Context context, AttributeSet attrs, int defStyleAttr,
            int defStyleRes, Theme popupTheme) {
        super(context, attrs, defStyleAttr, defStyleRes);

       ....
        mPopup = new ListPopupWindow(mPopupContext, attrs, defStyleAttr, defStyleRes);
        mPopup.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
        mPopup.setPromptPosition(ListPopupWindow.POSITION_PROMPT_BELOW);
        mPopup.setListSelector(popupListSelector);
        //给Popuwindow添加条目点击事件
        mPopup.setOnItemClickListener(new DropDownItemClickListener());
		//默认超过两个字符之后才开发执行过滤操作
        mThreshold = a.getInt(R.styleable.AutoCompleteTextView_completionThreshold, 2);
		//创建时已经自己给自己添加了一个文本内容变化的监听
        addTextChangedListener(new MyWatcher());

        mPassThroughClickListener = new PassThroughClickListener();
        super.setOnClickListener(mPassThroughClickListener);
    }

1.4 DropDownItemClickListener
...
 private class DropDownItemClickListener implements AdapterView.OnItemClickListener {
        public void onItemClick(AdapterView parent, View v, int position, long id) {
            performCompletion(v, position, id);
        }
}
...

private void performCompletion(View selectedView, int position, long id) {
       		...
            //填充控件文本
            replaceText(convertSelectionToString(selectedItem));
         	...
    }

1.5 MyWatcher
 private class MyWatcher implements TextWatcher {
        public void afterTextChanged(Editable s) {
        //执行过滤操作
            doAfterTextChanged(); 
        }
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
            doBeforeTextChanged();
        }
        public void onTextChanged(CharSequence s, int start, int before, int count) {
        }
    }

二、AutoCompleteTextView使用

2.1 自定义适配器CompleteAdapter
package yang.study.com.appcompletetextviewdemo;

import android.content.Context;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;

import java.util.List;

public class CompleteAdapter extends BaseAdapter implements Filterable {
    private final Context context;
    private final List<ProvinceModel> provinceModelList;

    public CompleteAdapter(Context context, List<ProvinceModel> provinceModelList) {
        this.context = context;
        this.provinceModelList = provinceModelList;
    }

    public void setData(Object objects) {
        provinceModelList.clear();
        if (objects != null) {
            List<ProvinceModel> provinceModelListResult = (List<ProvinceModel>) objects;
            provinceModelList.addAll(provinceModelListResult);
            notifyDataSetChanged();
        } else {
            notifyDataSetInvalidated();
        }
    }

    @Override
    public int getCount() {
        Log.e("Filter::", "CompleteAdapter::getCount==");
        return provinceModelList == null ? 0 : provinceModelList.size();
    }

    @Override
    public ProvinceModel getItem(int position) {
        return provinceModelList.get(position);
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = View.inflate(context, android.R.layout.simple_list_item_1, null);
        }
        TextView tv = (TextView) convertView;
        tv.setText(position + "数据id==" + getItem(position).provinceName);
        return convertView;
    }

    /**
     * 给AppCompatAutoCompleteTextView设置Adapter之后就会被调用
     * @return
     */
    @Override
    public Filter getFilter() {
        return new CompleteFilterable(provinceModelList, this);
    }
}

2.1 自定义过滤器CompleteFilterable
package yang.study.com.appcompletetextviewdemo;

import android.text.TextUtils;
import android.util.Log;
import android.widget.Filter;

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

public class CompleteFilterable extends Filter {
    private List<ProvinceModel> provinceModelList = new ArrayList<>();
    private CompleteAdapter completeAdapter;

    public CompleteFilterable(List<ProvinceModel> provinceModelList, CompleteAdapter completeAdapter) {
        this.provinceModelList.addAll(provinceModelList);
        this.completeAdapter = completeAdapter;
    }

    /**
     * 执行过滤
     * 如果采取服务器端过滤之后返回结果,那么该方法不用执行
     * 任何过滤操作。只需要将查询结果赋值给FilterResults即可
     *
     * @param constraint
     * @return
     */
    @Override
    protected FilterResults performFiltering(CharSequence constraint) {
        FilterResults filterResults = new FilterResults();
        ArrayList<ProvinceModel> provinceModelArrayList = new ArrayList<>();
        if (!TextUtils.isEmpty(constraint)) {
            for (int i = 0; i < provinceModelList.size(); i++) {
                ProvinceModel provinceModel = provinceModelList.get(i);
                if (provinceModel.provinceName.contains(constraint)) {
                    provinceModelArrayList.add(provinceModel);
                }
            }
        }
        filterResults.count = provinceModelArrayList.size();
        filterResults.values = provinceModelArrayList;
        return filterResults;
    }

    /**
     * 发布过滤结果
     *
     * @param constraint
     * @param results
     */
    @Override
    protected void publishResults(CharSequence constraint, FilterResults results) {
        completeAdapter.setData(results.values);
    }

    /**
     * 点击联想搜索结果条目的时候使用
     *
     * @param resultValue
     * @return
     */
    @Override
    public CharSequence convertResultToString(Object resultValue) {
        return resultValue == null ? "" : ((ProvinceModel) resultValue).provinceName;
    }
}

三、注意事项

1.在Activity中使用的时候如果发现软件盘出现将PopupWindow顶起,那么可以在清单文件中给Activity添加android:windowSoftInputMode="adjustNothing"

2.在Dialog中使用的时候如果发现软件盘出现将PopupWindow顶起,那么可以给该Dialog的window设置window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING);

四、效果图

4.1 Activity中使用
4.2 Dialog中使用

源代码

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值