StaggeredGridLayoutManager和移动项目 [英] StaggeredGridLayoutManager and moving items

查看:1827
本文介绍了StaggeredGridLayoutManager和移动项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一个非常简单的项目,由recyclerview显示28幅影像与 StaggeredGridLayoutManager 。但是当我滚动recyclerview它移动的物品,例如从左至右或交换左侧和右侧的列。

codeS:

 进口的java.util.ArrayList;
进口的java.util.List;

进口android.app.Activity;
进口android.os.Bundle;
进口android.support.v7.widget.RecyclerView;
进口android.support.v7.widget.StaggeredGridLayoutManager;


公共类MainActivity延伸活动{


    字符串mImageDir;
    私人RecyclerView mRecyclerView;
    私人StaggeredGridLayoutManager mLayoutManager;



    MyRecyclerAdapter myRecyclerAdapter;
    名单< ImageModel> mImageList;

    @覆盖
    保护无效的onCreate(包savedInstanceState){

        super.onCreate(savedInstanceState);
        的setContentView(R.layout.activity_main);
        mRecyclerView =(RecyclerView)findViewById(R.id.recyclerview_rootview);
        mLayoutManager =新StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);
        mLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setHasFixedSize(假);
        mImageList =新的ArrayList< ImageModel>();
        的for(int i = 1; I< 29;我++){
            ImageModel IMG =新ImageModel();
            img.setTitle(图像无+ I);
            INT drawableResourceId = this.getResources()则getIdentifier(形象+将String.valueOf(我),绘制,this.getPackageName())。
            img.setResId(drawableResourceId);
            mImageList.add(IMG);

        }
        myRecyclerAdapter =新MyRecyclerAdapter(MainActivity.this,mImageList);
        mRecyclerView.setAdapter(myRecyclerAdapter);

    }

}
 

和适配器:

 公共类MyRecyclerAdapter扩展RecyclerView.Adapter< MyRecyclerAdapter.ViewHolder> {


    私人列表< ImageModel> mItems;
    语境mContext;

    公共MyRecyclerAdapter(上下文的背景下,名单,其中,ImageModel>对象){
        mContext =背景;
        mItems =物体;

    }

    静态类ViewHolder扩展RecyclerView.ViewHolder {
        公共ImageView的mImageView;
        公众的TextView mTextView;
        公众查看rootView;
        公共ViewHolder(查看ItemView控件){
            超(ItemView控件);
            rootView = ItemView控件;
            mImageView =(ImageView的)itemView.findViewById(R.id.image);
            mTextView =(TextView中)itemView.findViewById(R.id.title);
        }
    }

    @覆盖
    公众诠释getItemCount(){

        返回mItems.size();
    }

    @覆盖
    公共无效onBindViewHolder(ViewHolder持有人,INT位置){

        ImageModel项目= mItems.get(位置);
        Picasso.with(mContext).load(item.getResId())到(holder.mImageView)。
        holder.mTextView.setText(item.getTitle());
    }


    @覆盖
    公共ViewHolder onCreateViewHolder(ViewGroup中的父母,INT ARG1){
        LayoutInflater充气=
                (LayoutInflater)mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        查看convertView = inflater.inflate(R.layout.item,父母,假);
        返回新ViewHolder(convertView);

    }

}
 

和采样运动项目:

http://i.imgur.com/FUapm2K.gif?1

如果你玩(上下卷),你可以发现更多有趣的动画: - )

如何prevent这一点,有一个像一个普通的列表视图稳定的布局?

修改

  @覆盖
公共无效onBindViewHolder(ViewHolder持有人,INT位置){

    ImageModel项目= mItems.get(位置);
    RelativeLayout.LayoutParams RLP =(RelativeLayout.LayoutParams)holder.mImageView.getLayoutParams();
    流通股比例= item.getHeight()/ item.getWidth();
    rlp.height =(int)的(rlp.width *比);
    holder.mImageView.setLayoutParams(RLP);
    Picasso.with(mContext).load(item.getResId())到(holder.mImageView)。
    holder.mTextView.setText(item.getTitle());
}
 

解决方案

这是发生因为SGLM不保留任何与W有关意见/ h的信息。因此,每次视图是反弹,它得到了占位尺寸,然后再当图像被加载的最终尺寸。

