首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >包含带有subtext的列表视图的addTextChangedListener

包含带有subtext的列表视图的addTextChangedListener
EN

Stack Overflow用户
提问于 2012-05-14 16:36:45
回答 4查看 5.9K关注 0票数 4

我想搜索列表并在列表中再次显示结果,所以我使用了addtextchangelistener,但找不到使用subtext的listview的方法

下面是我的代码:

代码语言:javascript
复制
  package com.android;

    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.LineNumberReader;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.StringTokenizer;

    import android.app.ListActivity;
    import android.os.Bundle;
    import android.text.Editable;
    import android.text.TextWatcher;
    import android.util.Log;
    import android.view.View;
    import android.widget.ArrayAdapter;
    import android.widget.EditText;
    import android.widget.ListView;
    import android.widget.SimpleAdapter;
    import android.widget.TextView;

    public class MyListDemoActivity extends ListActivity {
        /** Called when the activity is first created. */
        TextView tv;



        //** List<String> content;

        EditText actv;
        List<String> arr_sort;
        //** ArrayAdapter<String> adapter;
        SimpleAdapter simpleadapter;
        ListView lv;

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

            String line = " ";

            LineNumberReader linenoreader = null;
            StringTokenizer stringtokanixer = null;
        //**    content = new ArrayList<String>();
            List<Map<String,String>> data= new ArrayList<Map<String,String>>();

            lv = (ListView) findViewById(android.R.id.list);

            try {

                InputStream istream = getResources().openRawResource(R.raw.grelist);
                InputStreamReader streamreader = new InputStreamReader(istream);

                linenoreader = new LineNumberReader(streamreader);
                linenoreader.mark(15);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }// try catch ends here

            Log.v("getting", "working");

            for(int i=0;i<8;i++)
            {
                Map<String,String> datum= new HashMap<String,String>(2);
                try {
                    line = linenoreader.readLine();
                    Log.v("item",line);
                } catch (IOException e) {

                    e.printStackTrace();
                }
                Log.v("getting", line);
                stringtokanixer = new StringTokenizer(line);

                String st = stringtokanixer.nextToken();
                String meaning="";
                while (stringtokanixer.hasMoreTokens()) {
                    meaning +=" " +stringtokanixer.nextToken();

                }// for ends

                // map is used to add word and meaning 
                datum.put("word",st);
                datum.put("meaning",meaning);
                data.add(datum);

                //List<String> is usedto add
        //**        content.add(st);
            }


            simpleadapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"word","meaning"}, new int[]{android.R.id.text1,android.R.id.text2});

            // setListAdapter(adapter);

            lv.setAdapter(simpleadapter);
            tv = (TextView) findViewById(R.id.textView1);

            actv = (EditText) findViewById(R.id.editText1);


            /*  
                actv.addTextChangedListener(new TextWatcher() {
                int len = 0;


                @Override
                public void onTextChanged(CharSequence s, int start, int before,
                        int count) {
                        arr_sort = new ArrayList<String>();

                        len = actv.getText().length();

                        for (int i = 0; i < content.size(); i++) {
                            if (len <= content.get(i).length()) {
                                if (actv.getText()
                                        .toString()
                                        .trim()
                                        .equalsIgnoreCase(
                                                (String) content.get(i).subSequence(0,
                                                        len))) {

                                    arr_sort.add(content.get(i));
                                    Log.v("infor loop afterTextChanged", s.toString());
                                }

                            }

                        }

            //          adapter.notifyDataSetChanged();

                        adapter = new ArrayAdapter<String>(MyListDemoActivity.this,
                            android.R.layout.simple_list_item_1, arr_sort);
                        setListAdapter(adapter);
                }

                @Override
                public void beforeTextChanged(CharSequence s, int start, int count,
                        int after) {
                        Log.v("beforetextchange","hello here");
                }

                @Override
                public void afterTextChanged(Editable s) {
                    Log.v("aftertextchange","hello here");

                }
            }); // text watcher class ends here
    */


        }// on create ends here

        public void onListItemClick(ListView ls, View v, int position, long id) {
            //tv.setText(content.get(position));

            // tv.setText(content[position]) // in case of string

        }// endsd here onListItemClick(
    }
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-05-18 02:32:58

下面是我如何更改您的代码以使其正常工作:

1.我会删除arr_sort变量,并添加另一个ArrayList Maps来保存过滤后的值:

代码语言:javascript
复制
//  List<String> arr_sort;
    final ArrayList<Map<String, String>> data = 
        new ArrayList<Map<String, String>>();
    final ArrayList<Map<String, String>> filteredData = 
        new ArrayList<Map<String, String>>();

