2016-09-16 7 views
1

переведена с использованием «google translate»!Android. Поиск и фильтрация в RecyclerView

Кратко о проблеме. Я решил попробовать использовать RecyclerView. Готовые решения, такие как search listView, не нужно реализовывать все. Поэтому я нашел решение, если оно необходимо в нижней части исходного кода, но есть проблема. Существует список, он отображает заголовки, когда вы нажимаете на любой элемент во втором повороте Activiti, который уже имеет заголовок и полное описание. понял, что я люблю: В MainActivity загружает из базы данных (с использованием сахаром ОРМА) заголовков и идентификатора

ArrayList<String> arrTitle = new ArrayList<>(); 
for(Contact contact:allContacts){ 
arrTitle.add(contact.title); 
} 

ArrayList<String> arrId = new ArrayList<>(); 
for(Contact contact:allContacts){ 
long i = contact.getId(); 
String str = Long.toString(i); 
arrId.add(str); 
} 

Тогда передать их к адаптеру

mAdapter = new RecyclerAdapter(arrTitle, arrId); 

Адаптер Ресайклер адаптера я получаю значение выводит, заголовок в списке, а второй ПАРОЛЯ активность

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

// Convert the id to the array 
idTab = new String[mId.size()]; 
for (int i = 0; i != mId.size(); i++) { 
    idTab[i] = mId.get(i); 
} 

// Element position 
final int idvadaptere = position; 
// Display headers RecyclerView 
holder.mTextView.setText(mDataset.get(position)); 

holder.itemView.setOnClickListener(new View.OnClickListener() { 
    @Override 
    public void onClick(View v) { 
     Context context = v.getContext(); 
     Intent ddddd = new Intent(context, LastActivity.class); 
     ddddd.putExtra("id", idTab[idvadaptere]); 
     context.startActivity(ddddd); 
    } 
}); 
} 

Во втором Activiti LastActivity я получить идентификатор и на б ASIS этого идентификатора уже выводить значения в текстовом поле

// Get the Intent extract from it an object 
// Extract from it an object 
idString = intent.getStringExtra("id"); 
// Convert the id in number 
idInt = Integer.parseInt(idString); 


// Display the text fields 
Contact title = Contact.findById(Contact.class, idInt); 
String titleStr = title.title; 
textView.setText(titleStr); 

Contact prich = Contact.findById(Contact.class, idInt); 
String prichStr = prich.prich; 
textView2.setText(prichStr); 

Проблема заключается в том, что, если положить в поиске заголовка, положение заголовка этого списка не будет пятым, к примеру, и первым и идентификатор должны отличаться от второго значения aktiviti, не выставляя пятый id, а с первого. Исходный поиск, он отлично работает, если вам нужно кого-то скопировать, единственной проблемой является передача данных, нажав на элемент списка.

activity_main.xml

<android.support.v7.widget.SearchView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/search_view" 
    android:layout_gravity="right" 
    app:theme="@style/Theme.AppCompat.NoActionBar" 
    app:searchIcon="@drawable/ic_search_white_24dp"/> 

MainActivity.java

private SearchView searchView; 

В OnCreate

searchView = (SearchView) findViewById(R.id.search_view); 
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { 
    @Override 
    public boolean onQueryTextSubmit(String text) { 
     return false; 
    } 

    @Override 
    public boolean onQueryTextChange(String text) { 
     mAdapter.filter(text); 
     return false; 
    } 
}); 

RecyclerAdapter.java

private ArrayList<String> mDataset; 
private ArrayList<String> mCleanCopyDataset; 

Конструктор

public RecyclerAdapter(ArrayList<String> dataset) { 
mDataset = dataset; 
mCleanCopyDataset = mDataset; 
} 

Поиск

 // The filter() method we iterate through all the items on the list and if any item contains the search text, we add it to a new list mDataset: 

public void filter(String charText) { 
charText = charText.toLowerCase(Locale.getDefault()); 
mDataset = new ArrayList<String>(); 
if (charText.length() == 0) { 
    // mCleanCopyDataset we always contains the unaltered and the filter (full) copy of the list of data 
    mDataset.addAll(mCleanCopyDataset); 
} else { 
    for (String item : mCleanCopyDataset) { 

     // we iterate through all the items on the list and if any item contains the search text, we add it to a new list mDataset 
     if (item.toLowerCase(Locale.getDefault()).contains(charText)) { 
      mDataset.add(item); 
     } 
    } 
} 
// method notifyDataSetChanged() allows you to update the list on the screen after filtration 
notifyDataSetChanged(); 
} 

