我正在使用从放置在服务器中的数据库获取的数据创建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文件)
编辑:我通过创建实现可过滤的自定义基本适配器解决了这个问题。并不像我最初想的那么难;)答案 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("");
希望这有帮助,我自己没有尝试过,现在没时间,但这是我一见钟情......