我也会让它们成为最终的,因为当我们可以修改它们的内容时,给它们分配全新的值是没有意义的。

2. simpleadapter应始终显示过滤后的数据,因此需要进行修改:

代码语言:javascript
复制
filteredData.addAll(data); // fill up filteredData initially with the whole list
simpleadapter = new SimpleAdapter(this, filteredData, 
        android.R.layout.simple_list_item_2, 
        new String[] { "word", "meaning" }, 
        new int[] {android.R.id.text1, android.R.id.text2 });

3.接下来,我将过滤代码从onTextChanged方法移到afterTextChanged方法,以根据输入的整个文本执行过滤。使用Regexp也比所有字符串操作(+,substring...)消耗的资源更少。

这样,您的TextWatcher实现将如下所示:

代码语言:javascript
复制
actv.addTextChangedListener(new TextWatcher()
{
    @Override
    public void onTextChanged(CharSequence s, int start, int before, int count)
    {}

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

    @Override
    public void afterTextChanged(Editable s)
    {
        Log.v("MLDA", "afterTextChanged");
        // a temporary source list for better performance:
        // if it's possible, use the smaller filtered list
        final ArrayList<Map<String, String>> tmpSource = 
            new ArrayList<Map<String,String>>();
        tmpSource.addAll(
            (filterText.length() > 0 && s.toString().contains(filterText)) 
            ? filteredData : data);
        filterText = s.toString();

        // a temporary result list to fill with the filtered data
        final ArrayList<Map<String, String>> tmpResult = 
            new ArrayList<Map<String,String>>();

        if (filterText.length() == 0)
            tmpResult.addAll(data); //if no filter, return the base data
        else
        {
            final Pattern pattern = 
                Pattern.compile("(?i)" + Pattern.quote(s.toString()));
            Matcher matcher;
            for (final Map<String, String> map : tmpSource)
            {
                //first match against the "word":
                matcher = pattern.matcher(map.get("word"));
                if (!matcher.find())
                {
                    //if no matches were found, try to match the "meaning"
                    matcher = pattern.matcher(map.get("meaning"));
                    if (!matcher.find())
                        continue; //if no match, move to the next map
                }
                tmpResult.add(map); //match found: add to new list
            }
        }

        filteredData.clear();
        filteredData.addAll(tmpResult);
        simpleadapter.notifyDataSetChanged(); // update display
    }
});

使用临时列表可以在不更新gui的情况下构建整个过滤数据(如果直接向filteredData列表删除/添加项目,适配器将触发更新方法)。

还要注意,通过检查新的过滤器文本是否包含旧的文本,我们可以使用当前的filteredData列表作为源。

类似地,如果filterText是一个空字符串,那么就没有必要执行任何匹配,我们可以简单地返回base列表。

票数 2
EN

Stack Overflow用户

发布于 2012-05-22 13:46:23

我已经回答了两个StackOverflow问题,你可以,

首先是使用安卓提供的getFilter(),通过Adapter类的Filterable接口进行过滤。你可以从here上查看。

其次是使用外部jar Lambdaj,这是从列表中过滤大量数据的最好、最有效的方法。您也可以从here查看这一点。

票数 4
EN

Stack Overflow用户

发布于 2012-05-18 20:00:40

我所理解的是:-你只是想过滤ListView。对吗?

如果我误解了问题,请告诉我!

main.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"
    android:layout_width="fill_parent" android:layout_height="fill_parent">

    <EditText android:id="@+id/search" android:layout_width="fill_parent" android:layout_height="wrap_content"
        android:inputType="text" />

    <ListView android:id="@+id/list" android:layout_width="fill_parent" android:layout_height="fill_parent" />

</LinearLayout>

ListViewSearchActivity

代码语言:javascript
复制
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;

public class ListViewSearchActivity extends Activity implements TextWatcher {

    private SimpleAdapter simpleAdapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.main);

        EditText search = (EditText) findViewById(R.id.search);
        search.addTextChangedListener(this);

        List<Map<String, String>> data = new ArrayList<Map<String, String>>();
        for(int i=0;i<8;i++) {
            Map<String,String> map = new HashMap<String, String>(2);
            map.put("word", "word " + i);
            map.put("meaning", "meaning " + (i + 10));
            data.add(map);
        }

        ListView listView = (ListView) findViewById(R.id.list);
        this.simpleAdapter = new SimpleAdapter(this, data, android.R.layout.simple_list_item_2, new String[]{"word","meaning"}, new int[]{android.R.id.text1,android.R.id.text2});
        listView.setAdapter(this.simpleAdapter);
    }

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

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

    @Override
    public void afterTextChanged(Editable s) {
        this.simpleAdapter.getFilter().filter(s.toString());
    }

}
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10579922

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档