2017-12-27 6 views
0

Ich bin ein Anfänger in Android-Programmierung und ich habe ein Problem, für das ich keine Lösung finden kann. Ich habe stackoverflow für Stunden gesucht, aber ich verstehe es immer noch nicht, wie soll ich das Zeug machen:Wie implementiert man Suchfunktion auf benutzerdefinierten ArrayAdapter mit Searchview?

Ich habe eine schlanke API mit PHP erstellt, die mit einem lokalen xampp mysql Server kommuniziert, und ich kann grundlegende CRUD-Operationen darauf ausführen . Ich bekomme die Daten mit der API vom Server, die alle "Elemente" in der Datenbank zu einer Liste zurückgibt, und ich kann dies in einer ListView verwenden. Jedes Listenelement hat 6 TextViews, also habe ich einen benutzerdefinierten ArrayAdapter erstellt, aber ich weiß nicht, ob ich nach bestimmten Listenelementen suchen soll.

My Item-Klasse:

public class Item { 

     private String mName; 
     private String mQuantity; 
     private String mDate_added; 
     private String mBarcode; 
     private String mPrice; 
     private String mWarranty; 
     private int mId; 

     public Item(String mName, String mQuantity, String mDate_added, String mBarcode, String mPrice, String mWarranty,int mId) { 
      this.mName = mName; 
      this.mQuantity = mQuantity; 
      this.mDate_added = mDate_added; 
      this.mBarcode = mBarcode; 
      this.mPrice = mPrice; 
      this.mWarranty = mWarranty; 
      this.mId = mId; 
     } 

     public int getmId(){return mId; } 

     public String getmName() { 
      return mName; 
     } 

     public String getmQuantity() { 
      return mQuantity; 
     } 

     public String getmDate_added() { 
      return mDate_added; 
     } 

     public String getmBarcode() { 
      return mBarcode; 
     } 

     public String getmPrice() { 
      return mPrice; 
     } 

     public String getmWarranty() { 
      return mWarranty; 
     } 
    } 

Mein Adapter

public class ItemAdapter extends ArrayAdapter<Item> { 


    public ItemAdapter(Context context, ArrayList<Item> items) { 
     super(context,0, items); 

    } 


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

     View ListItemView= convertView; 
     if (ListItemView == null) { 



      ListItemView = LayoutInflater.from(getContext()).inflate(R.layout.list_item,parent,false); 

      Item currentItem = getItem(position); 


      TextView nameText = (TextView) ListItemView.findViewById(R.id.name); 
      TextView quantityText = (TextView) ListItemView.findViewById(R.id.quantity); 
      TextView date_addedText = (TextView) ListItemView.findViewById(R.id.date_added); 
      TextView barcodeText = (TextView) ListItemView.findViewById(R.id.barcode); 
      TextView priceText = (TextView) ListItemView.findViewById(R.id.price); 
      TextView warrantyText = (TextView) ListItemView.findViewById(R.id.warranty); 


      nameText.setText(currentItem.getmName()); 
      quantityText.setText(currentItem.getmQuantity() +" e"); 
      date_addedText.setText(currentItem.getmDate_added()); 
      barcodeText.setText(currentItem.getmBarcode()); 
      priceText.setText(currentItem.getmPrice()+ " pr/e"); 
      warrantyText.setText(currentItem.getmWarranty()); 

     } 

     return ListItemView; 
    } 

} 

ich die Daten mit HttpURLConnection get-Methode, und ich verwende eine AsyncTaskLoader dafür. Dies gibt die Daten von einer gegebenen URL an eine Liste zurück.

public class ItemLoader extends AsyncTaskLoader<List<Item>> { 

    private String mUrl; 

    public ItemLoader(Context context, String url) { 
     super(context); 
     mUrl = url; 
    } 


    @Override 
    protected void onStartLoading() { 



     forceLoad(); 
    } 



    @Override 
    public List<Item> loadInBackground() { 


     if (mUrl == null) { 
      return null; 
     } 

     // Perform the network request, parse the response, and extract a list of items. 
     List<Item> items = QueryUtils.fetchItemData(mUrl); 
     return items; 
    } 

} 

Als nächstes, In meiner Haupttätigkeit implementiere ich loader Rückrufe.

private ItemAdapter mAdapter; 

    @Override 
     public android.content.Loader<List<Item>> onCreateLoader(int i, Bundle bundle) { 

      return new ItemLoader(this,API_REQUEST_URL); 
     } 


    @Override 
     public void onLoadFinished(android.content.Loader<List<Item>> loader, List<Item> items) { 
      mAdapter.clear(); 

      if (items != null && !items.isEmpty()) { 


       mAdapter.addAll(items); 
      } 

     } 

@Override 
    public void onLoaderReset(android.content.Loader<List<Item>> loader) { 
     Log.e("init loader","Log"); 

     mAdapter.clear(); 
    } 

In onCreate

android.app.LoaderManager loaderManager = getLoaderManager(); 
      loaderManager.initLoader(0, null, MainActivity.this); 

listView.setAdapter(mAdapter); 

Ich mag für die Namen der Elemente suchen, und zurück in der Listview des entsprechend. Ich habe eine Suche für sie mit einem setOnQueryTextListener:

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

     SearchManager manager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); 
     SearchView search = (SearchView) menu.findItem(R.id.search).getActionView(); 
     search.setSearchableInfo(manager.getSearchableInfo(getComponentName())); 

     search.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 

      @Override 
      public boolean onQueryTextSubmit(String s) { 


       return false; 
      } 

      @Override 
      public boolean onQueryTextChange(String s) { 

       return false; 
      } 

     }); 

     return true; 
    } 

aaand ... jetzt bin ich irgendwie stecken. Ich weiß, ich sollte "Filterable" auf der Adapter-Klasse implementieren, einige Methoden überschreiben, einen Filter erstellen, usw., und es ist nicht so schwer, wenn ich eine hartcodierte Liste habe, die ich nur ändern muss, aber diese Netzwerkanforderungen, Hintergrundthreads, bekomme Daten vom Server Zeug verwirrt mich so sehr, ich weiß nicht, was zu tun ist.

Halp! : c

Antwort

0

Sie können die Methode getFilter() in Ihrem Adapter überschreiben und eine Implementierung von Filter zurückgeben, die Ihren Datensatz entsprechend der Eingabe filtert.

Und bei der Suche Rückruf können Sie

adapter.getFilter().filter(queryString); 

Here's an example

+0

Akzeptieren Sie die Antwort, wenn es geholfen hat – elmorabea

0

Es ist viel schwieriger das nicht nennen. Von Ihrem Code kann ich sagen, dass Sie Daten mit Loadern in Ihrer Aktivität erhalten. Und Loader stellt diese Daten dem Adapter zur Verfügung.

Aktivität -> Loader -> Abrufen von Daten -> Gehen Sie zur Adapter -> Anzeigen von Daten in der Liste

So, jetzt, wenn Sie filterbar implementieren möchten, können Sie implementieren und gefilterten Daten aus verfügbaren Liste. Wenn Sie alle Daten durchsuchen oder filtern, können Sie den Loader erneut aufrufen, um Daten von der Datenbank oder dem Webdienst abzurufen und dann Daten unter Verwendung neuer Daten im Adapter anzuzeigen.

Verwandte Themen