选择题检索的ListView选择题、ListView

2023-09-06 09:18:20 作者:只为他袖手天下

好,我有多种选择的ListView工作正常。我检查框的接触(在一个String []举行),并能返回值的罚款。因为有些人有一堆接触我想创造一种搜索栏像股票一个用于Android手机的书。我创建了一个EditText和我上面的列表对准它。我发现过滤code在这里计算器,它奇妙的作品。

我的问题:

在筛选某人的名字了,你选择的名字,当你要么退格从EditText上或继续输入,您所选择的名称的正确位置不会被保存。举例来说,如果我开始输入亚当,并获得阿达,然后选择它,如果我退格中输入颂歌,无论位置阿达是在被选中。它汇集了亚当是从点击的地方(假设2),并在列表中恢复检查那个位置(2)即使亚当是不存在了。我需要一种方法来收集名字..然后在列表中恢复或再次搜索,名字亚当被选中,而不是位置亚当是previously的。我绝对没有的想法不是创建吨数组的其他和真的可以使用一些帮助。下面是一些我使用的code:

  @覆盖
      公共无效的onCreate(包savedInstanceState){
        super.onCreate(savedInstanceState);
        的setContentView(R.layout.contacts_list);


        myListView =(ListView控件)findViewById(android.R.id.list);
        sea​​rch_EditText =(EditText上)findViewById(R.id.search_EditText);
        sea​​rch_EditText.addTextChangedListener(filterTextWatcher);

        适配器=新的ArrayAdapter<字符串>(这一点,android.R.layout.simple_list_item_multiple_choice,ContactsList);
        setListAdapter(适配器);

        myListView.setItemsCanFocus(假);
        。getListView()setChoiceMode(2);
        myListView.setTextFilterEnabled(真正的);
        myListView.setFastScrollEnabled(真正的);
        myListView.invalidate();
}

    私人TextWatcher filterTextWatcher =新TextWatcher(){
        公共无效afterTextChanged(编辑S){

        }

        公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,
                之后INT){

        }

        公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,
                诠释计数){

            。adapter.getFilter()过滤器(S);

        }

    };
 

解决方案

我从来没有最终找到一个比一个我准备到下面列出更好的方法。我不使用这个code多了,如果有一个更好的解决方案,我希望有人有它贴的地方。

我最终什么做什么是创建一个的ArrayList 保存所选择的名称。如果选定姓名,名称推入的ArrayList ,而如果它是不加以控制,它是从列表中弹出。当 afterTextChanged 被选择,该列表是通过迭代和,如果他们在适配器目前列出的名称被检查。当您完成与选择的过程,并要继续,我清除的EditText 清除过滤器,因此填充在ListView的完整列表和设置的所有联系人选定如果它们存在于该ArrayList。

快速集成Android实现listview的字母AZ排序 界面侧边字母索引

请注意,我用一个自定义的适配器的接触,只有列表名称列表,因此,如果您使用其它类型的数据的这种解决方案可能会更混乱了,我看这个方法被攻击的解决方案:

  / **用于过滤** /
私人TextWatcher filterTextWatcher =新TextWatcher(){

    公共无效beforeTextChanged(CharSequence中,诠释开始,诠释计数,之后INT){

        ListView控件列表视图= getListView();

        SparseBooleanArray检查= listview.getCheckedItemPositions();
        的for(int i = 0; I< ContactsList.length;我++){
            如果(checked.get(我)==真){
                对象o = getListAdapter()的getItem(我)。
                字符串名称= o.toString();
                //如果数组列表中不包含的名称,其添加
                如果(selected.contains(名)){
                    // 没做什么
                } 其他 {
                    selected.add(名称);
                }
            }
        }
    } //<  -  beforeTextChanged结束

    公共无效onTextChanged(CharSequence中,诠释开始,诠释之前,诠释计数){
        。adapter.getFilter()过滤器(S);
    } //<  -  onTextChanged结束

    公共无效afterTextChanged(编辑S){
        ListView控件列表视图= getListView();
        //取消选中的一切:
        的for(int i = 0; I< listview.getCount();我++){
            listview.setItemChecked(我,FALSE);
        }

        adapter.getFilter()。过滤(S,新Filter.FilterListener(){
            公共无效onFilterComplete(诠释计数){
                adapter.notifyDataSetChanged();
                ListView控件列表视图= getListView();
                的for(int i = 0; I< adapter.getCount();我++){
                    //如果当前(过滤的)
                    //列表视图您正在查看已包含在列表中的名称,
                    //勾选
                    对象o = getListAdapter()的getItem(我)。
                    字符串名称= o.toString();
                    如果(selected.contains(名)){
                        listview.setItemChecked(我,真正的);
                    } 其他 {
                        listview.setItemChecked(我,FALSE);
                    }
                }

            }
        });
    } //<  -  afterTextChanged结束

}; //<  -  TextWatcher结束
 

