首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >StaggeredGridLayoutManager和移动项目

StaggeredGridLayoutManager和移动项目
EN

Stack Overflow用户
提问于 2014-12-24 12:32:21
回答 8查看 27K关注 0票数 27

我创建了一个非常简单的项目,通过回收视图用StaggeredGridLayoutManager显示了28张图片。但是当我滚动回收视图时,它会将物品从左向右移动,或者交换左和右的列。

代码:

代码语言:javascript
复制
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);

    }

} 

适配器:

代码语言:javascript
复制
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);

    }

}

以及一个样本移动项目:

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

如果你玩(上下滚动),你会发现更有趣的动画:-)

如何防止这种情况,并有稳定的布局,像一个普通的列表视图?

编辑

代码语言:javascript
复制
@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());
}
EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2014-12-31 09:38:11

之所以发生这种情况,是因为SGLM没有保存任何有关视图的w/h信息。因此,每次视图是反弹,它得到的地方持有人的大小首先,然后最后的大小时,图像被加载。

加载实际图像w/不同大小(比位置保持器)触发一个新的布局请求,而在该布局请求期间,SGLM检测到UI中会出现空白(或者某个项目w/较高位置出现在项目w/较低位置下面),从而重新排序项目w/ a动画。

您可以通过将您的位置持有者图像设置为实际图像的维度来避免这种情况。如果您没有提前使用它,则可以在第一次加载映像后保存它们,并在下一个onBind调用中使用它。

票数 19
EN

Stack Overflow用户

发布于 2016-03-02 13:14:57

当我使用StaggeredGridLayoutManager时,对我起作用的是禁用循环视图上的所有动画。

mRecyclerView.setItemAnimator(null);

如果只想限制移动动画并保留添加和删除项动画,则可以创建自己的动画器。

票数 20
EN

Stack Overflow用户

发布于 2016-10-24 08:05:46

你可以试试这个

代码语言:javascript
复制
    StaggeredGridLayoutManager manager = new StaggeredGridLayoutManager(2, OrientationHelper.VERTICAL);
    manager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_NONE);
    mRecyclerView.setLayoutManager(manager);

设置这个之后,当你滚动到顶部时,你会发现顶部有一个空白。继续设置这个

代码语言:javascript
复制
    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
            ((StaggeredGridLayoutManager)recyclerView.getLayoutManager()).invalidateSpanAssignments();
        }
    });

这是我的工作,我从这条路走过来。我希望它能帮到你!

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27636999

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档