带有自定义适配器和过滤器的Autocompletetextview

时间:2013-05-28 00:43:56

标签: android

我正在尝试为此ArrayAdapter设置自定义AutoCompleteTextView

public class AutoCompleteContactArrayAdapter extends
    ArrayAdapter<Map<String, String>> implements Filterable {
private Context mContext;
private List<Map<String, String>> mContactList;

public AutoCompleteContactArrayAdapter(Context context,
        List<Map<String, String>> objects) {
    super(context, R.layout.auto_contact_list, objects);
    mContext = context;
    mContactList = objects;
    // TODO Auto-generated constructor stub
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.auto_contact_list, parent,
            false);
    TextView nameView = (TextView) rowView.findViewById(R.id.ccontName);
    TextView phoneView = (TextView) rowView.findViewById(R.id.ccontNo);
    TextView typeView = (TextView) rowView.findViewById(R.id.ccontType);
    Map<String, String> contactMap = mContactList.get(position);

    nameView.setText(contactMap.get("name"));
    phoneView.setText(contactMap.get("phone"));
    typeView.setText(contactMap.get("type"));

    return rowView;
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<String> result = new ArrayList<String>();
            result.add("test");
            result.add("another");
            result.add("last");
            FilterResults r = new FilterResults();
            r.values = result;
            r.count = result.size();
            return r;
        }
    };
}
}

在调试中,应用程序正在输入filter方法publishResults()performFiltering(),但正在显示的结果集不是我的测试array [测试,另一个,最后]它只是显示忽略我的过滤器的所有结果。

5 个答案:

答案 0 :(得分:30)

以下是我的代码的当前实现:

xml

<AutoCompleteTextView
    android:id="@+id/searchAutoComplete"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentRight="true"
    android:layout_centerVertical="true"
    android:layout_marginRight="10dp"
    android:layout_toRightOf="@+id/linearLayout1"
    android:background="@drawable/abs__textfield_search_default_holo_light"
    android:drawableLeft="@drawable/abs__ic_search_api_holo_light"
    android:drawableRight="@drawable/abs__ic_clear_holo_light"
    android:hint="@string/search"
    android:imeOptions="actionSearch"
    android:inputType="textAutoComplete|textAutoCorrect" >

适配器:

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

import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;

public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {

    private ArrayList<String> fullList;
    private ArrayList<String> mOriginalValues;
    private ArrayFilter mFilter;

    public AutoCompleteAdapter(Context context, int resource, int textViewResourceId, List<String> objects) {

        super(context, resource, textViewResourceId, objects);
        fullList = (ArrayList<String>) objects;
        mOriginalValues = new ArrayList<String>(fullList);

    }

    @Override
    public int getCount() {
        return fullList.size();
    }

    @Override
    public String getItem(int position) {
        return fullList.get(position);
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        return super.getView(position, convertView, parent);
    }

    @Override
    public Filter getFilter() {
        if (mFilter == null) {
            mFilter = new ArrayFilter();
        }
        return mFilter;
    }


    private class ArrayFilter extends Filter {
        private Object lock;

        @Override
        protected FilterResults performFiltering(CharSequence prefix) {
            FilterResults results = new FilterResults();

            if (mOriginalValues == null) {
                synchronized (lock) {
                    mOriginalValues = new ArrayList<String>(fullList);
                }
            }

            if (prefix == null || prefix.length() == 0) {
                synchronized (lock) {
                    ArrayList<String> list = new ArrayList<String>(mOriginalValues);
                    results.values = list;
                    results.count = list.size();
                }
            } else {
                final String prefixString = prefix.toString().toLowerCase();

                ArrayList<String> values = mOriginalValues;
                int count = values.size();

                ArrayList<String> newValues = new ArrayList<String>(count);

                for (int i = 0; i < count; i++) {
                    String item = values.get(i);
                    if (item.toLowerCase().contains(prefixString)) {
                        newValues.add(item);
                    }

                }

                results.values = newValues;
                results.count = newValues.size();
            }

            return results;
        }

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

        if(results.values!=null){
        fullList = (ArrayList<String>) results.values;
        }else{
            fullList = new ArrayList<String>();
        }
            if (results.count > 0) {
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }
    }
}

最后在代码中初始化像这样...

       ArrayList<String> searchArrayList= new ArrayList<String>();
//initilaze this array with your data
        AutoCompleteAdapter adapter = new AutoCompleteAdapter(this, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, searchArrayList);
        autoCompleteTextView = (AutoCompleteTextView) customNav.findViewById(R.id.searchAutoComplete);
        autoCompleteTextView.setAdapter(adapter);

完成:)

答案 1 :(得分:4)

好吧,我想我弄清楚Luksprog说这个代码现在有用了,关键是这个

mContactList = (ArrayList<Map<String, String>>) results.values;

