如何使用相同的 RecyclerView 制作 SearchView?
How to make SearchView with same RecyclerView?
我在添加到 MainActivity body 容器的 RecyclerView 中有一些片段。我有一个带有工具栏和 RecyclerView 的片段,它被添加到 MainActivity 头容器中。我想搜索所有 RecyclerView 的所有元素,并为 body 容器制作 setVisibility(View.GONE)
,为头部 RecyclerView 制作 setVisibility(View.VISIBLE)
。不懂怎么搜索
fragment_stations.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager" />
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/container_from_toolbar"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</LinearLayout>
fragment_search.xml
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<include layout="@layout/toolbar_main"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewSearch"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager" />
</RelativeLayout>
</LinearLayout>
RecyclerStationAdapter.java(对于 body 容器)
public class RecyclerStationAdapter extends RecyclerView.Adapter<RecyclerStationAdapter.ViewHolder> {
private LayoutInflater mLayoutInflater;
private List<Station> mStations;
private Context mContext;
private static AnimatorHelper animatorHelper;
public RecyclerStationAdapter(Context context, List<Station> stations) {
this.mStations = stations;
this.mLayoutInflater = LayoutInflater.from(context);
mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.example_list_item_station, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
// viewHolder.setIsRecyclable(false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Station station = mStations.get(position);
holder.textView.setText(station.getName());
// holder.setIsRecyclable(false);
Glide.with(mContext)
.load(mStations.get(position).getImage())
.error(R.drawable.ic_launcher_foreground)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.into(holder.imageView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createFirebaseReport(position);
Log.d("debug", mStations.get(position).getName());
Player player = new Player(mStations.get(position).getStream());
player.start(mContext);
startPlayerService();
if (animatorHelper != null)
animatorHelper.stopAnimation();
animatorHelper = new AnimatorHelper(holder.playViewAnimation);
animatorHelper.startAnimation();
Log.d("anm", String.valueOf(holder.getItemId()));
}
private void startPlayerService() {
Intent serviceIntent = new Intent(mContext, NotificationService.class);
serviceIntent.setAction(Const.ACTION.STARTFOREGROUND_ACTION);
mContext.startService(serviceIntent);
}
});
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
private void createFirebaseReport(int position) {
FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(mContext);
Bundle eventDetails = new Bundle();
StringBuilder sb = new StringBuilder();
sb.append(mStations.get(position).getName() + " : " + mStations.get(position).getStream());
eventDetails.putString("station", sb.toString());
firebaseAnalytics.logEvent("select_station", eventDetails);
}
@Override
public int getItemCount() {
return mStations.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
final ImageView imageView;
final TextView textView;
final AVLoadingIndicatorView playViewAnimation;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.ivStation);
textView = itemView.findViewById(R.id.tvStation);
playViewAnimation = itemView.findViewById(R.id.playing_anim);
}
}
}
您可以在 Adapter class 上添加 getFilter() 方法,在 Fragment 上添加 onCreateOptionsMenu 方法。请遵循以下代码;
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.seach_menu, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) menuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
customAdapter_halal.getFilter().filter(newText);
return false;
}
});
}
和
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> implements Filterable {
private Context context;
LayoutInflater layoutInflater;
List<Model> modeller;
List<Model> filteredModel;
public CustomAdapter(Context context, List<Model> models) {
this.context = context;
this.modeller = models;
this.filteredModel = models; // bu sekilde ekliyoruz
}
@NonNull
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
layoutInflater = LayoutInflater.from(context);
View v = layoutInflater.inflate(R.layout.row_list, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull CustomAdapter.ViewHolder holder, int position) {
holder.name.setText(filteredModel.get(position).getName());
holder.packageName.setText(filteredModel.get(position).getPackageName());
holder.developer.setText(filteredModel.get(position).getDeveloperName());
holder.price.setText(filteredModel.get(position).getPrice() + " " + "€");
holder.rating.setText(String.valueOf(filteredModel.get(position).getRatingValue()));
Picasso.get().load(filteredModel.get(position).getIconUrl()).into(holder.image_icon);
holder.linearLayout.setTag(holder);
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewHolder viewHolder = (ViewHolder) v.getTag();
int position = holder.getAdapterPosition();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
String pName = filteredModel.get(position).getPackageName();
String sabit = "https://play.google.com/store/apps/details?id=";
String uzanti = sabit + pName;
intent.setData(Uri.parse(uzanti));
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return filteredModel.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String searchString = charSequence.toString();
if (searchString.isEmpty()) {
filteredModel = modeller;
} else {
ArrayList<Model> tempFilteredList = new ArrayList<>();
for (Model model : modeller) {
// search for user name
if (model.getName().toLowerCase().contains(searchString)) {
tempFilteredList.add(model);
}
}
filteredModel = tempFilteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredModel;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
filteredModel = (ArrayList<Model>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView name, packageName, developer, rating, price;
LinearLayout linearLayout;
ImageView image_icon;
public ViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
packageName = itemView.findViewById(R.id.text_packagename);
developer = itemView.findViewById(R.id.text_developer);
rating = itemView.findViewById(R.id.text_rating);
price = itemView.findViewById(R.id.text_price);
image_icon = itemView.findViewById(R.id.image_icon);
linearLayout = itemView.findViewById(R.id.linear_layout);
}
}
}
最重要的一点是不要忘记添加 setHasOptionsMenu(true);在你的 oncreateview() 方法上。
我在添加到 MainActivity body 容器的 RecyclerView 中有一些片段。我有一个带有工具栏和 RecyclerView 的片段,它被添加到 MainActivity 头容器中。我想搜索所有 RecyclerView 的所有元素,并为 body 容器制作 setVisibility(View.GONE)
,为头部 RecyclerView 制作 setVisibility(View.VISIBLE)
。不懂怎么搜索
fragment_stations.xml
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager" />
</RelativeLayout>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/container_from_toolbar"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="@+id/main_container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" />
</ScrollView>
</LinearLayout>
fragment_search.xml
<LinearLayout android:layout_height="wrap_content"
android:layout_width="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<include layout="@layout/toolbar_main"/>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:descendantFocusability="blocksDescendants">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewSearch"
android:visibility="visible"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layoutManager="LinearLayoutManager" />
</RelativeLayout>
</LinearLayout>
RecyclerStationAdapter.java(对于 body 容器)
public class RecyclerStationAdapter extends RecyclerView.Adapter<RecyclerStationAdapter.ViewHolder> {
private LayoutInflater mLayoutInflater;
private List<Station> mStations;
private Context mContext;
private static AnimatorHelper animatorHelper;
public RecyclerStationAdapter(Context context, List<Station> stations) {
this.mStations = stations;
this.mLayoutInflater = LayoutInflater.from(context);
mContext = context;
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = mLayoutInflater.inflate(R.layout.example_list_item_station, parent, false);
ViewHolder viewHolder = new ViewHolder(view);
// viewHolder.setIsRecyclable(false);
return new ViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
Station station = mStations.get(position);
holder.textView.setText(station.getName());
// holder.setIsRecyclable(false);
Glide.with(mContext)
.load(mStations.get(position).getImage())
.error(R.drawable.ic_launcher_foreground)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.into(holder.imageView);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
createFirebaseReport(position);
Log.d("debug", mStations.get(position).getName());
Player player = new Player(mStations.get(position).getStream());
player.start(mContext);
startPlayerService();
if (animatorHelper != null)
animatorHelper.stopAnimation();
animatorHelper = new AnimatorHelper(holder.playViewAnimation);
animatorHelper.startAnimation();
Log.d("anm", String.valueOf(holder.getItemId()));
}
private void startPlayerService() {
Intent serviceIntent = new Intent(mContext, NotificationService.class);
serviceIntent.setAction(Const.ACTION.STARTFOREGROUND_ACTION);
mContext.startService(serviceIntent);
}
});
}
@Override
public int getItemViewType(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
private void createFirebaseReport(int position) {
FirebaseAnalytics firebaseAnalytics = FirebaseAnalytics.getInstance(mContext);
Bundle eventDetails = new Bundle();
StringBuilder sb = new StringBuilder();
sb.append(mStations.get(position).getName() + " : " + mStations.get(position).getStream());
eventDetails.putString("station", sb.toString());
firebaseAnalytics.logEvent("select_station", eventDetails);
}
@Override
public int getItemCount() {
return mStations.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
final ImageView imageView;
final TextView textView;
final AVLoadingIndicatorView playViewAnimation;
public ViewHolder(@NonNull View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.ivStation);
textView = itemView.findViewById(R.id.tvStation);
playViewAnimation = itemView.findViewById(R.id.playing_anim);
}
}
}
您可以在 Adapter class 上添加 getFilter() 方法,在 Fragment 上添加 onCreateOptionsMenu 方法。请遵循以下代码;
@Override
public void onCreateOptionsMenu(@NonNull Menu menu, @NonNull MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.seach_menu, menu);
MenuItem menuItem = menu.findItem(R.id.action_search);
androidx.appcompat.widget.SearchView searchView = (androidx.appcompat.widget.SearchView) menuItem.getActionView();
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
@Override
public boolean onQueryTextSubmit(String query) {
return false;
}
@Override
public boolean onQueryTextChange(String newText) {
customAdapter_halal.getFilter().filter(newText);
return false;
}
});
}
和
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.ViewHolder> implements Filterable {
private Context context;
LayoutInflater layoutInflater;
List<Model> modeller;
List<Model> filteredModel;
public CustomAdapter(Context context, List<Model> models) {
this.context = context;
this.modeller = models;
this.filteredModel = models; // bu sekilde ekliyoruz
}
@NonNull
@Override
public CustomAdapter.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
layoutInflater = LayoutInflater.from(context);
View v = layoutInflater.inflate(R.layout.row_list, parent, false);
return new ViewHolder(v);
}
@Override
public void onBindViewHolder(@NonNull CustomAdapter.ViewHolder holder, int position) {
holder.name.setText(filteredModel.get(position).getName());
holder.packageName.setText(filteredModel.get(position).getPackageName());
holder.developer.setText(filteredModel.get(position).getDeveloperName());
holder.price.setText(filteredModel.get(position).getPrice() + " " + "€");
holder.rating.setText(String.valueOf(filteredModel.get(position).getRatingValue()));
Picasso.get().load(filteredModel.get(position).getIconUrl()).into(holder.image_icon);
holder.linearLayout.setTag(holder);
holder.linearLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ViewHolder viewHolder = (ViewHolder) v.getTag();
int position = holder.getAdapterPosition();
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
String pName = filteredModel.get(position).getPackageName();
String sabit = "https://play.google.com/store/apps/details?id=";
String uzanti = sabit + pName;
intent.setData(Uri.parse(uzanti));
context.startActivity(intent);
}
});
}
@Override
public int getItemCount() {
return filteredModel.size();
}
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
String searchString = charSequence.toString();
if (searchString.isEmpty()) {
filteredModel = modeller;
} else {
ArrayList<Model> tempFilteredList = new ArrayList<>();
for (Model model : modeller) {
// search for user name
if (model.getName().toLowerCase().contains(searchString)) {
tempFilteredList.add(model);
}
}
filteredModel = tempFilteredList;
}
FilterResults filterResults = new FilterResults();
filterResults.values = filteredModel;
return filterResults;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
filteredModel = (ArrayList<Model>) filterResults.values;
notifyDataSetChanged();
}
};
}
public class ViewHolder extends RecyclerView.ViewHolder {
TextView name, packageName, developer, rating, price;
LinearLayout linearLayout;
ImageView image_icon;
public ViewHolder(@NonNull View itemView) {
super(itemView);
name = itemView.findViewById(R.id.text_name);
packageName = itemView.findViewById(R.id.text_packagename);
developer = itemView.findViewById(R.id.text_developer);
rating = itemView.findViewById(R.id.text_rating);
price = itemView.findViewById(R.id.text_price);
image_icon = itemView.findViewById(R.id.image_icon);
linearLayout = itemView.findViewById(R.id.linear_layout);
}
}
}
最重要的一点是不要忘记添加 setHasOptionsMenu(true);在你的 oncreateview() 方法上。