中的实际图像瓦特/不同大小(比占位)触发一个新的布局的请求,并且该布局请求期间,SGLM检测会有在UI间隙(或某些项目瓦特/高的位置下面显示的项因此W /较低的位置)重新排序项瓦特/动画。

您可以通过您的占位符图像设置为实际图像的尺寸避免它。如果你没有拥有它的时间提前,可以将它们保存后的图像加载的第一次,并用它在未来的onBind电话。

I have created a very simple project, displaying 28 images with StaggeredGridLayoutManager by recyclerview. but as I scroll the recyclerview it moves items for example from left to right or swap the column of left and right.

codes:

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;


public class MainActivity extends Activity {


    String mImageDir;
    private RecyclerView mRecyclerView;
    private StaggeredGridLayoutManager mLayoutManager;



    MyRecyclerAdapter myRecyclerAdapter;
    List<ImageModel> mImageList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);   
        mRecyclerView = (RecyclerView)findViewById(R.id.recyclerview_rootview);
        mLayoutManager = new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL);     
        mLayoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);        
        mRecyclerView.setLayoutManager(mLayoutManager);
        mRecyclerView.setHasFixedSize(false);
        mImageList = new ArrayList<ImageModel>();
        for (int i = 1; i < 29 ; i++) {
            ImageModel img = new ImageModel();
            img.setTitle("Image No " + i);
            int drawableResourceId = this.getResources().getIdentifier("image"+String.valueOf(i), "drawable", this.getPackageName());
            img.setResId(drawableResourceId);
            mImageList.add(img);

        }
        myRecyclerAdapter = new MyRecyclerAdapter(MainActivity.this,mImageList);        
        mRecyclerView.setAdapter(myRecyclerAdapter);

    }

} 

And the adapter:

public class MyRecyclerAdapter extends RecyclerView.Adapter<MyRecyclerAdapter.ViewHolder> {


    private List<ImageModel> mItems;
    Context mContext;

    public MyRecyclerAdapter(Context context,List<ImageModel> objects) {
        mContext = context;
        mItems = objects;

    }

    static class ViewHolder extends RecyclerView.ViewHolder{
        public  ImageView mImageView;
        public  TextView mTextView;
        public View rootView;
        public ViewHolder(View itemView) {
            super(itemView);
            rootView = itemView;
            mImageView =(ImageView)itemView.findViewById(R.id.image);
            mTextView =(TextView)itemView.findViewById(R.id.title);
        }
    }

    @Override
    public int getItemCount() {

        return mItems.size();
    }

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

        ImageModel item = mItems.get(position); 
        Picasso.with(mContext).load(item.getResId()).into(holder.mImageView);
        holder.mTextView.setText(item.getTitle());
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int arg1) {
        LayoutInflater inflater =    
                (LayoutInflater) mContext.getSystemService(Activity.LAYOUT_INFLATER_SERVICE);
        View convertView = inflater.inflate(R.layout.item, parent, false);
        return new ViewHolder(convertView);

    }

}

and a sample moving item:

http://i.imgur.com/FUapm2K.gif?1

if you play (scroll up and down) you can discover more interesting animation :-)

How to prevent that and having stable layout like an ordinary listview?

Edit

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

    ImageModel item = mItems.get(position);
    RelativeLayout.LayoutParams rlp = (RelativeLayout.LayoutParams)holder.mImageView.getLayoutParams();
    float ratio = item.getHeight()/item.getWidth();
    rlp.height = (int)(rlp.width * ratio);
    holder.mImageView.setLayoutParams(rlp);
    Picasso.with(mContext).load(item.getResId()).into(holder.mImageView);
    holder.mTextView.setText(item.getTitle());
}

解决方案

This is happening because SGLM does not keep any w/h information about the views. So each time a View is rebound, it gets the place holder size first and then the final size when the image is loaded.

Loading the actual image w/ different size (than place holder) triggers a new layout request, and during that layout request, SGLM detects that there will be gaps in the UI (or some item w/ higher position appears below an item w/ lower position) thus re-orders items w/ an animation.

You can avoid it by setting your place holder image to the dimensions of the actual image. If you don't have it ahead of time, you can save them after the image is loaded for the first-time and use it in the next onBind call.

这篇关于StaggeredGridLayoutManager和移动项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