programacion - Adaptador de vista de lista personalizado con filtro Android
listview dinamico android studio (7)
Espero que sea útil para otros.
// put below code (method) in Adapter class
public void filter(String charText) {
charText = charText.toLowerCase(Locale.getDefault());
myList.clear();
if (charText.length() == 0) {
myList.addAll(arraylist);
}
else
{
for (MyBean wp : arraylist) {
if (wp.getName().toLowerCase(Locale.getDefault()).contains(charText)) {
myList.add(wp);
}
}
}
notifyDataSetChanged();
}
declarar a continuación el código en la clase de adaptador
private ArrayList<MyBean> myList; // for loading main list
private ArrayList<MyBean> arraylist=null; // for loading filter data
debajo del código en el adaptador Constructor
this.arraylist = new ArrayList<MyBean>();
this.arraylist.addAll(myList);
y debajo del código en su clase de actividad
final EditText searchET = (EditText)findViewById(R.id.search_et);
// Capture Text in EditText
searchET.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable arg0) {
// TODO Auto-generated method stub
String text = searchET.getText().toString().toLowerCase(Locale.getDefault());
adapter.filter(text);
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) {
// TODO Auto-generated method stub
}
});
Estoy intentando implementar un filtro en mi lista de lista. Pero cada vez que el texto cambia, la lista desaparece. Ayuda Aquí están mis códigos. La clase de adaptador.
package com.talagbe.schymn;
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.TextView;
public class HymnsAdapter extends ArrayAdapter<Hymns> {
ArrayList<Hymns> hymnarray;
Context context;
LayoutInflater inflater;
int Resource;
public HymnsAdapter(Context context, int resource, ArrayList<Hymns> objects) {
super(context, resource, objects);
// TODO Auto-generated constructor stub
hymnarray=objects;
Resource= resource;
this.context=context;
inflater= (LayoutInflater) context.getSystemService(context.LAYOUT_INFLATER_SERVICE);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
ViewHolder holder;
if(convertView==null){
convertView= inflater.inflate(Resource,null);
holder= new ViewHolder();
holder.hymntitle= (TextView) convertView.findViewById(R.id.Hymn_title);
// holder.hymntext= (TextView) convertView.findViewById(R.id.Channel_name);
convertView.setTag(holder);
}else{
holder=(ViewHolder)convertView.getTag();
}
holder.hymntitle.setText(hymnarray.get(position).getTitle());
//holder.hymntext.setText(hymnarray.get(position).getText());
return convertView;
}
static class ViewHolder{
public TextView hymntitle;
public TextView hymntext;
}
}
Aquí está la otra clase donde intento implementar el filtro. Tengo un edittext, donde lo implemento en textChangeListener
package com.talagbe.schymn;
import java.util.ArrayList;
import database.DatabaseHelper;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.widget.AdapterView.OnItemClickListener;
public class Home extends Fragment {
private static final String DB_NAME = "schymn.sqlite";
private static final String TABLE_NAME = "Hymns";
private static final String Hymn_ID = "_id";
private static final String Hymn_Title = "Title";
private static final String Hymn_Text = "Text";
private SQLiteDatabase database;
ListView list;
EditText search;
HymnsAdapter vadapter;
ArrayList<Hymns> HymnsList;
String url;
Context context=null;
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.index, container,false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
list = (ListView)getActivity().findViewById(R.id.hymn_list);
search = (EditText) getActivity().findViewById(R.id.search);
HymnsList = new ArrayList<Hymns>();
DatabaseHelper dbOpenHelper = new DatabaseHelper(getActivity(), DB_NAME);
database = dbOpenHelper.openDataBase();
fillHymns();
//setUpList();
}
private void fillHymns() {
Cursor hymnCursor = database.query(TABLE_NAME,
new String[]
{Hymn_ID, Hymn_Title,Hymn_Text},
null, null, null, null
, Hymn_Title);
hymnCursor.moveToFirst();
if(!hymnCursor.isAfterLast()) {
do {
Hymns hy = new Hymns();
hy.setTitle(hymnCursor.getString(1));
hy.setText(hymnCursor.getString(2));
HymnsList.add(hy);
} while (hymnCursor.moveToNext());
}
hymnCursor.close();
vadapter = new HymnsAdapter(getActivity().getApplicationContext(),R.layout.hymns,HymnsList);
list.setAdapter(vadapter);
list.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent intent = new Intent(getActivity().getApplicationContext(), Hymn_Text.class);
intent.putExtra("Title",HymnsList.get(position).getTitle());
intent.putExtra("Text",HymnsList.get(position).getText());
startActivity(intent);
//Log.i("Text",HymnsList.get(position).getText());
}
});
search.addTextChangedListener( new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int start, int before, int count) {
// TODO Auto-generated method stub
if(count>0){
}
}
@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
Home.this.vadapter.getFilter().filter(s);
Log.i("Changed",s.toString());
}
});
}
}
El registro, registra cualquier entrada que escriba, pero no muestra la vista de lista. Gracias
Primero, crea EditText en el archivo xml y asigna una identificación, por ejemplo, con_pag_etPesquisa. Después de eso, crearemos dos listas, donde una es la vista de lista y la otra para recibir el mismo contenido, pero se mantendrá como una copia de seguridad. Antes de mover objetos a las listas, primero los inicializa a continuación:
//Declaring
public EditText etPesquisa;
public ContasPagarAdapter adapterNormal;
public List<ContasPagar> lstBkp;
public List<ContasPagar> lstCp;
//Within the onCreate method, type the following:
etPesquisa = (EditText) findViewById(R.id.con_pag_etPesquisa);
etPesquisa.addTextChangedListener(new TextWatcher(){
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3){
filter(String.valueOf(cs));
}
@Override
public void beforeTextChanged(CharSequence cs, int arg1, int arg2, int arg3){
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable e){
}
});
//Before moving objects to lists first initializes them as below:
lstCp = new ArrayList<ContasPagar>();
lstBkp = new ArrayList<ContasPagar>();
//When you add objects to the main list, repeat the procedure also for bkp list, as follows:
lstCp.add(cp);
lstBkp.add(cp);
//Now initializes the adapter and let the listener, as follows:
adapterNormal = new ContasPagarAdapter(ContasPagarActivity.this, lstCp);
lvContasPagar.setAdapter(adapterNormal);
lvContasPagar.setOnItemClickListener(verificaClickItemContasPagar(lstCp));
//Now create the methods inside actito filter the text entered by the user, as follows:
public void filter(String charText){
charText = charText.toLowerCase();
lstCp.clear();
if (charText.length() == 0){
lstCp.addAll(lstBkp);
appendAddItem(lstBkp);
}
else {
for (int i = 0; i < lstBkp.size(); i++){
if((lstBkp.get(i).getNome_lancamento() + " - " + String.valueOf(lstBkp.get(i).getCodigo())).toLowerCase().contains(charText)){
lstCp.add(lstBkp.get(i));
}
}
appendAddItem(lstCp);
}
}
private void appendAddItem(final List<ContasPagar> novaLista){
runOnUiThread(new Runnable(){
@Override
public void run(){
adapterNormal.notifyDataSetChanged();
}
});
}
Puede implementar el filtro de búsqueda en la vista de lista de dos maneras. 1. usando searchview 2. usando edittext.
Si quieres usar searchview, lee aquí: searchview filter.
Si desea usar edittext, lea a continuación.
Me he tomado como referencia de: listview search filter android
Fragmentos de código para hacer filtro con edittext.
Primero crea la clase de modelo MovieNames.java:
public class MovieNames {
private String movieName;
public MovieNames(String movieName) {
this.movieName = movieName;
}
public String getMovieName() {
return this.movieName;
}
}
Crear el archivo listview_item.xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp">
<TextView
android:id="@+id/name"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</RelativeLayout>
Hacer la clase ListViewAdapter.java:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.Locale;
public class ListViewAdapter extends BaseAdapter {
// Declare Variables
Context mContext;
LayoutInflater inflater;
private ArrayList<MovieNames> arraylist;
public ListViewAdapter(Context context, ArrayList<MovieNames> arraylist) {
mContext = context;
inflater = LayoutInflater.from(mContext);
this.arraylist = arraylist;
}
public class ViewHolder {
TextView name;
}
@Override
public int getCount() {
return arraylist.size();
}
@Override
public MovieNames getItem(int position) {
return arraylist.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
public View getView(final int position, View view, ViewGroup parent) {
final ViewHolder holder;
if (view == null) {
holder = new ViewHolder();
view = inflater.inflate(R.layout.listview_item, null);
// Locate the TextViews in listview_item.xml
holder.name = (TextView) view.findViewById(R.id.name);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
// Set the results into TextViews
holder.name.setText(arraylist.get(position).getMovieName());
return view;
}
}
Prepare el archivo activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.example.parsaniahardik.searchedit.MainActivity"
android:orientation="vertical">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:hint="enter query"
android:singleLine="true">
<requestFocus/>
</EditText>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/listView"
android:divider="#694fea"
android:dividerHeight="1dp" />
</LinearLayout>
Finalmente haga la clase MainActivity.java:
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Toast;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private EditText etsearch;
private ListView list;
private ListViewAdapter adapter;
private String[] moviewList;
public static ArrayList<MovieNames> movieNamesArrayList;
public static ArrayList<MovieNames> array_sort;
int textlength = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Generate sample data
moviewList = new String[]{"Xmen", "Titanic", "Captain America",
"Iron man", "Rocky", "Transporter", "Lord of the rings", "The jungle book",
"Tarzan","Cars","Shreck"};
list = (ListView) findViewById(R.id.listView);
movieNamesArrayList = new ArrayList<>();
array_sort = new ArrayList<>();
for (int i = 0; i < moviewList.length; i++) {
MovieNames movieNames = new MovieNames(moviewList[i]);
// Binds all strings into an array
movieNamesArrayList.add(movieNames);
array_sort.add(movieNames);
}
adapter = new ListViewAdapter(this,movieNamesArrayList);
list.setAdapter(adapter);
etsearch = (EditText) findViewById(R.id.editText);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Toast.makeText(MainActivity.this, array_sort.get(position).getMovieName(), Toast.LENGTH_SHORT).show();
}
});
etsearch.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
textlength = etsearch.getText().length();
array_sort.clear();
for (int i = 0; i < movieNamesArrayList.size(); i++) {
if (textlength <= movieNamesArrayList.get(i).getMovieName().length()) {
Log.d("ertyyy",movieNamesArrayList.get(i).getMovieName().toLowerCase().trim());
if (movieNamesArrayList.get(i).getMovieName().toLowerCase().trim().contains(
etsearch.getText().toString().toLowerCase().trim())) {
array_sort.add(movieNamesArrayList.get(i));
}
}
}
adapter = new ListViewAdapter(MainActivity.this, array_sort);
list.setAdapter(adapter);
}
});
}
}
Puede usar la interfaz filtrable en su adaptador, vea un buen ejemplo a continuación:
fuente original y Vea otro ejemplo here
public class SearchableAdapter extends BaseAdapter implements Filterable {
private List<String>originalData = null;
private List<String>filteredData = null;
private LayoutInflater mInflater;
private ItemFilter mFilter = new ItemFilter();
public SearchableAdapter(Context context, List<String> data) {
this.filteredData = data ;
this.originalData = data ;
mInflater = LayoutInflater.from(context);
}
public int getCount() {
return filteredData.size();
}
public Object getItem(int position) {
return filteredData.get(position);
}
public long getItemId(int position) {
return position;
}
public View getView(int position, View convertView, ViewGroup parent) {
// A ViewHolder keeps references to children views to avoid unnecessary calls
// to findViewById() on each row.
ViewHolder holder;
// When convertView is not null, we can reuse it directly, there is no need
// to reinflate it. We only inflate a new View when the convertView supplied
// by ListView is null.
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_item, null);
// Creates a ViewHolder and store references to the two children views
// we want to bind data to.
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.list_view);
// Bind the data efficiently with the holder.
convertView.setTag(holder);
} else {
// Get the ViewHolder back to get fast access to the TextView
// and the ImageView.
holder = (ViewHolder) convertView.getTag();
}
// If weren''t re-ordering this you could rely on what you set last time
holder.text.setText(filteredData.get(position));
return convertView;
}
static class ViewHolder {
TextView text;
}
public Filter getFilter() {
return mFilter;
}
private class ItemFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<String> list = originalData;
int count = list.size();
final ArrayList<String> nlist = new ArrayList<String>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
filterableString = list.get(i);
if (filterableString.toLowerCase().contains(filterString)) {
nlist.add(filterableString);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredData = (ArrayList<String>) results.values;
notifyDataSetChanged();
}
}
}
//in your Activity or Fragment where of Adapter is instantiated :
editTxt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
System.out.println("Text ["+s+"]");
mSearchableAdapter.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Una cosa que noté es que cada vez que editas la lista (agregando elementos, por ejemplo) y @Override getView
por ella, dentro del método @Override getView
, no debes usar @Override getView
filteredData.get(position)
, ya que arroja una excepción de IndexOutOfBounds
.
En cambio, lo que funcionó para mí fue el método getItem(position)
, que pertenece a la clase ArrayAdapter
.
por favor revisa el código a continuación, te ayudará
DrawerActivity.userListview
.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
int pos = position;
Intent intent = new Intent(getContext(),
UserDetail.class);
intent.putExtra("model", list.get(position));
context.startActivity(intent);
}
});
return convertView;
}
@Override
public android.widget.Filter getFilter() {
return new android.widget.Filter() {
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
ArrayList<UserListModel> updatelist = (ArrayList<UserListModel>) results.values;
UserListCustomAdaptor newadaptor = new UserListCustomAdaptor(
getContext(), getCount(), updatelist);
if (results.equals(constraint)) {
updatelist.add(modelobj);
}
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
list = new ArrayList<UserListModel>();
if (constraint != null && DrawerActivity.userlist != null) {
constraint = constraint.toString().toLowerCase();
int length = DrawerActivity.userlist.size();
int i = 0;
while (i < length) {
UserListModel modelobj = DrawerActivity.userlist.get(i);
String data = modelobj.getFirstName() + " "
+ modelobj.getLastName();
if (data.toLowerCase().contains(constraint.toString())) {
list.add(modelobj);
}
i++;
}
filterResults.values = list;
filterResults.count = list.size();
}
return filterResults;
}
};
}
@Override
public int getCount() {
return list.size();
}
@Override
public UserListModel getItem(int position) {
return list.get(position);
}
puede encontrar una clase de adaptador de lista personalizada con filtros modificables mediante el cambio de texto en el texto de edición ...
crear una clase de adaptador de lista personalizada con la implementación de Filterable:
private class CustomListAdapter extends BaseAdapter implements Filterable{
private LayoutInflater inflater;
private ViewHolder holder;
private ItemFilter mFilter = new ItemFilter();
public CustomListAdapter(List<YourCustomData> newlist) {
filteredData = newlist;
}
@Override
public int getCount() {
return filteredData.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
holder = new ViewHolder();
if(inflater==null)
inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(convertView == null){
convertView = inflater.inflate(R.layout.row_listview_item, null);
holder.mTextView = (TextView)convertView.findViewById(R.id.row_listview_member_tv);
convertView.setTag(holder);
}else{
holder = (ViewHolder)convertView.getTag();
}
holder.mTextView.setText(""+filteredData.get(position).getYourdata());
return convertView;
}
@Override
public Filter getFilter() {
return mFilter;
}
}
class ViewHolder{
TextView mTextView;
}
private class ItemFilter extends Filter {
@SuppressLint("DefaultLocale")
@Override
protected FilterResults performFiltering(CharSequence constraint) {
String filterString = constraint.toString().toLowerCase();
FilterResults results = new FilterResults();
final List<YourCustomData> list = YourObject.getYourDataList();
int count = list.size();
final ArrayList<YourCustomData> nlist = new ArrayList<YourCustomData>(count);
String filterableString ;
for (int i = 0; i < count; i++) {
filterableString = ""+list.get(i).getYourText();
if (filterableString.toLowerCase().contains(filterString)) {
YourCustomData mYourCustomData = list.get(i);
nlist.add(mYourCustomData);
}
}
results.values = nlist;
results.count = nlist.size();
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
filteredData = (ArrayList<YourCustomData>) results.values;
mCustomListAdapter.notifyDataSetChanged();
}
}
mEditTextSearch.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if(mCustomListAdapter!=null)
mCustomListAdapter.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});