只add间距一次,不要多次add
目标实现下面的效果;
思考一下,很简单,Recycleview嵌套Recycleview;外层的item宽度固定,高度为自适应;内部为一个Recycleview实现的gradview,item宽度固定,然后给内层的recycleview设置一个间距:即addItemDecoration。
但是,事情会这么简单吗?简单我就不会写出来。照着思路一步步走下去,写好后发现,内部Item的间距竟然是会变动的,开始的时候是正常的1倍间距,往后拉多个时,变成了2倍行距,然后继续上啦或者下拉,3倍行距,然后继续继续。图如下:
你以为这样就完了? too young, 我的逻辑是点击按钮会更新下按钮的状态,然后再adapter.notify,就出现了点击一次,item的间距会增大一次,如下图:
注:往右滚动时因为设置了右侧的间距,删除右侧间距保留上下间距时,内部的Recycleview的竖直方向上的间距会一直变大,效果和图是一样的。
至于为什么会出现这样的问题,暂时也没搞清楚,希望大牛看到可以指点下
附上源代码:
外层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顶部和底部,实现了如下效果: