7

Ich möchte durch RecyclerView suchen, ich habe List<BaseOfCards> (BaseOfCards ist mein Getter & Setter-Klasse) Mein RecyclerViewAdapter:Suche durch RecyclerView Suche mit

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> { 


private LayoutInflater inflater; 
private List<BaseOfCards> items; 

//private int itemLayout; 
//String cardvalue; 
private Activity mActivity; 

public RecyclerViewAdapter(Activity mActivity, Context context, List<BaseOfCards> items) { 
    this.mActivity = mActivity; 
    inflater = LayoutInflater.from(context); 
    this.items = items; 
    //this.itemLayout = itemLayout; 
} 

@Override 
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 

    View view = inflater.inflate(R.layout.custom_row, parent, false); 
    MyViewHolder holder = new MyViewHolder(view, mActivity); 
    return holder; 
} 

@Override 
public void onBindViewHolder(MyViewHolder holder, int position) { 

    BaseOfCards item = items.get(position); 
    holder.title.setTag(item); 
    holder.title.setText(item.getCardName()); 
} 

@Override 
public int getItemCount() { 

    return items.size(); 
} 

public static class MyViewHolder extends RecyclerView.ViewHolder { 
    private Activity mActivity; 
    TextView title; 
    ImageView titileImageView; 

    public MyViewHolder(View itemView, Activity mActivity) { 

     super(itemView); 

     titileImageView = (ImageView) itemView.findViewById(R.id.image_country); 


     title = (TextView) itemView.findViewById(R.id.listText); 
     this.mActivity = mActivity; 

    } 
} 

} 

ich Suche meinem Menü hinzufügen und initialisieren es in MainActivity:

MenuItem menuItem = menu.findItem(R.id.action_search1); 
    searchView = (SearchView) MenuItemCompat.getActionView(menuItem); 
    SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 
    searchView.setIconifiedByDefault(true); 

Was muss ich als nächstes tun? Machen Sie meine RecyclerViewAdapterimplement Filterable oder was? Oder machen Sie einfach Klasse filter in * RecyclerViewAdapter ** und rufen Sie einfach von meinem MainActivity?

Antwort

19

