简体   繁体   English

滚动顶部时,Android RecyclerView StaggeredGrid项目会改变位置

[英]Android RecyclerView StaggeredGrid items change position when scrolling top

In my Staggered Grid with 2 columns I use the effect of infinite list to automatically load elements 10 by 10, everything works fine except when I scroll up. 在我的Staggered Grid中有2列,我使用无限列表的效果自动加载元素10乘10,一切正常,除非我向上滚动。 The first two elements change their position. 前两个元素改变了他们的立场。 It is like the first two items jump from one column to another. 就像前两个项目从一列跳到另一列。

As I read, the adapter must save the state of each element. 在我阅读时,适配器必须保存每个元素的状态。 But, I do not know how to do it. 但是,我不知道该怎么做。

This is the main code that I use to display the StaggeredGrid functionality 这是我用来显示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();
    }
}

#Edit 1: #Edit 1:

This is how I instanciate the adapter 这就是我实现适配器的方式

 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);

The populate method happens as an asyntask response that comes in json format: populate方法作为以json格式提供的asyntask响应发生:

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

                JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);

                           ...

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

            }

And this is how i hold the onScroll: 这就是我持有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);
                }
            }
        }
    });

I appreciate any help 我感谢任何帮助

This is a feature. 这是一个功能。 Reordering and repositioning view for a seamless tream of items. 重新排序和重新定位视图的无缝tream项目。

Use setGapStrategy(int gapStrategy) 使用setGapStrategy(int gapStrategy)

Sets the gap handling strategy for StaggeredGridLayoutManager. 设置StaggeredGridLayoutManager的间隙处理策略。 If the gapStrategy parameter is different than the current strategy, calling this method will trigger a layout request. 如果gapStrategy参数与当前策略不同,则调用此方法将触发布局请求。

You will probably want GAP_HANDLING_NONE . 您可能需要GAP_HANDLING_NONE

Does not do anything to hide gaps. 没有做任何隐藏差距的事情。

This happens because the holder dose not recognize the width and height of the Image view when you scroll up and down. 发生这种情况是因为当您向上和向下滚动时,持有者无法识别图像视图的宽度和高度。 It clears the upper view when you scroll down and vice versa. 当您向下滚动时它会清除上部视图,反之亦然。

Use like this : 使用这样:

@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);
}

For clear see this link: Picasso/Glide-RecyclerView-StaggeredGridLayoutManager 要清楚,请参阅此链接: Picasso / Glide-RecyclerView-StaggeredGridLayoutManager

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM