ViewPager+RecyclerView联动

来源:互联网 发布:淘宝店铺618活动策划 编辑:程序博客网 时间:2024/06/04 01:08

ViewPager 和 RecyclerView 联动估计很多朋友都遇到过,ViewPager 带动 RecyclerView 很简单,头疼的是 RecyclerView 点击 item 不仅要带动 ViewPager,还要更换背景、或者更换 item 中文字或图片。好了,废话不多说,上菜。


1.ViewPager 带动 RecyclerView

ViewPager 和 RecyclerView 的简单声明和设置我就不细说了,至于 RecyclerView 是横的还是竖的也都是 setLayoutManager 就可以搞定的事。

我们先看 ViewPager 带动 RecyclerView 的 代码:

pager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {    @Override    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {    }    @Override    public void onPageSelected(int position) {        emoji_recycler.smoothScrollToPosition(position);        recyclerAdapter.setClickPosition(position);    }    @Override    public void onPageScrollStateChanged(int state) {    }});

是不是很简单?只要在 ViewPager 滑动的监听中加上:emoji_recycler.smoothScrollToPosition(position) 就可以让 ViewPager 滑到哪里,RecyclerView 显示那个 item 了。至于后面的 recyclerAdapter.setClickPosition(position) 代码部分,我们等会再说。


2.RecyclerView带动ViewPager

RecyclerView 很奇葩,不能设置 onItemClickListener,但是没关系,我们可以自己搞定,就在 Adapter 中加上接口回调。代码如下:

public class EmojiRecyclerAdapter extends RecyclerView.Adapter {    public interface OnItemClickListener {        void onItemClick(int position);    }    private OnItemClickListener onItemClickListener;    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {        this.onItemClickListener = onItemClickListener;    }        ......}

为什么要加上 position 这个参数呢? 原因很简单,联动至少需要知道点击的是哪里吧?!那么,问题又来了:position 在哪获取呢??答:既然是回调,那么就在 Adapter 中获取,代码如下:

@Override    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {        if (onItemClickListener != null) {            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    onItemClickListener.onItemClick(holder.getLayoutPosition());                }            });        }    }

分析上面的代码:点击这个 itemView,就会调用外部传入的 onItemClickListener 中的 onItemClick() 方法。(说的可能不清楚,但是我还是希望有些不完全了解接口回调机制的小伙伴能够看懂。)

好的,接下来我们看外部是如何传来 onItemClickListener 的了,在 Activity 中有如下代码:

  recyclerAdapter.setOnItemClickListener(new EmojiRecyclerAdapter.OnItemClickListener() {            @Override            public void onItemClick(int position) {                pager.setCurrentItem(position);                recyclerAdapter.setClickPosition(position);                recyclerAdapter.notifyDataSetChanged();            }        });

好了!到这里pager.setCurrentItem(position) 就让我们实现了 RecyclerView 联动 ViewPager 了,这个 position 就是 Adapter 中给我们的 position。而后面的 recyclerAdapter.setClickPosition(position) 代码部分是关于 RecyclerView 点击 item 变化图片的操作。


3.RecyclerView 点击 item 变化图片

上面的灰色代码部分:recyclerAdapter.setClickPosition(position),下面我们看 Adapter 中的代码:

    private int click_position;    public void setClickPosition(int position) {        this.click_position = position;        notifyDataSetChanged();    }
click_position 即点击的位置,用途是:如果点击的位置和 item 中某个位置一样,就改变其图片(表示选中),不一样就取消选中状态。代码如下:

    @Override    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {        Drawable drawable = context.getResources().getDrawable(pics.get(position));        ((MyViewHolder) holder).imageView.setImageDrawable(drawable);        if (position == click_position) {            ((MyViewHolder) holder).imageView.setSelected(true);        } else {            ((MyViewHolder) holder).imageView.setSelected(false);        }    }
drawable 中代码如下:

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android">    <item android:drawable="@mipmap/preview0_pressed" android:state_selected="true" />    <item android:drawable="@mipmap/preview0" android:state_selected="false" /></selector>

4.总结

运行结果如下(没有模拟器,真机又没有录屏功能,只好麻烦各位将就看了,能看到结果就行,哈哈。)


Adapter 中完整代码如下:

public class EmojiRecyclerAdapter extends RecyclerView.Adapter {    private int click_position;    public void setClickPosition(int position) {        this.click_position = position;        notifyDataSetChanged();    }    public interface OnItemClickListener {        void onItemClick(int position);    }    private OnItemClickListener onItemClickListener;    public void setOnItemClickListener(OnItemClickListener onItemClickListener) {        this.onItemClickListener = onItemClickListener;    }    private List<Integer> pics;    private Context context;    private LayoutInflater inflater;    public EmojiRecyclerAdapter(List<Integer> pics, Context context) {        this.pics = pics;        this.context = context;        inflater = LayoutInflater.from(context);    }    @Override    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {        View view = inflater.inflate(R.layout.item_recycler, parent, false);        return new MyViewHolder(view);    }    @Override    public void onBindViewHolder(final RecyclerView.ViewHolder holder, int position) {        Drawable drawable = context.getResources().getDrawable(pics.get(position));        ((MyViewHolder) holder).imageView.setImageDrawable(drawable);        if (position == click_position) {            ((MyViewHolder) holder).imageView.setSelected(true);        } else {            ((MyViewHolder) holder).imageView.setSelected(false);        }        if (onItemClickListener != null) {            holder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    onItemClickListener.onItemClick(holder.getLayoutPosition());                }            });        }    }    @Override    public long getItemId(int position) {        return position;    }    @Override    public int getItemCount() {        return pics.size();    }    private class MyViewHolder extends RecyclerView.ViewHolder {        ImageView imageView;        MyViewHolder(View itemView) {            super(itemView);            imageView = (ImageView) itemView.findViewById(R.id.img_item);        }    }}

MainActivity 中的主要代码就那两个监听,我就不贴了。

如果有错的地方或者更好的写法,希望大家批评指正,共同进步!大笑





原创粉丝点击