Android过滤器并在Async任务期间使用适配器对ListView进行排序

时间:2012-07-08 21:56:13

标签: android listview search asynchronous filter

我正在使用从放置在服务器中的数据库获取的数据创建ListView。 ListView每行有两个TextView,一个用于城市,另一个用于每个城市的ID在数据库上,但是这个文本视图(ID的一个)是来自ListView的HIDDEN,因此用户只能看到城市。

一切正常,但现在我想在listview中添加一个搜索栏,以便我可以过滤城市,但是我遇到了以下问题:

1.- ListView的适配器是一个简单的适配器,正如您在代码中看到的那样,我没有找到如何使用这样的适配器过滤Listview的示例。

2.-我通过异步任务获取ListView的信息,并在异步任务的 onPostExecute 方法中设置ListView,再次,我没有找到任何示例当它在这样的地方时过滤它。

这是“相关”代码。如果有人需要完整的代码,请问我。

public class SQLWebVer extends ListActivity implements OnItemClickListener{
ProgressDialog barraProgreso;
    ArrayList<HashMap<String, String>> listaCiudades;
    .
    .//some more varibles for the class
    .
    protected void onCreate(Bundle savedInstanceState) {
    // TODO Auto-generated method stub
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sqlwebver);

    // Hashmap de la ListView
    listaCiudades = new ArrayList<HashMap<String, String>>();

    new cargaCiudades().execute();//this is the call to the async task

    }
    class cargaCiudades extends AsyncTask<String, String, String>{//the async task
    .
    .//here are the onPreExecute and doInBackground methods
    .
         protected void onPostExecute(String file_url) {
        barraProgreso.dismiss();//quita la barra de la pantalla
        runOnUiThread(new Runnable(){//actualiza la UI(la listView)

            public void run() {
                // TODO Auto-generated method stub
                ListAdapter adapter = new SimpleAdapter 
                                      (SQLWebVer.this, listaCiudades, 
                                      R.layout.sqlweblist_item,
                          new String[]{"key_id", "key_ciudad"},new int[]
                                      {R.id.ID_CIUDAD, R.id.CIUDAD});

                setListAdapter(adapter);
            }

        });
        }
     }

我试图在onCreate和onPostExecute方法上添加过滤器功能,但没有运气,所以有什么建议吗?

P.D:BONUS问题,我如何按城市按字母顺序对ListView进行排序,但保持每个ID与他的城市相关?(不更改php文件)

编辑:我通过创建实现可过滤的自定义基本适配器解决了这个问题。并不像我最初想的那么难;)

2 个答案:

答案 0 :(得分:3)

前段时间我解决了这个问题,但我忘记发布对我有用的答案,所以这里是:

package android.codigo;

import java.util.ArrayList;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.ImageView;
import android.widget.TextView;


public class MiAdaptador extends ArrayAdapter<Item2> {

    private ArrayList<Item2> allItems;
    @SuppressWarnings("unused")
    private ArrayList<Item2> subItems;

    public ArrayList<Item2> getItems() {
        return allItems;
    }

    public MiAdaptador(Context context, int textViewResourceId,
            ArrayList<Item2> items) {
        super(context, textViewResourceId, items);
        this.allItems = items;
        this.subItems = items;
    }

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View v = convertView;
        if (v == null) {
            LayoutInflater vi = (LayoutInflater) getContext()
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = vi.inflate(R.layout.item2_lista, null);
        }

        Item2 it = subItems.get(position);

        if (it != null) {
            TextView nombre = (TextView) v.findViewById(R.id.textView1);
            ImageView img = (ImageView) v.findViewById(R.id.imageView1);
            ImageView img2 = (ImageView) v.findViewById(R.id.imageView2);
            ImageView img3 = (ImageView) v.findViewById(R.id.imageView3);
            if (nombre != null) {
                nombre.setText(it.getNombre());
            }
            if (img != null) {
                img.setImageResource(it.getID());
            }
            if (img != null) {
                img2.setImageResource(it.getID2());
            }
            if (img != null) {
                img3.setImageResource(it.getID3());
            }
        }

        return v;

    }
    public Filter getFilter() {
        Filter filter = new Filter() {

            @Override
            protected FilterResults performFiltering(CharSequence prefijo) {

                FilterResults results = new FilterResults();
                ArrayList<Item2> aux = new ArrayList<Item2>();

                // El prefijo tiene que ser mayor que 0 y existir
                if (prefijo != null && prefijo.toString().length() > 0) {

                    for (int index = 0; index < allItems.size(); index++) {
                        Item2 si = allItems.get(index);
                        String nombre = si.getNombre();

                        String nom[] = nombre.split(" ");
                        for(int i=0; i<nom.length; i++){
                            if (nom[i].toLowerCase().startsWith(prefijo.toString().toLowerCase())) {
                                aux.add(si);
                            }
                        }
                    }
                    results.values = aux;
                    results.count = aux.size();
                } else {
                    synchronized (allItems) {
                        results.values = allItems;
                        results.count = allItems.size();
                    }
                }
                return results;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence prefijo,FilterResults results) {
                subItems = (ArrayList<Item2>) results.values;
                notifyDataSetChanged();

            }
        };
        return filter;
    }
}

并在主类中添加了这个:

ListView lv = (ListView)findViewById(R.id.list);
    lv.setTextFilterEnabled(true);
    lv.setAdapter(adapter);
    lv.setOnItemClickListener(this);




    TextWatcher filtro = new TextWatcher(){

        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub

        }

        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub

        }

        public void onTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub
            adapter.getFilter().filter(e.getText().toString());//filtra el texto metido en el edittext en tiempo real
        }

    };

    e.addTextChangedListener(filtro);
}

答案 1 :(得分:0)

编辑:是的,尝试使用BaseAdapter,我只是读了一些SimpleAdapter无法动态改变的东西......或者类似的东西......

我不太确定,但这就是我的想法...... 你是AsyncTask必须实现

@覆盖         protected Void doInBackground(String ... params){

        SQLWebVer.this.runOnUiThread(new Runnable() {

            public void run() {

                ListAdapter adapter = new SimpleAdapter 
                                  (SQLWebVer.this, listaCiudades, 
                                  R.layout.sqlweblist_item,
                      new String[]{"key_id", "key_ciudad"},new int[]
                                  {R.id.ID_CIUDAD, R.id.CIUDAD});

            setListAdapter(adapter);
            }
        });
    }

因为你说...扩展了AsyncTask, 你应该尝试使用字符串的execute方法,如:

new cargaCiudades().execute("");

希望这有帮助,我自己没有尝试过,现在没时间,但这是我一见钟情......