Recycleview嵌套Recycleview时出现的一个问题-待解决

只add间距一次,不要多次add

目标实现下面的效果;

Recycleview嵌套Recycleview时出现的一个问题-待解决_第1张图片

思考一下,很简单,Recycleview嵌套Recycleview;外层的item宽度固定,高度为自适应;内部为一个Recycleview实现的gradview,item宽度固定,然后给内层的recycleview设置一个间距:即addItemDecoration。

但是,事情会这么简单吗?简单我就不会写出来。照着思路一步步走下去,写好后发现,内部Item的间距竟然是会变动的,开始的时候是正常的1倍间距,往后拉多个时,变成了2倍行距,然后继续上啦或者下拉,3倍行距,然后继续继续。图如下:

Recycleview嵌套Recycleview时出现的一个问题-待解决_第2张图片

你以为这样就完了? too young, 我的逻辑是点击按钮会更新下按钮的状态,然后再adapter.notify,就出现了点击一次,item的间距会增大一次,如下图:

注:往右滚动时因为设置了右侧的间距,删除右侧间距保留上下间距时,内部的Recycleview的竖直方向上的间距会一直变大,效果和图是一样的。

Recycleview嵌套Recycleview时出现的一个问题-待解决_第3张图片

至于为什么会出现这样的问题,暂时也没搞清楚,希望大牛看到可以指点下

附上源代码:

外层recycleview的adapter和layout

 

public class MainAdater extends RecyclerView.Adapter implements View.OnClickListener {
    List mList;
    Context mContext;
    public boolean shouldSet;
    //  ItemAdater itemAdater;

    public MainAdater(List mList, Context mContext, boolean shouldSet) {
        this.mList = mList;
        this.mContext = mContext;
        this.shouldSet = shouldSet;
    }

    //定义一个点击事件的接口
    public static interface onRecycleviewItemClickListener {

        void onItemClick(View view, MainBean data, int position);
    }

    private onRecycleviewItemClickListener mOnItemClickListener = null;

    public void setOnItemClickListener(onRecycleviewItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    public MainAdater(List allWifi, Context mContext) {
        this.mList = allWifi;
        this.mContext = mContext;
    }

    //item的点击事件
    @Override
    public void onClick(View view) {
        if (mOnItemClickListener != null) {
            //注意这里使用getTag方法获取数据
            mOnItemClickListener.onItemClick(view, (MainBean) view.getTag(R.id.id1), (Integer) view.getTag(R.id.id2));

        }
    }

    class MyViewholder extends RecyclerView.ViewHolder {
        RecyclerView gradview;
        TextView textView;

        public MyViewholder(View itemView) {
            super(itemView);
            gradview = (RecyclerView) itemView.findViewById(R.id.gradview);
            textView = (TextView) itemView.findViewById(R.id.textview);
        }
    }

    @Override
    public MainAdater.MyViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_recycleview, null);
        ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        WindowManager wm = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        lp.width = width;
        view.setLayoutParams(lp);
        Log.e("给外层item设置宽度", "====");
        //为item设置点击事件
        view.setOnClickListener(this);
        MyViewholder viewholder = new MyViewholder(view);
        return viewholder;
    }

    @Override
    public void onBindViewHolder(final MyViewholder holder, final int position) {
        View view = holder.itemView;
        ViewGroup.LayoutParams myLayoutParams = holder.itemView.getLayoutParams();
        //将数据保存在itemview的tag中
        holder.itemView.setTag(R.id.id1, mList.get(position));
        holder.itemView.setTag(R.id.id2, position);
        //对内层进行设置
        ItemAdater itemAdater = new ItemAdater(mList.get(position).getValues(), mContext);
        GridLayoutManager gridLayoutManager = new GridLayoutManager(mContext, 3);
        holder.gradview.setLayoutManager(gridLayoutManager);
        holder.gradview.setAdapter(itemAdater);
        holder.textView.setText(mList.get(position).getTitle());
        //设置间隔===这个是标签的
        WindowManager wm = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        int height = wm.getDefaultDisplay().getHeight();
        //这个就是本来的设置,因为后期为了实现效果,不用这个代码了
      //  holder.gradview.addItemDecoration(new RecycleviewItemForGradview((int) (0.01 * height)));
        Log.e("设置给内层的尺寸是", 0.01 * height + "===");
        itemAdater.setOnItemClickListener(new ItemAdater.onRecycleviewItemClickListener() {
            @Override
            public void onItemClick(View view, ItemBean data, int position1) {
                view.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.shape_gradview_choose));
                MainActivity mainActivity = (MainActivity) mContext;
                mainActivity.setData(position, position1);
            }
        });
    }

    @Override
    public int getItemCount() {
        if (mList == null || mList.size() == 0) {
            return 0;
        } else {
            return mList.size();
        }
    }


}

