RecyclerView布局管理器操作

时间:2017-05-30 06:46:19

标签: android android-recyclerview layout-manager

我有一个回收者视图应该显示如下数据(如果位置是偶数,则为1项,如果位置为奇数则为2项,并且老实说我尝试过但是我没有这样做。

这是它应该是什么样子

enter image description here

这就是现在的样子(忽略宽度和高度,看看视频3如何膨胀两次)

enter image description here

我正在使用LinearLayoutManager,而这是我的适配器:

public class MediaItemsAdapter extends RecyclerView.Adapter<MediaItemsAdapter.RecyclerViewHolder> {

private List<MediaItem> allMediaItems;
private Activity context;
private RecyclerViewOnItemClickListener itemClickListener;

public MediaItemsAdapter(Activity context, List<MediaItem> allMediaItems, RecyclerViewOnItemClickListener itemClickListener ) {

    this.allMediaItems = allMediaItems;
    this.context = context;
    this.itemClickListener = itemClickListener;
}

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

    MediaItem mediaItem = allMediaItems.get(position);

    if(position %2 == 0){ // even

        holder.tvTitle.setText(mediaItem.getTitle());
        holder.tvSummary.setText(mediaItem.getDate());

        try {
            Picasso.with(context)
                    .load(mediaItem.getImageUrl())
                    .into(holder.ivImage, new com.squareup.picasso.Callback() {
                        @Override
                        public void onSuccess() {
                            holder.ivImage.setAlpha((float) 1);
                        }

                        @Override
                        public void onError() {
                            Log.wtf("error", "in loading");
                        }
                    });

        } catch (Exception e) {
            e.printStackTrace();
        }

        holder.ivPlay.setVisibility(mediaItem.isVideo() ? View.VISIBLE : View.GONE);
    }else{ //odd

        holder.tvTitle.setText(mediaItem.getTitle());
        holder.tvSummary.setText(mediaItem.getDate());

        try {
            Picasso.with(context)
                    .load(mediaItem.getImageUrl())
                    .into(holder.ivImage, new com.squareup.picasso.Callback() {
                        @Override
                        public void onSuccess() {
                            holder.ivImage.setAlpha((float) 1);
                        }

                        @Override
                        public void onError() {
                            Log.wtf("error", "in loading");
                        }
                    });

        } catch (Exception e) {
            e.printStackTrace();
        }

        holder.ivPlay.setVisibility(mediaItem.isVideo() ? View.VISIBLE : View.GONE);

        try{

            MediaItem secondMediaItem = allMediaItems.get(position + 1);
            holder.tvSecondTitle.setText(secondMediaItem.getTitle());
            holder.tvSecondSummary.setText(secondMediaItem.getDate());

            try {
                Picasso.with(context)
                        .load(secondMediaItem.getImageUrl())
                        .into(holder.ivSecondImage, new com.squareup.picasso.Callback() {
                            @Override
                            public void onSuccess() {
                                holder.ivSecondImage.setAlpha((float) 1);
                            }

                            @Override
                            public void onError() {
                                Log.wtf("error", "in loading");
                            }
                        });

            } catch (Exception e) {
                e.printStackTrace();
            }

            holder.ivSecondPlay.setVisibility(secondMediaItem.isVideo() ? View.VISIBLE : View.GONE);
        }catch (Exception e){
            e.printStackTrace();
        }
    }

}

@Override
public int getItemViewType(int position) {
    return position %2 == 0 ? 0 : 1;
}

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


public interface RecyclerViewOnItemClickListener {
    void onItemClicked(View v, int position);
}

public RecyclerViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View layoutView;

    if (viewType == 0 ){

        layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.even_media_layout, parent, false);
        RecyclerViewHolder rcv = new RecyclerViewHolder(layoutView);
        return (rcv);
    }else{

        layoutView = LayoutInflater.from(parent.getContext()).inflate(R.layout.odd_media_layout, parent, false);
        RecyclerViewHolder rcv = new RecyclerViewHolder(layoutView);
        return (rcv);
    }
}

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

    private TextView tvTitle, tvSecondTitle, tvSummary, tvSecondSummary;
    private ImageView ivImage, ivSecondImage;
    private ImageButton ivPlay, ivSecondPlay;

    protected View itemView;

    public RecyclerViewHolder(View itemView) {
        super(itemView);
        this.itemView = itemView;
        this.itemView.setOnClickListener(this);

        tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
        tvSecondTitle = (TextView) itemView.findViewById(R.id.tvSecondTitle);
        tvSummary = (TextView) itemView.findViewById(R.id.tvSummary);
        tvSecondSummary = (TextView) itemView.findViewById(R.id.tvSecondSummary);

        ivImage = (ImageView) itemView.findViewById(R.id.ivImage);
        ivSecondImage = (ImageView) itemView.findViewById(R.id.ivSecondImage);

        ivPlay = (ImageButton) itemView.findViewById(R.id.ivPlay);
        ivSecondPlay = (ImageButton) itemView.findViewById(R.id.ivSecondPlay);
    }

    @Override
    public void onClick(View view) {
        itemClickListener.onItemClicked(view, getLayoutPosition());
    }
}
}

如何防止数据复制,如何告诉数组列表对象3已经被夸大了?有没有比LinearLayoutManager更好的方法

问候。

3 个答案:

答案 0 :(得分:1)

用户GridLayoutManage到您的RecyclerView并设置跨度大小查找。

    GridLayoutManager glm = new GridLayoutManager(this, 2, GridLayoutManager.VERTICAL, false);
    glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup(){

        @Override
        public int getSpanSize(int position) {
            return position % 3 == 0 ? 2 : 1;
        }
    });

答案 1 :(得分:0)

你的计算在这里出错了

return position %2 == 0 ? 0 : 1;

见这个

|0|
1|2
|3|
4|5
|6|
7|8

如果仔细观察物品的出现,则3的倍数的物品具有全宽。

所以基本上你的计算应该像

return position % 3 == 0 ? 0 : 1;

更多的解释,即使行有两个项目,但你正在计算偶数项目。

也要纠正这部分代码

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

    final int adapterPosition = holder.getAdapterPosition();
    MediaItem mediaItem = allMediaItems.get(adapterPosition);

    if(adapterPoaition % 3 == 0){ // every third item
       //your codes
    }
    //remaining codes
}

这里首先要考虑的是你应该使用适配器位置而不是作为参数传递的视图位置。接下来你必须在这里使用第三个位置而不是第二个

  

P.S。您的适配器代码有点乱,不确定是否纠正   这个计算会给你正确的结果,直到你这样做   小代码清理。

答案 2 :(得分:0)

我建议您使用适配器代理,显然您可以在没有它的情况下执行此操作,但它可以帮助您进一步开发。

Here你可以阅读它

你应该在isForViewType()中根据提供的条件return position % 2 == 1创建2个委托,并在onCreateViewHolder()返回相关的ViewHolder(你将有2个)