web-dev-qa-db-fra.com

GetFilter personnalisé dans ArrayAdapter personnalisé dans android

J'ai du mal à implémenter getFilter personnalisé dans arrayAdapter personnalisé. En fait, je ne sais pas comment le mettre en œuvre. J'ai essayé différents codes mais toujours pas de chance. Voici mon adaptateur de baie personnalisé.

package com.test.FilterableList.Adapters;

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;

import com.test.FilterableList.Models.ListTO;
import com.test.FilterableList.R;

import Android.widget.Filterable;


public class FilterableAdapter extends ArrayAdapter<ListTO> implements Filterable {

    // declaring our ArrayList of items
    public ArrayList<ListTO> objects;

    /* here we must override the constructor for ArrayAdapter
    * the only variable we care about now is ArrayList<Item> objects,
    * because it is the list of objects we want to display.
    */
    public FilterableAdapter(Context context, int textViewResourceId, ArrayList<ListTO> objects) {
        super(context, textViewResourceId, objects);
        this.objects = objects;
    }

    /*
     * we are overriding the getView method here - this is what defines how each
     * list item will look.
     */
    public View getView(int position, View convertView, ViewGroup parent){

        // assign the view we are converting to a local variable
        View v = convertView;

        // first check to see if the view is null. if so, we have to inflate it.
        // to inflate it basically means to render, or show, the view.
        if (v == null) {
            LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            v = inflater.inflate(R.layout.list_item, null);
        }

        /*
         * Recall that the variable position is sent in as an argument to this method.
         * The variable simply refers to the position of the current object in the list. (The ArrayAdapter
         * iterates through the list we sent it)
         *
         * Therefore, i refers to the current Item object.
         */
        ListTO i = objects.get(position);

        if (i != null) {

            // This is how you obtain a reference to the TextViews.
            // These TextViews are created in the XML files we defined.

            TextView tt = (TextView) v.findViewById(R.id.list_name);
            if (tt != null){
                tt.setText(i.FileName);
            }



        }

        // the view must be returned to our activity
        return v;

    }
}

Et voici la classe ListTO.

package com.test.FilterableList.Models;

public class ListTO {

    public int Id;
    public String FileName;
    public String FileUri;

    public ListTO(int id, String fileName, String fileUri) {

        Id = id;
        FileName = fileName;
        FileUri = fileUri;

    }

}

Et voici la mise en page.

<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:orientation="vertical"
    Android:background="@drawable/blacklikenbackground"
    tools:context=".AllListActivity" >

    <EditText
        Android:layout_width="fill_parent"
        Android:layout_height="wrap_content"
        Android:text="Search"
        Android:id="@+id/inputSearch"
        />


    <ListView
        Android:id="@+id/test_list"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content">
    </ListView>

</LinearLayout>

Ici, le mot-clé de recherche provient de "inputSearch" EditText.

Voici l'auditeur de texte modifié.

 inputSearch.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
                        // When user changed the Text
                      //  Toast.makeText(getActivity(), cs.toString(), Toast.LENGTH_LONG).show();
                        m_adapter.getFilter().filter(cs);
                    }

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

                    }

                    @Override
                    public void afterTextChanged(Editable arg0) {
                        // TODO Auto-generated method stub
                    }
                });

Merci.

37
Redone

Vous rencontrez des problèmes, principalement parce que vous utilisez un objet personnalisé. Si vous transmettez une valeur String ou int à l'adaptateur de tableaux, son savoir comment la filtrer. Mais si vous passez l'implémentation de filtre par défaut d'objet personnalisé, vous n'avez aucune idée de comment gérer cela.

Bien qu'il ne soit pas clair ce que vous essayez de faire dans votre filtre, je vous recommande de suivre les étapes.

  1. Implémentation correcte de ListTO, même si cela n'a rien à voir avec votre objectif pour le moment
  2. Implémenter un filtre personnalisé
  3. retournez votre filtre

Implémenter un filtre personnalisé

La première chose que vous devez faire est, implementsFilterable depuis votre adaptateur de baie.

Deuxièmement, fournissez l'implémentation de votre Filter

