使用 SearchView 过滤后自定义适配器不刷新 - Android-
Custom Adapter Not Refreshing after Filter with SearchView - Android-
这是我的问题:
我正在尝试过滤一个长的 ListView,预加载数据库,使用自定义 ArrayAdapter 实现可过滤,我设置使用 ActionBar SearchView 进行过滤,交易是在完成过滤后(调试我意识到它做得很好) 我的列表视图没有刷新新列表(过滤后的列表),这是我的代码:
CategoriesActivity.java
public class CategoriesActivity extends Activity implements OnQueryTextListener {
ListView lista;
String datos;
private ProgressDialog pDialog;
List<Categoria> elementos;
ArrayAdapter<Categoria> adaptador;
SharedPreferences settings;
SearchView mSearchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_categories);
settings = PreferenceManager.getDefaultSharedPreferences(this);
new CargarListView().execute();
}
public class CargarListView extends AsyncTask<String, Void, String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(CategoriesActivity.this);
pDialog.setCancelable(true);
pDialog.setMessage("Cargando categorias...");
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setProgress(0);
pDialog.show();
}
protected String doInBackground(String... Strings) {
HttpClient httpclient = new DefaultHttpClient();
/*Creamos el objeto de HttpClient que nos permitira conectarnos mediante peticiones http*/
//HttpPost httppost = new HttpPost("http://myurl.com/app/callajax.php");
HttpPost httppost = new HttpPost("http://myurl.com/list_category.php");
/*El objeto HttpPost permite que enviemos una peticion de tipo POST a una URL especificada*/
String text = "";
try {
/*Una vez añadidos los parametros actualizamos la entidad de httppost, esto quiere decir en pocas palabras anexamos los parametros al objeto para que al enviarse al servidor envien los datos que hemos añadido*/
/*Finalmente ejecutamos enviando la info al server*/
HttpResponse resp = httpclient.execute(httppost);
HttpEntity ent = resp.getEntity();/*y obtenemos una respuesta*/
text = EntityUtils.toString(ent);
} catch (ClientProtocolException e) {
e.printStackTrace();
text = "error";
} catch (IOException e) {
e.printStackTrace();
text = "error";
}
return text;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null ) {
try {
JSONArray Jarr = new JSONArray(result);
JSONObject datos = Jarr.getJSONObject(0);
JSONArray jArray = datos.getJSONArray("data");
elementos = new ArrayList<Categoria>();
int sum = 0;
for(int i=0; i < jArray.length(); i++) {
String titulo = jArray.getJSONObject(i).getString("title");
String id = jArray.getJSONObject(i).getString("id");
String cantidad = jArray.getJSONObject(i).getString("count");
elementos.add(new Categoria(id, titulo, cantidad));
sum += Integer.valueOf(cantidad);
}
elementos.add(0, new Categoria("1", "En todos", String.valueOf(sum)));
//Instancia del ListView
lista = (ListView)findViewById(R.id.listView1);
//Inicializar el adaptador con la fuente de datos
adaptador = new CategoriaArrayAdapter(CategoriesActivity.this, elementos);
//Relacionando la lista con el adaptador
lista.setTextFilterEnabled(true);
lista.setAdapter(adaptador);
lista.setFastScrollEnabled(true);
lista.setOnItemClickListener( new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Categoria Opcion = (Categoria)adaptador.getItem(position);
Toast.makeText(getApplicationContext(), "Categoria: "+Opcion.getTitulo(), Toast.LENGTH_SHORT).show();
Editor edit = settings.edit();
edit.putString("PREF_CATEGORY", Opcion.getId());
edit.apply();
finish();
}
});
}catch (JSONException e) {
e.printStackTrace();
}
}
pDialog.dismiss();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.categories, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
setupSearchView(searchItem);
return true;
}
private void setupSearchView(MenuItem searchItem) {
// TODO Auto-generated method stub
mSearchView.setOnQueryTextListener(this);
}
@Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
adaptador.getFilter().filter(newText);
return false;
}
CategoriesArrayAdapter.java
public class CategoriaArrayAdapter extends ArrayAdapter<Categoria> implements Filterable {
List<Categoria> original;
List<Categoria> filtered;
public CategoriaArrayAdapter(Context context, List<Categoria> objects) {
super(context, 0, objects);
this.original = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
//Obteniendo una instancia del inflater
LayoutInflater inflater = (LayoutInflater)getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//Salvando la referencia del View de la fila
View listItemView = convertView;
//Comprobando si el View no existe
if (null == convertView) {
//Si no existe, entonces inflarlo con cat_list_view.xml
listItemView = inflater.inflate(
R.layout.cat_list_item,
parent,
false);
}
//Obteniendo instancias de los elementos
TextView titulo = (TextView)listItemView.findViewById(R.id.txtCat);
TextView cantidad = (TextView)listItemView.findViewById(R.id.txtCantcat);
//Obteniendo instancia de la Tarea en la posición actual
Categoria item = getItem(position);
titulo.setText(item.getTitulo());
cantidad.setText("("+item.getCantidad()+")");
return listItemView;
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
//constraint is the result from text you want to filter against.
//objects is your data set you will filter from
if(constraint != null && original !=null) {
int length= original.size();
filtered.clear();
for (int i = 0; i<length; i++){
Locale locale = Locale.getDefault();
Categoria item = original.get(i);
String data = item.getTitulo();
if (data.toLowerCase(locale).contains(constraint.toString())) {
filtered.add(item);
}
}
filterResults.values = filtered;
filterResults.count = filtered.size();
}else{
filterResults.count = original.size();
filterResults.values = original;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
original = (List<Categoria>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
return filter;
}
}
我是不是漏了什么???我真的需要帮助...
基于这个答案 -> Custom filtering in Android using ArrayAdapter
,这是我的解决方案:
@Override
public Filter getFilter() {
if (filter == null) {
filter = new ArrayFilter();
}
return filter;
}
private class ArrayFilter extends Filter{
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint != null && constraint.length()> 0) {
ArrayList<Categoria> values = new ArrayList<Categoria>(original);
filtered = new ArrayList<Categoria>();
int length = values.size();
for (int i = 0; i<length; i++) {
Locale locale = Locale.getDefault();
Categoria item = values.get(i);
String data = item.getTitulo();
if (data.toLowerCase(locale).contains(constraint.toString())) {
filtered.add(item);
}
}
filterResults.values = filtered;
filterResults.count = filtered.size();
}else{
synchronized(this) {
filterResults.count = original.size();
filterResults.values = original;
}
}
return filterResults;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
data = (List<Categoria>) results.values;
notifyDataSetChanged();
clear();
addAll(data);
notifyDataSetInvalidated();
}
}
}
这是我的问题:
我正在尝试过滤一个长的 ListView,预加载数据库,使用自定义 ArrayAdapter 实现可过滤,我设置使用 ActionBar SearchView 进行过滤,交易是在完成过滤后(调试我意识到它做得很好) 我的列表视图没有刷新新列表(过滤后的列表),这是我的代码:
CategoriesActivity.java
public class CategoriesActivity extends Activity implements OnQueryTextListener {
ListView lista;
String datos;
private ProgressDialog pDialog;
List<Categoria> elementos;
ArrayAdapter<Categoria> adaptador;
SharedPreferences settings;
SearchView mSearchView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_categories);
settings = PreferenceManager.getDefaultSharedPreferences(this);
new CargarListView().execute();
}
public class CargarListView extends AsyncTask<String, Void, String>{
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(CategoriesActivity.this);
pDialog.setCancelable(true);
pDialog.setMessage("Cargando categorias...");
pDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
pDialog.setProgress(0);
pDialog.show();
}
protected String doInBackground(String... Strings) {
HttpClient httpclient = new DefaultHttpClient();
/*Creamos el objeto de HttpClient que nos permitira conectarnos mediante peticiones http*/
//HttpPost httppost = new HttpPost("http://myurl.com/app/callajax.php");
HttpPost httppost = new HttpPost("http://myurl.com/list_category.php");
/*El objeto HttpPost permite que enviemos una peticion de tipo POST a una URL especificada*/
String text = "";
try {
/*Una vez añadidos los parametros actualizamos la entidad de httppost, esto quiere decir en pocas palabras anexamos los parametros al objeto para que al enviarse al servidor envien los datos que hemos añadido*/
/*Finalmente ejecutamos enviando la info al server*/
HttpResponse resp = httpclient.execute(httppost);
HttpEntity ent = resp.getEntity();/*y obtenemos una respuesta*/
text = EntityUtils.toString(ent);
} catch (ClientProtocolException e) {
e.printStackTrace();
text = "error";
} catch (IOException e) {
e.printStackTrace();
text = "error";
}
return text;
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (result != null ) {
try {
JSONArray Jarr = new JSONArray(result);
JSONObject datos = Jarr.getJSONObject(0);
JSONArray jArray = datos.getJSONArray("data");
elementos = new ArrayList<Categoria>();
int sum = 0;
for(int i=0; i < jArray.length(); i++) {
String titulo = jArray.getJSONObject(i).getString("title");
String id = jArray.getJSONObject(i).getString("id");
String cantidad = jArray.getJSONObject(i).getString("count");
elementos.add(new Categoria(id, titulo, cantidad));
sum += Integer.valueOf(cantidad);
}
elementos.add(0, new Categoria("1", "En todos", String.valueOf(sum)));
//Instancia del ListView
lista = (ListView)findViewById(R.id.listView1);
//Inicializar el adaptador con la fuente de datos
adaptador = new CategoriaArrayAdapter(CategoriesActivity.this, elementos);
//Relacionando la lista con el adaptador
lista.setTextFilterEnabled(true);
lista.setAdapter(adaptador);
lista.setFastScrollEnabled(true);
lista.setOnItemClickListener( new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
Categoria Opcion = (Categoria)adaptador.getItem(position);
Toast.makeText(getApplicationContext(), "Categoria: "+Opcion.getTitulo(), Toast.LENGTH_SHORT).show();
Editor edit = settings.edit();
edit.putString("PREF_CATEGORY", Opcion.getId());
edit.apply();
finish();
}
});
}catch (JSONException e) {
e.printStackTrace();
}
}
pDialog.dismiss();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.categories, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
mSearchView = (SearchView) searchItem.getActionView();
setupSearchView(searchItem);
return true;
}
private void setupSearchView(MenuItem searchItem) {
// TODO Auto-generated method stub
mSearchView.setOnQueryTextListener(this);
}
@Override
public boolean onQueryTextSubmit(String query) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
// TODO Auto-generated method stub
adaptador.getFilter().filter(newText);
return false;
}
CategoriesArrayAdapter.java
public class CategoriaArrayAdapter extends ArrayAdapter<Categoria> implements Filterable {
List<Categoria> original;
List<Categoria> filtered;
public CategoriaArrayAdapter(Context context, List<Categoria> objects) {
super(context, 0, objects);
this.original = objects;
}
@Override
public View getView(int position, View convertView, ViewGroup parent){
//Obteniendo una instancia del inflater
LayoutInflater inflater = (LayoutInflater)getContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//Salvando la referencia del View de la fila
View listItemView = convertView;
//Comprobando si el View no existe
if (null == convertView) {
//Si no existe, entonces inflarlo con cat_list_view.xml
listItemView = inflater.inflate(
R.layout.cat_list_item,
parent,
false);
}
//Obteniendo instancias de los elementos
TextView titulo = (TextView)listItemView.findViewById(R.id.txtCat);
TextView cantidad = (TextView)listItemView.findViewById(R.id.txtCantcat);
//Obteniendo instancia de la Tarea en la posición actual
Categoria item = getItem(position);
titulo.setText(item.getTitulo());
cantidad.setText("("+item.getCantidad()+")");
return listItemView;
}
@Override
public Filter getFilter() {
Filter filter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
//constraint is the result from text you want to filter against.
//objects is your data set you will filter from
if(constraint != null && original !=null) {
int length= original.size();
filtered.clear();
for (int i = 0; i<length; i++){
Locale locale = Locale.getDefault();
Categoria item = original.get(i);
String data = item.getTitulo();
if (data.toLowerCase(locale).contains(constraint.toString())) {
filtered.add(item);
}
}
filterResults.values = filtered;
filterResults.count = filtered.size();
}else{
filterResults.count = original.size();
filterResults.values = original;
}
return filterResults;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
original = (List<Categoria>) results.values;
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
return filter;
}
}
我是不是漏了什么???我真的需要帮助...
基于这个答案 -> Custom filtering in Android using ArrayAdapter ,这是我的解决方案:
@Override
public Filter getFilter() {
if (filter == null) {
filter = new ArrayFilter();
}
return filter;
}
private class ArrayFilter extends Filter{
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if(constraint != null && constraint.length()> 0) {
ArrayList<Categoria> values = new ArrayList<Categoria>(original);
filtered = new ArrayList<Categoria>();
int length = values.size();
for (int i = 0; i<length; i++) {
Locale locale = Locale.getDefault();
Categoria item = values.get(i);
String data = item.getTitulo();
if (data.toLowerCase(locale).contains(constraint.toString())) {
filtered.add(item);
}
}
filterResults.values = filtered;
filterResults.count = filtered.size();
}else{
synchronized(this) {
filterResults.count = original.size();
filterResults.values = original;
}
}
return filterResults;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
data = (List<Categoria>) results.values;
notifyDataSetChanged();
clear();
addAll(data);
notifyDataSetInvalidated();
}
}
}