【问题标题】:RecyclerView notifyDataSetChange scroling all the way up, not working as i want it toRecyclerView notifyDataSetChanged 一直向上滚动,无法按我的意愿工作
【发布时间】:2016-09-24 16:57:19
【问题描述】:

我正在我的应用程序中为 Facebook 编写一个照片选择器,我有一个带有网格布局的 recyclerview,我想防止向上滚动,我可以通过使用 scrollToPosition 来做到这一点,这可行但不是这样我想要

问题

当我单击第 2 行上的照片时,该行跳到顶部并成为第 1 个可见行,如果我单击第 3 行,则会发生同样的事情。

如果视图可见,我不希望回收站移动它应该保持不变,所以如果我点击最后一个可见行上的照片,我希望滚动保持不变,我不希望它使最后一行成为第一行。

尝试解决它

我尝试了几件事来解决这个问题,我尝试调用setNestedScrollingEnabled 我关注了这个How to disable RecyclerView scrolling?

 public static void onItemClick(int position){
    //picker.setNestedScrollingEnabled(false);
    for(int k = 0; k<photoBag.size();k++) {
        if(k == position)
            photoBag.set(position, new PhotoBag(photoBag.get(position).getPhoto(), true)); //Here im marking the photo to selected
        else
            photoBag.set(k, new PhotoBag(photoBag.get(k).getPhoto(), false));//Here im setting unselecting all the other photos
    }

    picker.setAdapter(adapter);
    adapter.notifyDataSetChanged();

    picker.scrollToPosition(position);

    //Log.d("FacebookPicker", "position " + grid.findFirstCompletelyVisibleItemPosition());
    //picker.setNestedScrollingEnabled(true);
}

我认为禁用滚动可能会将 recyclerview 锁定在当前位置,但它并没有向上跳。

我也尝试在调用 notifyDataSetChange 后获取垂直偏移并设置它,但我找不到以编程方式设置偏移的方法

编辑

适配器

class PickerAdapter extends RecyclerView.Adapter<PickerAdapter.PickerAdapterHolder>   {
public final String TAG = "PickerAdapter";

private ArrayList<PhotoBag> photoBag;
private Context context;

private OnClickListener onClickListener;


class PickerAdapterHolder extends RecyclerView.ViewHolder implements View.OnClickListener  {

    ImageView photo;
    ImageView imageBorder;

    PickerAdapterHolder(View view) {
        super(view);
        photo = (ImageView) view.findViewById(R.id.photoItem);
        photo.setOnClickListener(this);
    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.photoItem:
                FacebookPhotoPicker.onItemClick(getAdapterPosition()); //i know that there are better ways to get the clicked item from other class but since im still debuging i don't need to worry about performace i just need it to work
                break;
        }
    }
}

PickerAdapter(Context context, ArrayList<PhotoBag> itemList) {
    this.photoBag = itemList;
    this.context = context;
}


@Override
public PickerAdapterHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.facebook_picker_item, null);
    return new PickerAdapterHolder(layoutView);
}

@Override
public void onBindViewHolder(final PickerAdapterHolder holder, final int position) {
    if(photoBag.get(position).isSelected()){
        int border = Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, context.getResources().getDisplayMetrics()));

        Bitmap photo = photoBag.get(position).getPhoto();
        photo = Bitmap.createScaledBitmap(photo,photo.getWidth() - (border*2), photo.getHeight() - (border*2), false);
        photo = addWhiteBorder(photo,border);
        holder.photo.setImageBitmap(photo);
    }else {
        holder.photo.setImageBitmap(photoBag.get(position).getPhoto());
    }
}

@Override
public int getItemCount() {
    return this.photoBag.size();
}


private Bitmap addWhiteBorder(Bitmap bmp, int borderSize) {
    Bitmap bmpWithBorder = Bitmap.createBitmap(bmp.getWidth() + borderSize * 2, bmp.getHeight() + borderSize * 2, bmp.getConfig());
    Canvas canvas = new Canvas(bmpWithBorder);
    canvas.drawColor(Color.WHITE);
    canvas.drawBitmap(bmp, borderSize, borderSize, null);
    return bmpWithBorder;
}

【问题讨论】:

  • 如果我错了请纠正我,你的问题是让你在 recylerview 中有 10 个项目,现在你从 fb 添加新项目,现在添加项目后你的 recylerview 又回到第一个项目?
  • 我没有添加项目,当我点击一张照片时,我将其设置为选中,对不起,我会更新我的问题以使其更清楚,当我将其更新为选中时它会跳转到第一个
  • 您想在 RecyclerView 上突出显示所选项目吗?像thak这样的东西?
  • 是的,我可以这样做,但我不希望回收站上去,我会分享我的回收站课程,给我一秒钟
  • 我添加了我的适配器类

标签: android android-recyclerview


【解决方案1】:

从onItemClick中删除这两行

picker.setAdapter(adapter);
picker.scrollToPosition(position);

每次你setAdapter它都会重置位置,现在你不需要再次设置新位置。

这应该可以。如果没有,请检查我的这个答案(以及他们的 cmets)关于提供 ID How to remain at a scroll position in RecyclerView after adding items at its first index and call notifydatasetchange

【讨论】:

  • 解决了这个问题非常感谢,我认为我需要重置适配器
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-15
  • 2021-12-02
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多