RecyclerView网格和列表的布局切换效果

  • Post author:
  • Post category:其他


效果图

网格布局:
在这里插入图片描述
列表布局:
在这里插入图片描述

要实现网格布局和列表布局之间切换的效果,我知道有两种方法可以实现这个效果。一种是通过定义两个不同布局内容的适配器,通过切换是适配器来切换布局内容,这种方法感觉不叫笨拙,相对而言我比较喜欢使用另一种方法。另一种方法则只需要定义一个适配器,在适配的内部定义一个变量来区分具体使用哪个布局内容,在通过这个变量来实现切换的效果。下面贴出主要的实现代码。

首先第一步是在activity中或fragment中定义好需要的两个布局(网格,列表),也就是创建布局管理器,接下来就是正常操作的初始化RecyclerView。然后是设置点击事件切换布局。

内容有所省略,加载RecyclerView数据的方法不贴。代码:

public class HomeFragment extends Fragment {
    private Activity myActivityContext; //Activity上下文
    private GridLayoutManager gridLayoutManager;//网格布局
    private LinearLayoutManager linearLayoutManager;//列表布局
    private CommodityAdapter rvCommodityAdapter;//RecyclerView的适配器

    /*控件*/
    private CheckBox cbCut; //切换排列方式按钮
    private RecyclerView rvResult;//RecyclerView容器

    @Override
    public void onAttach(@NonNull Context context) {
        super.onAttach(context);
        myActivityContext = (Activity) context;
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_home, container, false);
        /*获取控件*/
        cbCut = view.findViewById(R.id.cb_home_cut);
        rvResult = view.findViewById(R.id.rv_home_result);

        gridLayoutManager = new GridLayoutManager(myActivityContext, 2);
        linearLayoutManager = new LinearLayoutManager(myActivityContext);

        init(); //初始化页面
        setViewEventListener(); //设置监听事件
        return view;
    }

    /*初始化页面方法*/
    private void init() {
        /*--------------------RecyclerView初始化---------------------*/
        //1、设置布局管理器
        //=1.1、创建布局管理器
        //=1.2、设置为垂直排列,用setOrientation方法设置(默认为垂直布局),列表布局才需要设置
        //=1.3、设置recyclerView的布局管理器,首次设置(相当于第一次进入时显示的布局)
        rvResult.setLayoutManager(gridLayoutManager);
        //2、设置适配置
        List<CommodityBean> listData = new ArrayList<>();
        //=2.1、初始化适配器
        rvCommodityAdapter = new CommodityAdapter(listData, myActivityContext, myApplication);
        //=2.2、设置点击事件
        rvCommodityAdapter.setItemClickListener(new CommodityAdapter.OnItemClickListener() {
            //每条数据的点击事件
            @Override
            public void onItemClick(View view, CommodityBean data, int position) {
                //跳转到预定页面
                Intent intent = new Intent(myActivityContext, CommodityActivity.class);
                //传递选中的商品数据
                Bundle bundle = new Bundle();//捆绑
                bundle.putSerializable("CommodityBean", (Serializable) data);
                //传递选择的客房类型数据
                intent.putExtras(bundle);
                myActivityContext.startActivity(intent);

            }
        });
        //=2.3 设置recyclerView的适配器
        rvResult.setAdapter(rvCommodityAdapter);
        //3、添加android自带的分割线
        rvResult.addItemDecoration(new DividerItemDecoration(myActivityContext, DividerItemDecoration.VERTICAL));
        //4、设置增加或删除条目的动画
        rvResult.setItemAnimator(new DefaultItemAnimator());

        //加载RecyclerView数据的方法
        loadListData(true);
    }

    /*设置控件事件监听方法*/
    private void setViewEventListener() {
        //切换布局点击事件
        cbCut.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (cbCut.isChecked()) {
                    //1:设置布局类型
                    rvCommodityAdapter.setType(0);
                    //2:设置对应的布局管理器
                    rvResult.setLayoutManager(gridLayoutManager);
                    //3:刷新adapter
                } else {
                    rvCommodityAdapter.setType(1);
                    linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
                    rvResult.setLayoutManager(linearLayoutManager);
                }
            }
        });
    }
}

接下来是适配器的代码,主要是通过变量来设置不同的布局内容和一个对外的方法切换布局。

内容有所省略,绑定数据部分也不贴,代码:

public class CommodityAdapter extends RecyclerView.Adapter<CommodityAdapter.ViewHolder> {
    private int type; //控制布局类型的变量
    private List<CommodityBean> listData; //RecyclerView数据
    private Activity myActivityContext; //Activity上下文
    private OnItemClickListener onItemClickListener; //存放点击事件的接口
    /*构造器*/
    public CommodityAdapter(List<CommodityBean> listData, Activity myActivityContext) {
        this.listData = listData;
        this.myActivityContext = myActivityContext; 
    }
    /*内部接口:存放点击事件*/
    public interface OnItemClickListener {
        /*整条数据的点击事件*/
        void onItemClick(View view, CommodityBean data, int position);
    }
    /*设置点击事件的方法*/
    public void setItemClickListener(OnItemClickListener onItemClickListener) {
        this.onItemClickListener = onItemClickListener;
    }
    /*创建ViewHolder   设置RecyclerViewItem布局*/
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == 0) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv_commodity_reseau, parent, false));
        } else if (viewType == 1) {
            return new ViewHolder(LayoutInflater.from(parent.getContext()).inflate(R.layout.item_rv_commodity_list, parent, false));
        }
        return null;
    }
    @Override
    public int getItemViewType(int position) {
        return type;
    }
    /*绑定数据*/
    @Override
    public void onBindViewHolder(@NonNull ViewHolder holder, int position) {}
    /*告诉RecyclerView有多少条数据*/
    @Override
    public int getItemCount() {
        return listData.size();
    }
    /**
     * 对外方法 用于切换布局方式
     *
     * @param type
     */
    public void setType(int type) {
        this.type = type; 
    }
    /*//获取列表项的控件*/
    static class ViewHolder extends RecyclerView.ViewHolder {
        /*控件*/
        ImageView ivPictureList; //商品图片
        TextView tvNameList; //商品名称
        TextView tvPriceList; //商品价格
        TextView tvSaleList; //商品已售数量
        TextView tvPlaceOriginList; //商品出产地
        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            /*获取控件*/
            ivPictureList = itemView.findViewById(R.id.iv_commodity_picture);
            tvNameList = itemView.findViewById(R.id.tv_commodity_name);
            tvPriceList = itemView.findViewById(R.id.tv_commodity_price);
            tvSaleList = itemView.findViewById(R.id.tv_commodity_number_people);
            tvPlaceOriginList = itemView.findViewById(R.id.tv_commodity_place_origin);
        }
    }
}

需要注意的是,我这里的两个item布局文件内它们的对应控件都是一样的id,所以我这里可以这样设置。如果两个item布局文件内对应控件的id不一致的话设置数据和获取控件时会报异常。如果两个item布局文件的对应控件的id不一致或内容本就不相同的话可以考虑使用开始时说的第一种定义两个适配器的方法来实现。

以上就是主要的实现代码,View布局文件我就不贴出来了。



版权声明:本文为qq_41708308原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。