Filter myFilter = new Filter() {
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
         FilterResults filterResults = new FilterResults();   
         ArrayList<ListTO> tempList=new ArrayList<ListTO>();
         //constraint is the result from text you want to filter against. 
         //objects is your data set you will filter from
         if(constraint != null && objects!=null) {
             int length=objects.size();
             int i=0;
                while(i<length){
                    ListTO item=objects.get(i);
                    //do whatever you wanna do here
                    //adding result set output array     

                    tempList.add(item);

                    i++;
                }
                //following two lines is very important
                //as publish result can only take FilterResults objects
                filterResults.values = tempList;
                filterResults.count = tempList.size();
          }
          return filterResults;
      }

      @SuppressWarnings("unchecked")
      @Override
      protected void publishResults(CharSequence contraint, FilterResults results) {
          objects = (ArrayList<ListTO>) results.values;
          if (results.count > 0) {
           notifyDataSetChanged();
          } else {
              notifyDataSetInvalidated();
          }  
      }
     };

Dernière étape,

@Override
     public Filter getFilter() {
        return myFilter;
    }
46
minhaz

Pas besoin d'écrire l'adaptateur de baie. écrire une méthode toString () qui devrait retourner la valeur du nom de fichier.

Comme

public class ListTO {

    public int Id;
    public String FileName;
    public String FileUri;

    public ListTO(int id, String fileName, String fileUri) {

        Id = id;
        FileName = fileName;
        FileUri = fileUri;

    }

    public String toString(){
        return FileName
    }

}
8
chandu tangudu

Vous devez remplacer la méthode getFilter() dans l'adaptateur et fournir votre propre filtre. Jetez un oeil dans ce exemple filtrable pour voir une implémentation réelle.

Ajoutez le code getFilter() suivant à votre classe FilterableAdapter et remplissez-le avec votre filtrage:

/* (non-Javadoc)
 * @see Android.widget.ArrayAdapter#getFilter()
 */
@Override
public Filter getFilter() {
    return new Filter() {

        /* (non-Javadoc)
         * @see Android.widget.Filter#performFiltering(Java.lang.CharSequence)
         */
        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            // TODO Auto-generated method stub
            /*
             * Here, you take the constraint and let it run against the array
             * You return the result in the object of FilterResults in a form
             * you can read later in publichResults.
             */
            return null;
        }

        /* (non-Javadoc)
         * @see Android.widget.Filter#publishResults(Java.lang.CharSequence, Android.widget.Filter.FilterResults)
         */
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {
            // TODO Auto-generated method stub
            /*
             * Here, you take the result, put it into Adapters array
             * and inform about the the change in data.
             */
        }

    };
}

J'ai ajouté des conseils que faire dans les commentaires.

8
jboi

