4

我想在列表中搜索并再次在列表中显示结果,所以我使用了 addtextchangelistener,但找不到一种方法让它与带有 subtext 的 listview 一起使用

这是我的代码:

  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(
    }
4

4 回答 4

4

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

首先是使用getFilter()android 为 Adapter 类提供的 Filterable 接口进行过滤。您可以从here.

其次是使用外部 jar Lambdaj,这是从列表中过滤大量数据的最佳和有效方式。您也可以从here.

于 2012-05-22T05:46:23.007 回答
3

我的理解是: - 只是你想过滤ListView. 对?

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

主要的.xml

<?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>

列表视图搜索活动

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());
    }

}
于 2012-05-18T12:00:40.323 回答
2

以下是我将如何更改您的代码以使其工作的方法:

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

//  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数据,所以必须修改:

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 也比所有字符串操作(+、子字符串...)消耗的资源更少

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

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列表。

于 2012-05-17T18:32:57.627 回答
1
ArrayList<String> tempList ;
edtText.addTextChangedListener(new TextWatcher() {
            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
                // TODO Auto-generated method stub
            }

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count,
                    int after) {
                // TODO Auto-generated method stub

            }

            @Override
            public void afterTextChanged(Editable s) {
                // TODO Auto-generated method stub
                if (!edtText.getText().toString().equalsIgnoreCase("")){
                    tempList = new ArrayList<String>();
                    tempList.clear();
                    String text = filterText.getText().toString();
                    for(int i=0 ;i< listname.size();i++){
                        //if(globalconstant.mosq_list.get(globalconstant.hashformosq.get(globalconstant.tempList.get(i))).name.toUpperCase().toString().contains(text.toUpperCase())){
                        if(listname.get(i).toUpperCase().toString().contains(text.toUpperCase())){
                            tempList.add(listname.get(i));
                        }
                    }
                 used changed tempList
                }else{

                    unchaged tempList
                }
            }
        });
    }
于 2012-05-17T18:54:24.003 回答