Организация поиска в RecyclerView
Я использовал RecyclerView для отображения списка с элементами. Хочу реализовать поиск по этому способу, но желательно наиболее простым и действенным способом. разобраться в тех примерах что нашел в интернете не получилось, увы, т.к. они ещё сложны для меня (пока что новичок).
Код адаптера:
public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.MyViewHolder> {
private Context mContext ;
private List<Anime> mData ;
RequestOptions option;
public RecyclerViewAdapter(Context mContext, List<Anime> mData) {
this.mContext = mContext;
this.mData = mData;
// Request option for Glide
option = new RequestOptions().centerCrop().placeholder(R.drawable.loading_shape).error(R.drawable.loading_shape);
}
@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view ;
LayoutInflater inflater = LayoutInflater.from(mContext);
view = inflater.inflate(R.layout.anime_row_item,parent,false) ;
final MyViewHolder viewHolder = new MyViewHolder(view) ;
viewHolder.view_container.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent(mContext, AnimeActivity.class);
i.putExtra("id",mData.get(viewHolder.getAdapterPosition()).getID());
i.putExtra("title",mData.get(viewHolder.getAdapterPosition()).getName());
i.putExtra("description",mData.get(viewHolder.getAdapterPosition()).getDescription());
i.putExtra("author",mData.get(viewHolder.getAdapterPosition()).getCategorie());
i.putExtra("mindescript",mData.get(viewHolder.getAdapterPosition()).getMinDesc());
i.putExtra("rating",mData.get(viewHolder.getAdapterPosition()).getRating());
i.putExtra("previewimgurl",mData.get(viewHolder.getAdapterPosition()).getImage_url());
i.putExtra("modsize",mData.get(viewHolder.getAdapterPosition()).getFileSize());
mContext.startActivity(i);
}
});
return viewHolder;
}
@Override
public void onBindViewHolder(MyViewHolder holder, int position) {
holder.tv_name.setText(mData.get(position).getName());
holder.tv_category.setText(mData.get(position).getCategorie());
holder.tv_min_description.setText(mData.get(position).getMinDesc());
// Load Image from the internet and set it into Imageview using Glide
Glide.with(mContext).load(mData.get(position).getImage_url()).apply(option).into(holder.img_thumbnail);
}
@Override
public int getItemCount() {
return mData.size();
}
public static class MyViewHolder extends RecyclerView.ViewHolder {
TextView tv_name ;
TextView tv_category;
TextView tv_min_description;
ImageView img_thumbnail;
LinearLayout view_container;
public MyViewHolder(View itemView) {
super(itemView);
view_container = itemView.findViewById(R.id.container);
tv_name = itemView.findViewById(R.id.anime_name);
tv_category = itemView.findViewById(R.id.categorie);
tv_min_description = itemView.findViewById(R.id.minidescript);
img_thumbnail = itemView.findViewById(R.id.thumbnail);
}
}
}
P.S Хотелось бы, чтоб поиск был снизу ( пока не разобрался, опять же )
Главный активити:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lstAnime = new ArrayList<>() ;
recyclerView = findViewById(R.id.recyclerviewid);
jsonrequest();
}
private void jsonrequest() {
request = new JsonArrayRequest(JSON_URL, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
JSONObject jsonObject = null;
for (int i = 0 ; i < response.length(); i++ ) {
try {
jsonObject = response.getJSONObject(i) ;
//тут у меня некий код по типу такого
R1 r = new R1() ;
r.setID(jsonObject.getString("id"));
lstAnime.add(anime);
} catch (JSONException e) {
e.printStackTrace();
}
}
setuprecyclerview(lstAnime);
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
});
requestQueue = Volley.newRequestQueue(MainActivity.this);
requestQueue.add(request) ;
}
private void setuprecyclerview(List<Anime> lstAnime) {
RecyclerViewAdapter myadapter = new RecyclerViewAdapter(this,lstAnime) ;
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setAdapter(myadapter);
}
Ответы (1 шт):
Автор решения: Cypher
→ Ссылка
Вот пример того как решить эту задачу с помощью паттерна Observer. У нас "тупая" вьюха, а вся логика фильтрации во ViewModel.
Activity:
class SearchViewActivity : AppCompatActivity() {
private lateinit var viewModel: SearchViewModel
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_search_view)
viewModel = ViewModelProvider(this).get(SearchViewModel::class.java)
viewModel.filteredItems.observe(this) {
recycler_view.adapter = SearchAdapter(it)
}
search_view.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
override fun onQueryTextSubmit(query: String?): Boolean {
query?.let { viewModel.filterItems(it) }
return true
}
override fun onQueryTextChange(newText: String?): Boolean {
newText?.let { viewModel.filterItems(it) }
return true
}
})
}
}
ViewModel:
class SearchViewModel : ViewModel() {
private val items = MutableLiveData<MutableList<Item>>().apply {
value = mutableListOf(
Item(1, "Один"),
Item(2, "Два"),
Item(3, "Три"),
Item(4, "Четыре"),
Item(5, "Пять")
)
}
val filteredItems = MutableLiveData<MutableList<Item>>().apply {
value = items.value
}
fun filterItems(query: String) {
viewModelScope.launch {
val filteredList = mutableListOf<Item>()
items.value?.map {
if (it.title.contains(query, true)) filteredList.add(it)
}
filteredItems.postValue(filteredList)
}
}
}
Adapter:
class SearchAdapter(private val items: List<Item>) :
RecyclerView.Adapter<SearchAdapter.SearchViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = SearchViewHolder(
LayoutInflater.from(parent.context).inflate(R.layout.item_date, parent, false)
)
override fun onBindViewHolder(holder: SearchViewHolder, position: Int) {
holder.title.text = items[position].title
}
override fun getItemCount() = items.size
class SearchViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val title: TextView = view.date_title
}
}
Item:
data class Item(
val id: Int,
val title: String
)
R.layout.activity_search_view:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".recycler_search.SearchViewActivity">
<androidx.appcompat.widget.SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="0dp"
android:layout_height="0dp"
app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/search_view"
tools:listitem="@layout/item_date" />
</androidx.constraintlayout.widget.ConstraintLayout>
