2015-08-11 13 views
5

Im new per lo sviluppo Android. Quello che voglio è cercare nella mia listview usando il widget searchview della barra delle azioni. Come posso implementare la funzionalità di ricerca. Quello che mi manca è la funzionalità di ricerca per questo. Ho visto alcune funzioni di ricerca ma è basato su editText. Per favore aiuto.Barra di azione Android Cerca con listview

Ecco il mio codice:

menu.xml

<item android:id="@+id/menu_search" 
      android:title="@string/menu_search" 
      android:icon="@android:drawable/ic_menu_search" 
      android:showAsAction="ifRoom|collapseActionView" 
      android:actionViewClass="android.widget.SearchView" /> 

Nel mio manifest.xml

<activity 
      android:name=".MainActivity" 
      <intent-filter> 
       <action android:name="android.intent.action.SEARCH" /> 
      </intent-filter> 
      <meta-data 
       android:name="android.app.searchable" 
       android:resource="@xml/searchable"> 
      </meta-data> 
     </activity> 

sul mio MainActivity.java

protected void onCreate(Bundle savedInstanceState) { 
      super.onCreate(savedInstanceState); 
      setContentView(R.layout.activity_main); 

       this.lv = (ListView) findViewById(R.id.listView); 

       this.databaseAccess = DatabaseAccess.getInstance(getApplicationContext()); 
       this.persons= getPersonList(); 

       Adapter adapter = new Adapter(this, persons); 
       this.lv.setAdapter(adapter); 
} 
    public List<Person> getPersonList(){ 
      databaseAccess.open(); 
      List<Person> person= databaseAccess.getPersons(); 
      databaseAccess.close(); 
      return person; 
     } 

private class Adapter extends ArrayAdapter<Person> { 

     public Adapter(Context context, List<Person> objects) { 
      super(context, 0, objects); 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      if (convertView == null) { 
       convertView = getLayoutInflater().inflate(R.layout.persons, parent, false); 
      } 

      TextView id = (TextView) convertView.findViewById(R.id.id); 
      TextView name= (TextView) convertView.findViewById(R.id.name); 
      TextView lastname = (TextView) convertView.findViewById(R.id.latname); 

      Person p = persons.get(position); 
      id.setText(p.getId()); 
      name.setText(p.getName()); 
      lastname.setText(p.getLastName()); 

      return convertView; 
     } 

risposta

3

È necessario implementare l'interfaccia Filterable nell'adattatore.

Poi gonfiare il menù:

@Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    MenuItem searchMenuItem = menu.findItem(R.id.menu_search); 
    if (searchMenuItem == null) { 
     return; 
    } 

    searchView = (SearchView) searchMenuItem.getActionView(); 
    if (searchView != null) { 
     searchView.setQueryHint(getString(R.string.search_hint)); 
     searchView.setMaxWidth(2129960); // https://stackoverflow.com/questions/18063103/searchview-in-optionsmenu-not-full-width 
     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
      @Override 
      public boolean onQueryTextSubmit(String s) { 
       return false; 
      } 

      @Override 
      public boolean onQueryTextChange(String s) { 
       SearchFragment.this.onQueryTextChange(s); 
       return false; 
      } 
     }); 
    } 
} 

E poi specificare il metodo, che ha gestito l'evento di modifica testo della query, qualcosa di simile:

void onQueryTextChange(String query) { 
    searchAdapter.getFilter().filter(query); 
} 

Più informazioni here

0

provare questo esempio. Sample search widget

+0

codice funziona, ma quando ho implementato sul mio codice, i risultati della ricerca non sono mostrando onTextChange() e onTextQuery(). Ritorna vuoto – Jah

1

avete usare il modello, listview e customadapter con filtri per questo. Ho creato una demo per questo, supponiamo che tu abbia un modello chiamato Product, e stai visualizzando il suo contenuto in un listview personalizzato dove nome, prezzo sono visualizzati in textview. Voglio dire in una riga personalizzata con due textview e vuoi filtrare l'elenco per uno dei campi della consuetudine row.here ho filtrato con "nome"

codice sorgente

// questo è il tuo modello

public class Product { 

    public String name; 
    public Integer price; 
    public Product(String name, Integer price) { 
     super(); 
     this.name = name; 
     this.price = price; 
    } 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 
    public Integer getPrice() { 
     return price; 
    } 
    public void setPrice(Integer price) { 
     this.price = price; 
    } 

} 

// questa è la tua attività con l'abitudine adattatore e listview

public class MainActivity extends Activity{ 
private LinearLayout llContainer; 
private EditText etSearch; 
private ListView lvProducts; 

private ArrayList<Product> mProductArrayList = new ArrayList<Product>(); 
private MyAdapter adapter1; 


@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 


    initialize(); 