essaye ça:

     public class Adptr extends BaseAdapter implements Filterable {
public ArrayList<Model> modelValues;

private Activity activity;
private LayoutInflater layoutinflater;
private List<Model> mOriginalValues;
private int PositionSelected = 0;

public Adptr (ArrayList<Model> modelValues, Activity activity) {
    super();
    this.modelValues = modelValues;
    this.activity = activity;


}

@Override
public int getCount() {

    return modelValues.size();
}

@Override
public Object getItem(int position) {

    return modelValues.get(position);
}

@Override
public long getItemId(int position) {

    return position;
}


@Override
public View getView(final int position, View convertView, ViewGroup parent) {

    layoutinflater = (LayoutInflater)  activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    ViewHolder holder = null;
    Model model = modelValues.get(position);

    if (convertView == null || !(convertView.getTag() instanceof ViewHolder)) {
        convertView = layoutinflater.inflate(R.layout.row_search, null);
        holder = new ViewHolder();
        holder.txtName = (TextView) convertView.findViewById(R.id.row_serch_txt_name);




        convertView.setTag(holder);
        convertView.setTag(R.id.row_serch_txt_name, holder.txtName);

    } else {
        holder = (ViewHolder) convertView.getTag();
    }

    holder.txtArtistName.setText("" + modelValue.get_NAME());




    return convertView;
}

class ViewHolder {
    TextView txtName;


}

@Override
public Filter getFilter() {

    Filter filter = new Filter() {

        @SuppressWarnings("unchecked")
        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            modelValues = (ArrayList<ModelValueArtist>) results.values; // has

            notifyDataSetChanged();
        }

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            FilterResults results = new FilterResults(); // Holds the
                                                            // results of a
                                                            // filtering
                                                            // operation in
                                                            // values
            // List<String> FilteredArrList = new ArrayList<String>();
            List<Model> FilteredArrList = new ArrayList<Model>();

            if (mOriginalValues == null) {
                mOriginalValues = new ArrayList<Model>(modelValues); // saves

            }

            /********
             * 
             * If constraint(CharSequence that is received) is null returns
             * the mOriginalValues(Original) values else does the Filtering
             * and returns FilteredArrList(Filtered)
             * 
             ********/
            if (constraint == null || constraint.length() == 0) {

                // set the Original result to return
                results.count = mOriginalValues.size();
                results.values = mOriginalValues;
            } else {
                Locale locale = Locale.getDefault();
                constraint = constraint.toString().toLowerCase(locale);
                for (int i = 0; i < mOriginalValues.size(); i++) {
                    Model model = mOriginalValues.get(i);

                    String data = model.get_NAME();
                    if (data.toLowerCase(locale).contains(constraint.toString())) {

                        FilteredArrList.add(modelMyMall);
                    }
                }
                // set the Filtered result to return
                results.count = FilteredArrList.size();
                results.values = FilteredArrList;

            }
            return results;
        }
    };
    return filter;
  }

     }
5
shivang Trivedi

Vous pouvez remplacer toString () dans votre classe d'objets personnalisée et renvoyer l'objet String que vous souhaitez filtrer.

@Override
public void toString(){
      return this.toBeFilteredString;
}

Et puis utilisez simplement le filtre intégré par défaut de arrayAdapter et appelez-le en utilisant

adapter.getFilter().filter(Charsequence c);
4
Nitesh Kumar

J'ai cherché pas mal de réponses sur SO pour obtenir tous les extraits nécessaires. Voici donc une version Kotlin d'un filtre personnalisé pour ma classe Registration. Celui-ci fonctionne réellement et tous les les informations dont vous avez besoin se trouvent dans ce code.

class RegistrationArrayAdapter(context: Context, private val layoutResId: Int, registrations: List<Registration>) :
    ArrayAdapter<Registration>(context, layoutResId, registrations) {

    private val filter = RegistrationFilter(registrations)

    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val registration = getItem(position)
        val view = convertView ?: LayoutInflater.from(context).inflate(layoutResId, null)
        (view as TextView).text = registration?.mainGuest?.name ?: ""
        return view
    }

    override fun getFilter() = filter

    inner class RegistrationFilter(private val originalList: List<Registration>) : Filter() {

        private val sourceObjects: ArrayList<Registration> = ArrayList()

        init {
            synchronized (this) {
                sourceObjects.addAll(originalList)
            }
        }

        override fun performFiltering(constraint: CharSequence?): FilterResults {
            if (constraint == null) return FilterResults()

            val result = FilterResults()

            if (constraint.isNotEmpty()) {
                val filteredList = ArrayList<Registration>()

                sourceObjects.filterTo(filteredList) { isWithinConstraint(it, constraint) }

                result.count = filteredList.size
                result.values = filteredList

            } else {
                synchronized(this) {
                    result.values = sourceObjects
                    result.count = sourceObjects.size
                }

            }
            return result
        }

        override fun publishResults(constraint: CharSequence?, results: FilterResults) {
            if (results.values == null) return

            @Suppress("UNCHECKED_CAST")
            val filtered = results.values as ArrayList<Registration>

            if (results.count > 0) {
                clear()
                addAll(filtered)
                notifyDataSetChanged()
            } else {
                notifyDataSetInvalidated()
            }

        }


        override fun convertResultToString(resultValue: Any?): CharSequence {
            return (resultValue as Registration).mainGuest.name
        }

        private fun isWithinConstraint(registration: Registration, constraint: CharSequence): Boolean {
            return registration.mainGuest.name.toLowerCase().contains(constraint, true)
        }

    }
}
0
muetzenflo