话不多说,先看效果图:
最上面的是简单的recycleview列表,下面的是可翻页滚动的菜单,采用的是viewpager + recycleview模式。
翻页滚动菜单使用方法:
private void initViewpager() {
List<MenuInfo> listData2 = new ArrayList<>();
for (int i = 0; i < 15; i++) {
MenuInfo menu = new MenuInfo();
menu.setResId(R.mipmap.ic_launcher);
menu.setName(String.valueOf(i));
listData2.add(menu);
}
ViewPagerAdapter viewPagerAdapter = new ViewPagerAdapter(this, 5);
viewPagerAdapter.setDate(listData2);
vpContent.setAdapter(viewPagerAdapter);
}
顶层的viewpager的适配器,用于适配有多少页的菜单:
public class ViewPagerAdapter extends PagerAdapter implements IMenuPageClickListener {
List<MenuInfo> data;
List<OnepageRecycleViewAdapter> adapterList;
Context context;
int pageSize = 5; //一页包含菜单的数量大小
String TAG = "ViewPagerAdapter";
public ViewPagerAdapter(Context context, int pageSize) {
this.context = context.getApplicationContext();
this.pageSize = pageSize;
}
public void setDate(List<MenuInfo> listData) {
this.data = listData;
this.adapterList = new ArrayList<>();
}
@Override
public int getCount() {//注意,这里是页数
if (data == null) {
return 0;
}
if (data.size() % pageSize == 0) {
return data.size() / pageSize;
} else {
return data.size() / pageSize + 1;
}
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int pageIndex) {
View view = LayoutInflater.from(context).inflate(R.layout.item_view_pager, null);
RecyclerView recyclerView = view.findViewById(R.id.rc_page_item);
GridLayoutManager layoutManager = new GridLayoutManager(context, 5);
recyclerView.setLayoutManager(layoutManager);
OnepageRecycleViewAdapter adapter;
if(adapterList.size() > pageIndex && adapterList.get(pageIndex) != null){
adapter = adapterList.get(pageIndex);
}else{
adapter = new OnepageRecycleViewAdapter(context, pageIndex);
}
List<MenuInfo> pageMenuList = getPageListData(pageIndex);
adapter.setData(pageMenuList);
adapter.setMenuItemClickListener(this);
recyclerView.setAdapter(adapter);
adapterList.add(adapter);
container.addView(view);
return view;
}
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {
container.removeView((View) object);
}
private List<MenuInfo> getPageListData(int position) {
int startIndex = 0;
int endIndex = 0;
if (data.size() / pageSize > position || (data.size() % pageSize == 0 && data.size() / pageSize == position)) { //15 5 1 15 5 0
startIndex = pageSize * position;
endIndex = pageSize * (position + 1);
} else { //16 5 3
startIndex = pageSize * position;
endIndex = data.size();
}
Log.e(TAG, "startIndex=" + startIndex + ";endIndex=" + endIndex + ";position=" + position);
List<MenuInfo> list = new ArrayList<>();
for (int i = startIndex; i < endIndex; i++) {
list.add(data.get(i));
}
return list;
}
private int mLastSelectedPageIndex = -1, mLastSelectedPosInPage = -1;
@Override
public void onMenuItemClick(int pageIndex, int position) {
int positionInAll = pageIndex * pageSize + position;
Toast.makeText(context, "点击第" + positionInAll + "个菜单", Toast.LENGTH_SHORT).show();
Log.e(TAG, "pageIndex=" + pageIndex + ";position = " + position);
adapterList.get(pageIndex).getMenuList().get(position).setSelected(true);
adapterList.get(pageIndex).notifyItemChanged(position);
Log.e(TAG, "mLastSelectedPageIndex=" + mLastSelectedPageIndex + ";mLastSelectedPosInPage=" + mLastSelectedPosInPage);
//并且通知其他菜单改变颜色
int lastPositionInAll = mLastSelectedPageIndex * pageSize + mLastSelectedPosInPage;
if (mLastSelectedPageIndex != -1 && mLastSelectedPosInPage != -1 && lastPositionInAll != positionInAll) {
adapterList.get(mLastSelectedPageIndex).getMenuList().get(mLastSelectedPosInPage).setSelected(false);
adapterList.get(mLastSelectedPageIndex).notifyItemChanged(mLastSelectedPosInPage);
}
mLastSelectedPageIndex = pageIndex;
mLastSelectedPosInPage = position;
}
}
每一页菜单的recycleview适配:
public class OnepageRecycleViewAdapter extends RecyclerView.Adapter<OnepageRecycleViewAdapter.MenuViewHolder> {
private List<MenuInfo> data;
private Context context;
private int pageIndex;
String TAG = "OnepageRecycleViewAdapter";
IMenuPageClickListener menuPageClickListener;
public OnepageRecycleViewAdapter(Context context, int pageIndex) {
this.context = context.getApplicationContext();
this.pageIndex = pageIndex;
}
public void setData(List<MenuInfo> data) {
this.data = data;
}
public void setMenuItemClickListener(IMenuPageClickListener listener) {
menuPageClickListener = listener;
}
@NonNull
@Override
public MenuViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
return new MenuViewHolder(LayoutInflater.from(context).inflate(R.layout.item_menu, null));
}
@Override
public void onBindViewHolder(@NonNull MenuViewHolder holder, final int position) {
Log.e(TAG, "onBindViewHolder position=" + position);
MenuInfo menu = data.get(position);
holder.ivIcon.setImageResource(menu.getResId());
holder.tvName.setText(menu.getName());
holder.llItemContent.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (menuPageClickListener != null) {
menuPageClickListener.onMenuItemClick(pageIndex, position);
}
}
});
if (menu.isSelected()) {
holder.tvName.setText(menu.getName() + "(选中)");
} else {
holder.tvName.setText(menu.getName());
}
}
public List<MenuInfo> getMenuList() {
return data;
}
@Override
public int getItemCount() {
return data == null ? 0 : data.size();
}
class MenuViewHolder extends RecyclerView.ViewHolder {
LinearLayout llItemContent;
ImageView ivIcon;
TextView tvName;
public MenuViewHolder(View itemView) {
super(itemView);
llItemContent = itemView.findViewById(R.id.ll_item_content);
ivIcon = itemView.findViewById(R.id.iv_icon);
tvName = itemView.findViewById(R.id.tv_name);
}
}
}
最后附上代码链接:
https://github.com/hqfeijian/HorizontalViewPager/tree/master
之前有一篇也是横向滚动菜单的,不过发现每一次点击去notifyItemChanged的时候,都会触发所有的item刷新,链接见:
https://blog.csdn.net/qq_22706515/article/details/53173162