您不想使用的过滤器时使用索引,因为索引1可能是一个在一个的ListView ,它可能是另一个的ListView 项目,当你更换过滤器。

OK I have a multiple choice ListView that works fine. I check the boxes for the contacts (held in a String[]) and can return the values fine. Because some people have a bunch of contacts I wanted to create a search bar kind of like the stock one for the Android phone book. I created an EditText and aligned it above my list. I found the filtering code here on StackOverflow and it works wonderfully.

My Problem:

When you filter someones name out, and you select the name, when you either backspace from the EditText or continue typing, the correct position of the name you selected is not saved. For example, if I start typing "Adam" and get to "Ada" and select it, if I backspace to type in "Carol", whatever position "Ada" was at is selected. It gathers the place that "Adam" was at from the click (Let's say 2) and when the list is restored checks that position (2) even though Adam is not there anymore. I need a way to gather the name.. then when the list is restored or searched again, the NAME Adam is checked and not the POSITION Adam was previously at. I have absolutely no ideas other than creating tons of Arrays and could really use some help. Below is some of the code I'm using:

    @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.contacts_list);


        myListView = (ListView)findViewById(android.R.id.list);
        search_EditText = (EditText) findViewById(R.id.search_EditText);
        search_EditText.addTextChangedListener(filterTextWatcher);

        adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice, ContactsList); 
        setListAdapter(adapter);

        myListView.setItemsCanFocus(false);
        getListView().setChoiceMode(2);
        myListView.setTextFilterEnabled(true);
        myListView.setFastScrollEnabled(true);
        myListView.invalidate();
}

    private TextWatcher filterTextWatcher = new TextWatcher() {
        public void afterTextChanged(Editable s) {

        }

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

        }

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

            adapter.getFilter().filter(s);

        }

    };

解决方案

I never ended up finding a better method than the one I am going to list below. I do not use this code much anymore, and if there is a better solution, I hope someone has it posted somewhere.

What I ended up doing was creating an ArrayList to hold the selected names. If the name is selected, the name is pushed into the ArrayList, and if it is unchecked, it is popped from the list. When afterTextChanged is selected, the list is iterated through and the names are checked if they are currently listed in the adapter. When you finish with the selection process and want to continue, I clear the EditText to clear the filter, therefore populating the complete list in the ListView and setting all of the contacts to selected if they exist in the ArrayList.

Note, I use a custom adapter for a list of contacts that only list names, so this solution may get more confusing if you use other types of data, and I look at this method as a hacked solution:

/** Used for filter **/
private TextWatcher filterTextWatcher = new TextWatcher() {

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

        ListView listview = getListView();

        SparseBooleanArray checked = listview.getCheckedItemPositions();
        for (int i = 0; i < ContactsList.length; i++) {
            if (checked.get(i) == true) {
                Object o = getListAdapter().getItem(i);
                String name = o.toString();
                // if the arraylist does not contain the name, add it
                if (selected.contains(name)){ 
                    // Do Nothing
                } else {
                    selected.add(name);
                }
            }
        }           
    } //<-- End of beforeTextChanged

    public void onTextChanged(CharSequence s, int start, int before, int count) {           
        adapter.getFilter().filter(s);              
    } //<-- End of onTextChanged

    public void afterTextChanged(Editable s) {
        ListView listview = getListView();
        // Uncheck everything:
        for (int i = 0; i < listview.getCount(); i++){
            listview.setItemChecked(i, false);                  
        }

        adapter.getFilter().filter(s, new Filter.FilterListener() {
            public void onFilterComplete(int count) {
                adapter.notifyDataSetChanged();
                ListView listview = getListView();
                for (int i = 0; i < adapter.getCount(); i ++) {
                    // if the current (filtered) 
                    // listview you are viewing has the name included in the list,
                    // check the box
                    Object o = getListAdapter().getItem(i);
                    String name = o.toString();
                    if (selected.contains(name)) {
                        listview.setItemChecked(i, true);
                    } else {
                        listview.setItemChecked(i, false);
                    }
                }

            }
        });         
    } //<-- End of afterTextChanged

}; //<-- End of TextWatcher

You don't want to use Indexes when using the filters because index 1 might be something in one ListView, and it might be another ListView item when you change the filter.