@Override
public int getCount(){
    return mContactList.size();
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) mContext
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View rowView = inflater.inflate(R.layout.auto_contact_list, parent,
            false);
    TextView nameView = (TextView) rowView.findViewById(R.id.ccontName);
    TextView phoneView = (TextView) rowView.findViewById(R.id.ccontNo);
    TextView typeView = (TextView) rowView.findViewById(R.id.ccontType);
    Map<String, String> contactMap = mContactList.get(position);

    nameView.setText(contactMap.get("name"));
    phoneView.setText(contactMap.get("phone"));
    typeView.setText(contactMap.get("type"));

    return rowView;
}
@Override
public Filter getFilter() {
    return new Filter() {
        @Override
        protected void publishResults(CharSequence constraint,
                FilterResults results) {

            if (results.count > 0) {
                mContactList = (ArrayList<Map<String, String>>) results.values;
                notifyDataSetChanged();
            } else {
                notifyDataSetInvalidated();
            }
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            ArrayList<Map<String, String>> result = new ArrayList<Map<String, String>>();
            HashMap<String,String> myMap = new HashMap<String,String>();
            myMap.put("name", "key");
            result.add(myMap);
            HashMap<String,String> myMap2 = new HashMap<String,String>();
            myMap2.put("name", "is");
            result.add(myMap2);
            HashMap<String,String> myMap3 = new HashMap<String,String>();
            myMap3.put("name", "another");
            result.add(myMap3);
            FilterResults r = new FilterResults();
            r.values = result;
            r.count = result.size();
            return r;
        }
    };
}

答案 2 :(得分:2)

Autocompletetextview使用适配器显示自动完成建议下拉列表。

Adapater应该是可过滤的,并且应该为数据列表中的每个项目提供视图填充数据。 Autocompletetextview使用适配器中定义的过滤器来获取结果并显示它们。

因此,如果您需要创建自定义适配器,则需要为getView提供实现并提供过滤器类。

完整的工作实例 autocompletetextview自定义布局和自定义适配器

http://www.zoftino.com/android-autocompletetextview-custom-layout-and-adapter

答案 3 :(得分:0)

如果您想在其中添加数据

String[] arr=new String[100];

然后错了。 您可以执行与ArrayList形式相同的工作,但请记住,您永远不会在这里放置Getter / Setter类。只需声明一下即可。看到这个例子。

在主分区中声明:

   ArrayList<String>arr=new ArrayList<>();

,然后以这种方式将其初始化:

for (int i = 0; i < jsonArray.length(); i++) {
                JSONObject jsonObject1 = (JSONObject) jsonArray.get(i);
                String imei = jsonObject1.getString("imei");
                String name = jsonObject1.getString("name");
                String my_pic = jsonObject1.getString("my_pic");
                String email = jsonObject1.getString("email");

                arr.add(name);
            }


            adapter= new ArrayAdapter<>
                    (this, android.R.layout.select_dialog_item, arr);
            autoCompleteText.setThreshold(1);//will start working from first character
            autoCompleteText.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
            autoCompleteText.setTextColor(Color.RED);


        }

我希望这对您有用。祝你好运

答案 4 :(得分:0)

任何对 Kotlin 版本感兴趣的人都可以在下面找到。

val ac = findViewById<AutoCompleteTextView>(R.id.searchAutoComplete)
var dataList = listOf("argument", "aid", "appear", "air", "advertise", "appendix", "apathy", "absence", "analysis",
    "bind", "bathroom", "broadcast", "bomb", "build", "bark", "beef", "brain", "bend",
    "conviction", "coincide", "castle", "cafe", "chemistry", "clean", "closed", "composer", "care", "crude")
ac.setAdapter(object : ArrayAdapter<String>(
    context, android.R.layout.simple_dropdown_item_1line, android.R.id.text1, dataList,
), Filterable {
    private var oriValue = dataList.toList()
    override fun getCount() = dataList.size
    override fun getItem(position: Int) = dataList[position]
    override fun getFilter() = object : Filter() {
        override fun performFiltering(prefix: CharSequence?) =
            FilterResults().apply {
                mutableListOf<String>().apply {
                    if (prefix == null || prefix.isEmpty()) addAll(oriValue)
                    else oriValue.map {
                        if (it.contains(prefix.toString(), true)) // ignore case
                        // if (it.contains(prefix.toString())) // match case
                        // if (it.startsWith(prefix.toString(), true)) // start with
                            add(it)
                    }
                    values = this
                    count = this.size
                }
            }
        override fun publishResults(constraint: CharSequence?, results: FilterResults?) {
            @Suppress("UNCHECKED_CAST")
            dataList = results?.values as List<String>? ?: listOf()
            if (results?.count ?: -1 > 0) notifyDataSetChanged() 
            else notifyDataSetInvalidated()
        }
    }
})