layout:

 

 




    

    

 

 

 

 

 

内层Recycleview的adapter和layout

 

public class ItemAdater extends RecyclerView.Adapter implements View.OnClickListener {
    List mList;
    Context mContext;

    //定义一个点击事件的接口
    public static interface onRecycleviewItemClickListener {

        void onItemClick(View view, ItemBean data,int position);
    }

    private ItemAdater.onRecycleviewItemClickListener mOnItemClickListener = null;

    public void setOnItemClickListener(ItemAdater.onRecycleviewItemClickListener listener) {
        this.mOnItemClickListener = listener;
    }

    public ItemAdater(List allWifi, Context mContext) {
        this.mList = allWifi;
        this.mContext = mContext;
    }

    //item的点击事件
    @Override
    public void onClick(View view) {
        if (mOnItemClickListener != null) {
            //注意这里使用getTag方法获取数据

            mOnItemClickListener.onItemClick(view, (ItemBean) view.getTag(R.id.id1), (Integer) view.getTag(R.id.id2));

        }
    }

    class MyViewholder extends RecyclerView.ViewHolder {
PercentRelativeLayout rel;
        TextView textView;

        public MyViewholder(View itemView) {
            super(itemView);
rel= (PercentRelativeLayout) itemView.findViewById(R.id.rel);
            textView = (TextView) itemView.findViewById(R.id.textview);
        }
    }

    @Override
    public ItemAdater.MyViewholder onCreateViewHolder(ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(mContext).inflate(R.layout.item_gradview_two, null);
        RecyclerView.LayoutParams lp = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        WindowManager wm = (WindowManager) mContext
                .getSystemService(Context.WINDOW_SERVICE);
        int width = wm.getDefaultDisplay().getWidth();
        int height = wm.getDefaultDisplay().getHeight();
        lp.height = (int) (0.07 * height);
        lp.width = (int) (0.3 * width);
        view.setLayoutParams(lp);
        Log.e("给内层item设置宽度","===="+lp.height);
        //为item设置点击事件
        view.setOnClickListener(this);
        ItemAdater.MyViewholder viewholder = new ItemAdater.MyViewholder(view);
        return viewholder;
    }

    @Override
    public void onBindViewHolder(ItemAdater.MyViewholder holder, int position) {
        View view = holder.itemView;
        ViewGroup.LayoutParams myLayoutParams = holder.itemView.getLayoutParams();
        //将数据保存在itemview的tag中
        holder.itemView.setTag(R.id.id1,mList.get(position));
        holder.itemView.setTag(R.id.id2,position);
        //在这里设置数据
        if(mList.get(position).isChoose()==true){
            holder.rel.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.shape_gradview_choose));
        }else {
            holder.rel.setBackgroundDrawable(mContext.getResources().getDrawable(R.drawable.shape_gradview_nochoose));
        }
        holder.textView.setText(mList.get(position).getValue());
    }

    @Override
    public int getItemCount() {
        if (mList == null || mList.size() == 0) {
            return 0;
        } else {
            return mList.size();
        }
    }


}

 




    


至于点击事件的处理,就是在外层adapter在onBindViewHolder中对内层recycleview实例化的时候,通过调用MainActivity的方法,显示源数据的变更和RecycleView数据的更新,更新方法如下:

 

 

 public void setData(int onePosition, int valuePosition) {
        Log.e("点击到的位置信息", onePosition + "=" + valuePosition);
        for (int i = 0; i < mList.size(); i++) {
            if (onePosition == i) {
                for (int j = 0; j < mList.get(onePosition).getValues().size(); j++) {
                    if (j == valuePosition) {
                        mList.get(i).getValues().get(j).setChoose(true);
                    } else {
                        mList.get(i).getValues().get(j).setChoose(false);
                    }
                }

            } else {
                for (int t = 0; t < mList.get(i).getValues().size(); t++) {
                    mList.get(i).getValues().get(t).setChoose(false);
                }

            }
        }
        mainAdater.notifyDataSetChanged();
    }

 

设置内部Recycleview的item间距的方法;

 

 

public class RecycleviewItemForGradview extends RecyclerView.ItemDecoration{
    private int space;

    public RecycleviewItemForGradview(int space) {
        this.space = space;
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
       outRect.bottom = space;
            outRect.top = space;
    }
}

 

 

 

 

 

对于两个bean类,外层的bean,分组的名称和内层bean的集合;内层bean,属性的名称和这个属性是否处于点击状态。

 

 

 

最后只能内层item的布局套布局,然后套的布局margin顶部和底部,实现了如下效果:

你可能感兴趣的:(Android)