полный код RecyclerAdapter.java

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> { 

private ArrayList<String> mDataset; 
private ArrayList<String> mId; 
private ArrayList<String> mCleanCopyDataset; 
String[] idTab; 
String[] titleTab; 

public static class ViewHolder extends RecyclerView.ViewHolder { 
    public TextView mTextView; 

    public ViewHolder(View v) { 
     super(v); 
     mTextView = (TextView) v.findViewById(R.id.tv_recycler_item); 
    } 
} 

public RecyclerAdapter(ArrayList<String> dataset, String[] titleTab, ArrayList<String> id) { 
    mDataset = dataset; 
    titleTab = titleTab; 
    mId = id; 
    mCleanCopyDataset = mDataset; 
} 

@Override 
public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, 
                int viewType) { 
    View v = LayoutInflater.from(parent.getContext()) 
      .inflate(R.layout.recycler_item, parent, false); 


    ViewHolder vh = new ViewHolder(v); 
    return vh; 
} 


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

    idTab = new String[mId.size()]; 
    for (int i = 0; i != mId.size(); i++) { 
     idTab[i] = mId.get(i); 
    } 

    holder.mTextView.setText(mDataset.get(position)); 

    holder.itemView.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      Context context = v.getContext(); 
      Intent ddddd = new Intent(context, LastActivity.class); 
      ddddd.putExtra("id", idTab[holder.getAdapterPosition()]); 
      context.startActivity(ddddd); 
     } 
    }); 
} 


@Override 
public int getItemCount() { 
    return mDataset.size(); 
} 



public void filter(String charText) { 
    charText = charText.toLowerCase(Locale.getDefault()); 
    mDataset = new ArrayList<String>(); 
    if (charText.length() == 0) { 

     mDataset.addAll(mCleanCopyDataset); 
    } else { 
     for (String item : mCleanCopyDataset) { 

      if (item.toLowerCase(Locale.getDefault()).contains(charText)) { 
       mDataset.add(item); 
      } 
     } 
    } 
    notifyDataSetChanged(); 
} 

}

enter image description here

enter image description here

ответ

3

Вы должны использовать Android встроенный в способность фильтровать ваши взгляды Ресайклер.

Чтобы сделать это, сделайте утилиту RecyclerAdapter фильтруемой.

public class MyAdapter extends RecyclerVew.Adapter implements Filterable { 

    private MyFilter filter; 

    public MyAdapter() { 
     // Do stuff 
    } 

    @Override 
    public Filter getFilter() { 
     if (filter == null) { 
      filter = new MyFilter(this, getElements()); 
     } 
     return filter; 
    } 

В этом примере кода вы увидите что-то, называемое MyFilter. Это то, что вы создадите и обеспечите пользовательскую логику.

Вот только один пример.

private static class MyFilter extends Filter { 

    private final MyAdapter adapter; 
    private final List<String> originalList; 
    private final List<String> filteredList; 

    private MyFilter(MyAdapter adapter, List<String> originalList) { 
     super(); 
     this.adapter = adapter; 
     this.originalList = new LinkedList<>(originalList); 
     this.filteredList = new ArrayList<>(); 
    } 

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

     if (charSequence.length() == 0) { 
      filteredList.addAll(originalList); 
     } else { 
      final String filterPattern = charSequence.toString().toLowerCase().trim(); 
      for (String item : originalList) { 
       if (item.toLowerCase().contains(filterPattern) { 
        filteredList.add(item); 
       } 
      } 
     } 

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

    @SuppressWarnings("unchecked") 
    @Override 
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) { 
     mDataset.clear(); 
     mDataset.add(filterResults.values); 
     adapter.notifyDataSetChanged(); 
    } 
} 

Затем в методе onQueryTextChange вызовите фильтр.

@Override 
public boolean onQueryTextChange(String text) { 
    mAdapter.getFilter().filter(text); 
    return false; 
} 
+0

Why clear(); и adapter.add (...); красный? – Artsait

+0

Я создал абстрактный класс адаптера, который имеет эти методы. Вам нужно будет управлять своим списком данных напрямую. Я изменю ответ в соответствии с вашим набором данных. – Weava

Смежные вопросы