1

サーバーに配置されたデータベースから取得したデータを使用して ListView を作成しています。ListView には、行ごとに 2 つの TextView があり、1 つは都市用、もう 1 つは各都市がデータベースに持つ ID 用ですが、このテキストビュー (ID の 1 つ) は 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 メソッドの両方にフィルター機能を追加しようとしましたが、運が悪かったので、何か提案はありますか?

PD:BONUS の質問です。ListView を都市ごとにアルファベット順に並べ替えるにはどうすればよいですか?(php ファイルを変更せずに)

編集:フィルター可能を実装するカスタムベースアダプターを作成することで問題を解決しました。最初思ったほど難しくなかった(;_;)

4

2 に答える 2

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);
}
于 2012-10-08T17:55:40.120 に答える
0

編集:ええ、BaseAdapterを使ってみてください。SimpleAdapterが動的に変更できないものなどを読んだだけです...

よくわかりませんが、これは私が思うことです...あなたはAsyncTaskを実装する必要があります

@Override 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);
            }
        });
    }

...extends AsyncTask と言うので、次のような文字列で execute メソッドを試す必要があります。

new cargaCiudades().execute("");

うまくいけば、これが役立つことを願っています.私は自分で試していません.

于 2012-07-08T22:36:04.420 に答える