    // Add Text Change Listener to EditText 
    etSearch.addTextChangedListener(new TextWatcher() { 

     @Override 
     public void onTextChanged(CharSequence s, int start, int before, int count) { 
      // Call back the Adapter with current character to Filter 
      adapter1.getFilter().filter(s.toString()); 
     } 

     @Override 
     public void beforeTextChanged(CharSequence s, int start, int count,int after) { 
     } 

     @Override 
     public void afterTextChanged(Editable s) { 
     } 
    }); 
} 

private void initialize() { 
    etSearch = (EditText) findViewById(R.id.etSearch); 
    lvProducts = (ListView)findViewById(R.id.lvOS); 
} 

@Override 
protected void onResume() { 
    // TODO Auto-generated method stub 
    super.onResume(); 

    mProductArrayList.add(new Product("a", 100)); 
    mProductArrayList.add(new Product("b", 200)); 
    mProductArrayList.add(new Product("c", 300)); 
    mProductArrayList.add(new Product("d", 400)); 
    mProductArrayList.add(new Product("e", 500)); 
    mProductArrayList.add(new Product("f", 600)); 
    mProductArrayList.add(new Product("g", 700)); 
    mProductArrayList.add(new Product("h", 800)); 
    mProductArrayList.add(new Product("i", 900)); 
    mProductArrayList.add(new Product("j", 1000)); 
    mProductArrayList.add(new Product("k", 1100)); 
    mProductArrayList.add(new Product("l", 1200)); 
    mProductArrayList.add(new Product("m", 1000)); 
    mProductArrayList.add(new Product("n", 1300)); 
    mProductArrayList.add(new Product("o", 1400)); 
    mProductArrayList.add(new Product("p", 1500)); 


    adapter1 = new MyAdapter(MainActivity.this, mProductArrayList); 
    lvProducts.setAdapter(adapter1); 
} 


// Adapter Class    
public class MyAdapter extends BaseAdapter implements Filterable { 

    private ArrayList<Product> mOriginalValues; // Original Values 
    private ArrayList<Product> mDisplayedValues; // Values to be displayed 
    LayoutInflater inflater; 

    public MyAdapter(Context context, ArrayList<Product> mProductArrayList) { 
     this.mOriginalValues = mProductArrayList; 
     this.mDisplayedValues = mProductArrayList; 
     inflater = LayoutInflater.from(context); 
    } 

    @Override 
    public int getCount() { 
     return mDisplayedValues.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     return position; 
    } 

    @Override 
    public long getItemId(int position) { 
     return position; 
    } 

    private class ViewHolder { 
     LinearLayout llContainer; 
     TextView tvName,tvPrice; 
    } 

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

     ViewHolder holder = null; 

     if (convertView == null) { 

      holder = new ViewHolder(); 
      convertView = inflater.inflate(R.layout.row, null); 
      holder.llContainer = (LinearLayout)convertView.findViewById(R.id.llContainer); 
      holder.tvName = (TextView) convertView.findViewById(R.id.tvName); 
      holder.tvPrice = (TextView) convertView.findViewById(R.id.tvPrice); 
      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 
     holder.tvName.setText(mDisplayedValues.get(position).name); 
     holder.tvPrice.setText(mDisplayedValues.get(position).price+""); 

     holder.llContainer.setOnClickListener(new OnClickListener() { 

      public void onClick(View v) { 

       Toast.makeText(MainActivity.this, mDisplayedValues.get(position).name, Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     return convertView; 
    } 

    @Override 
    public Filter getFilter() { 
     Filter filter = new Filter() { 

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

       mDisplayedValues = (ArrayList<Product>) results.values; // has the filtered values 
       notifyDataSetChanged(); // notifies the data with new filtered values 
      } 

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

       if (mOriginalValues == null) { 
        mOriginalValues = new ArrayList<Product>(mDisplayedValues); // saves the original data in mOriginalValues 
       } 

       /******** 
       * 
       * 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 { 
        constraint = constraint.toString().toLowerCase(); 
        for (int i = 0; i < mOriginalValues.size(); i++) { 
         String data = mOriginalValues.get(i).name; 
         if (data.toLowerCase().startsWith(constraint.toString())) { 
          FilteredArrList.add(new Product(mOriginalValues.get(i).name,mOriginalValues.get(i).price)); 
         } 
        } 
        // set the Filtered result to return 
         results.count = FilteredArrList.size(); 
         results.values = FilteredArrList; 
        } 
        return results; 
       } 
      }; 
      return filter; 
     } 
    } 
} 

// Questa è la vostra activity_main.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <EditText 
     android:id="@+id/etSearch" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"/> 

    <ListView 
     android:id="@+id/lvProducts" 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content"></ListView>  

</LinearLayout> 

// questa è la tua row.xml

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/llContainer" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="horizontal" > 

    <TextView 
     android:id="@+id/tvName" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:singleLine="true" 
     android:layout_weight="1"/> 

    <TextView 
     android:id="@+id/tvPrice" 
     android:layout_width="0dp" 
     android:layout_height="wrap_content" 
     android:singleLine="true" 
     android:layout_weight="1"/> 

</LinearLayout>