löste ich mein Problem

  1. meiner Klasse Make RecyclerViewAdapterimplements Filterable

  2. Add Linie private List<BaseOfCards> orig;

  3. Add-Methode getFilter in RecyclerViewAdapter

    public Filter getFilter() { 
    return new Filter() { 
        @Override 
        protected FilterResults performFiltering(CharSequence constraint) { 
         final FilterResults oReturn = new FilterResults(); 
         final List<BaseOfCards> results = new ArrayList<BaseOfCards>(); 
         if (orig == null) 
          orig = items; 
          if (constraint != null){ 
           if(orig !=null & orig.size()>0){ 
            for (final BaseOfCards g :orig) { 
             if (g.getCardName().toLowerCase().contains(constraint.toString()))results.add(g); 
            } 
           } 
           oReturn.values = results; 
          } 
          return oReturn; 
         } 
    
    @Override 
        protected void publishResults(CharSequence constraint, FilterResults results) { 
         items = (ArrayList<BaseOfCards>)results.values; 
         notifyDataSetChanged(); 
    
        } 
    }; 
    
  4. Make MainActivityimplements SearchView.OnQueryTextListener und Änderungsmethode onQueryTextChange:

    @Override 
    public boolean onQueryTextChange(String newText) { 
        if (TextUtils.isEmpty (newText)) { 
         adapter.getFilter().filter(""); 
        } else { 
         adapter.getFilter().filter(newText.toString()); 
        } 
        return true; 
    } 
    
+0

Cool, ich werde diese Funktionalität mit dieser Methode ('getFilter') in meinem https://github.com/davideas/FlexibleAdapter hinzufügen ;-) – Davidea

+0

@Davidea oh, es ist großartig, vielen Dank! – Ololoking

+0

Ich fügte diese Funktionalität hinzu, aber es war komplizierter als vorgesehen. Tatsächlich bin ich jetzt nicht davon überzeugt, diesen Filter im Adapter zu haben, denn die Objekte im Adapter sind ** bereits ** eine Kopie von etwas Originellem, das aus einer Quelle wie DB/XML/JSON im Speicher als Domänenobjekt kommt - Das Problem ist nicht der Filter, sondern der add/del/mod, den Sie auf einer ** gefilterten ** Liste durchführen: Alle Änderungen sollten sich auch in der "ursprünglichen" Adapterliste widerspiegeln ** UND ** in der ursprünglichen Quelle ... At Dieser Punkt ist praktischer, um eine gefilterte Kopierliste direkt vom Quell- und Update-Adapter mit dieser Liste zu haben. – Davidea

0

Verwenden eines autocompletetextview oder eine EditText i behandelt diese ein, wie folgend in dem

public List<SalesProductsItems> mItems   

die anfängliche listitem ist Instanz und.

public static List<SalesProductsItems> filteredIt 

ist die Instanz bei der Anzeige items.Since die erste Zeit null die Filterergebnisse die mItems Instanz nicht wird gleich die filteredIt Instanz verwendet (also die erste Liste zu verlieren), dann auf der publishResults Methode direkt vor mItems verliert die ursprünglichen Werte, ich setze es mit der übergebenen Instanz originallist gleich. Hoffe, dass es jemand

private static class ProductsFilter extends Filter { 

    private final SalesProductsAdapter adapter; 

    private final List<SalesProductsItems> originalList; 

    private final List<SalesProductsItems> filteredList; 

    private ProductsFilter(SalesProductsAdapter adapter, List<SalesProductsItems> originalList) { 
     super(); 
     this.adapter = adapter; 
     this.originalList = new LinkedList<>(originalList); 
     this.filteredList = new ArrayList<>(); 
    } 

    @Override 
    protected FilterResults performFiltering(CharSequence constraint) { 
     filteredList.clear(); 
     final FilterResults results = new FilterResults(); 

     if (constraint == null || constraint.length() == 0) 
      filteredList.addAll(originalList); 
     else { 
      final String filterPattern = constraint.toString().toLowerCase().trim(); 

      for (final SalesProductsItems it : originalList) { 

       if (it.getProduct().toLowerCase().contains(filterPattern)) { 
        filteredList.add(it); 
       } 
      } 
     } 

     results.values = filteredList; 
     results.count = filteredList.size(); 
     return results; 
    } 

    @Override 
    protected void publishResults(CharSequence constraint, FilterResults results) { 
     adapter.mItems = originalList; 
     if(results.count > 0) { 
      filteredIt.clear(); 
      filteredIt.addAll((ArrayList<SalesProductsItems>) results.values); 
      adapter.notifyDataSetChanged(); 
     } else { 
      filteredIt.clear(); 
      filteredIt.addAll(adapter.mItems); 
      adapter.notifyDataSetChanged(); 
     } 
    } 
} 
0

hilft ich ololoking Antwort hinzufügen möchten. In MainActivity sollten wir auch im nächsten Code hinzufügen, damit es funktionieren würde:

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.menu_layout, menu); 

    MenuItem searchItem = menu.findItem(R.id.action_search); 
    SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem); 
    SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 
    searchView.setIconifiedByDefault(true); 
    searchView.setOnQueryTextListener(this); 
    return super.onCreateOptionsMenu(menu); 

} 

Vielen Dank für Ihre Antwort ololoking. Es hat mir geholfen.

0

Von der Zeit wurde die andere positive Antwort getan habe implementiert ich jetzt einen schnell Asynchron-FilterAsyncTask in meiner FlexibleAdapter Bibliothek verwendet, ist Leistung sehr gut mit großen Listen, auch Animationen mit! Der Adapter ist konfigurierbar, um Eigenschaften im Filterergebnis zu aktivieren/deaktivieren, um die Geschwindigkeit bei Bedarf zu erhöhen. Ein weiterer großer Vorteil ist auch, dass die Schnittstelle immer noch auf den Benutzer reagiert.

Test in meinem Samsung S3 mit Android 6: mit einer Startliste von 10.450 Elementen, von dem Moment an den Hintergrundprozess dauert es ~ 1s, einen Charakter zu filtern und 3.890 Elemente auszuwählen.

Ich habe auch eine Wiki page mit allen Details zu Filter mit dem Adapter zu verwenden.

+0

Ich bin Haben Sie das gleiche Problem, haben Sie dieses Problem gelöst.Bitte helfen Sie mir @Davidea –

+0

@SagarHudge, von der Zeit meines letzten Kommentars auf die angenommene Antwort, mein Filter geändert, der aktuelle Weg zum Filtern ist in der Wiki-Seite beschrieben. Platz um es besser und ähnlicher mit Filter Klasse zu machen gibt es, aber jetzt ist das mit FlexAdapter so. – Davidea