【问题标题】:Android RecyclerView StaggeredGrid items change position when scrolling topAndroid RecyclerView StaggeredGrid 项目在滚动顶部时更改位置
【发布时间】:2016-03-20 07:16:52
【问题描述】:

在我的带有 2 列的交错网格中,我使用无限列表的效果来自动加载 10 x 10 的元素,除了向上滚动时,一切正常。前两个元素改变了它们的位置。就像前两项从一列跳到另一列。

正如我所读,适配器必须保存每个元素的状态。但是,我不知道该怎么做。

这是我用来显示 StaggeredGrid 功能的主要代码

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

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

    @Override
    public void getItemOffsets(Rect outRect, View view,
                               RecyclerView parent, RecyclerView.State state) {
        outRect.left = space;
        outRect.right = space;
        outRect.bottom = space+1;

        // Add top margin only for the first item to avoid double space between items
        if(parent.getChildLayoutPosition(view) == 0)
            outRect.top = space;
    }
}

public class SolventViewHolders extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView vh_name;
    public TextView vh_price;
    public ImageView vh_image;

    public SolventViewHolders(View v) {
        super(v);
        v.setOnClickListener(this);

        vh_image=(ImageView)v.findViewById(R.id.thumbnail);
        vh_name= (TextView) v.findViewById(R.id.title);
        vh_price= (TextView) v.findViewById(R.id.subtitle);
    }

    public void sendImage(String url) {
        Picasso.with(ctx)
                .load(url)
                .into(vh_image);
    }
    @Override
    public void onClick(View view) {
        int position = getPosition();

        if (user_id != null) {

            openDetail(MyLogs.get(position).getId_item(), MyLogs.get(position).getItemName(), MyLogs.get(position).getPrice(), MyLogs.get(position).getDescrip(), MyLogs.get(position).getId_store(), MyLogs.get(position).getId_store());
        }
    }
}

public class SolventRecyclerViewAdapter  extends RecyclerView.Adapter<SolventViewHolders> {


    private List<productItem> itemList;
    private Context context;

    public SolventRecyclerViewAdapter(Context context, List<productItem> itemList) {
        this.itemList = itemList;
        this.context = context;
    }
    @Override
    public SolventViewHolders onCreateViewHolder(ViewGroup parent, int viewType) {

        View layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_mosaico_defoult, null);
        SolventViewHolders rcv = new SolventViewHolders(layoutView);

        return rcv;
    }

    @Override
    public void onBindViewHolder(SolventViewHolders holder, int position) {

        holder.vh_name.setText(itemList.get(position).getName());
        holder.vh_price.setText("CLP:"+itemList.get(position).getPrice());

    }

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

#编辑 1:

这就是我实例化适配器的方式

 recyclerView = (RecyclerView)view.findViewById(R.id.recycler_view);
    recyclerView.setHasFixedSize(true);

    gaggeredGridLayoutManager = new StaggeredGridLayoutManager(2, 1);
    recyclerView.setLayoutManager(gaggeredGridLayoutManager);
    recyclerView.addItemDecoration(new SpacesItemDecoration(2));

    populateList(currentPage);

    rcAdapter= new SolventRecyclerViewAdapter(ctx, MyLogs);
    recyclerView.setAdapter(rcAdapter);

populate 方法以 json 格式的异步任务响应形式发生:

                            ...
            for(int i=0; i < lengthJsonArr; i++)
            {

                JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);

                           ...

                MyLogs.add("name,price,etc");
                rcAdapter.notifyDataSetChanged();

            }

这就是我持有 onScroll 的方式:

 recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {

            visibleItemCount = gaggeredGridLayoutManager.getChildCount();
            totalItemCount = gaggeredGridLayoutManager.getItemCount();
            int[] firstVisibleItems = null;
            firstVisibleItems = gaggeredGridLayoutManager.findFirstVisibleItemPositions(firstVisibleItems);
            if (firstVisibleItems != null && firstVisibleItems.length > 0) {
                pastVisiblesItems = firstVisibleItems[0];
            }

            if (loading) {
                if ((visibleItemCount + pastVisiblesItems) >= totalItemCount) {
                    loading= false;
                    Log.d("tag", "LOAD NEXT ITEM");
                    currentPage = currentPage + 1;
                    populateList(currentPage);
                }
            }
        }
    });

感谢您的帮助

【问题讨论】:

  • 如何将元素添加到数据列表中?显示用于实例化适配器以及使用新项目更新适配器的代码。您说您正在实现它以使其使用无限滚动(但是没有方法可以将数据添加到支持您的回收器适配器的数据结构中”
  • Sebastian,我也遇到了同样的问题,你有没有比bleeding182 提出的更好的解决方案?
  • @Rxxxx 不,这是我找到的唯一解决方案。如果你找到另一个,请让我现在

标签: android android-recyclerview vertical-scrolling staggered-gridview


【解决方案1】:

发生这种情况是因为当您上下滚动时,支架无法识别图像视图的宽度和高度。当您向下滚动时,它会清除上视图,反之亦然。

这样使用:

@Override
public void onBindViewHolder(ViewHolder viewHolder, int position) {

MyViewHolder vh = (MyViewHolder) viewHolder;
ImageModel item = imageModels.get(position);
RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams)vh.imageView.getLayoutParams();
float ratio = item.getHeight() / item.getWidth();
rlp.height = (int) (rlp.width * ratio);
vh.imageView.setLayoutParams(rlp);
vh.positionTextView.setText("pos: " + position);
vh.imageView.setRatio(item.getRatio());
Picasso.with(mContext).load(item.getUrl()).
placeholder(PlaceHolderDrawableHelper.getBackgroundDrawable(position)).
into(vh.imageView);
}

要清楚,请参阅此链接:Picasso/Glide-RecyclerView-StaggeredGridLayoutManager

【讨论】:

    【解决方案2】:

    这是一项功能。重新排序和重新定位视图以获得无缝的项目流。

    使用setGapStrategy(int gapStrategy)

    为 StaggeredGridLayoutManager 设置间隙处理策略。如果 gapStrategy 参数与当前策略不同,调用该方法会触发布局请求。

    你可能会想要GAP_HANDLING_NONE

    不做任何事情来隐藏差距。

    【讨论】:

    • 是的,这行得通,但现在滚动在前两个元素之间留下了空间差异。似乎有一列在另一列下方。 ¿这是唯一的解决方案?
    • ...你可以只使用网格布局吗?
    猜你喜欢
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多