应用RecyclerView实现Gallery相册效果——注意引入recyclerview-v7的版本

来源:互联网 发布:mac开启root权限 编辑:程序博客网 时间:2024/06/07 12:43

整理总结自鸿洋的博客:http://blog.csdn.net/lmj623565791/article/details/38173061/

一、初次使用RecyclerView实现”适配器“的功能

1、MainActivity.java

public class MainActivity extends Activity {    private RecyclerView mRecyclerView;    private GalleryAdapter mAdapter;    private List<Integer> mDatas;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        //获得数据        initDatas();        //得到控件        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview_horizontal);        //设置布局管理器        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);        mRecyclerView.setLayoutManager(linearLayoutManager);        //设置适配器        mAdapter = new GalleryAdapter(this, mDatas);        mRecyclerView.setAdapter(mAdapter);    }    private void initDatas() {        mDatas = new ArrayList<Integer>(Arrays.asList(R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f, R.mipmap.g, R.mipmap.h, R.mipmap.l));    }}


2、activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent">    <android.support.v7.widget.RecyclerView        android:id="@+id/id_recyclerview_horizontal"        android:layout_width="match_parent"        android:layout_height="120dp"        android:layout_centerVertical="true"        android:background="#FF0000"        android:scrollbars="none" /></RelativeLayout>


3、activity_index_gallery_item.xml

<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="120dp"    android:layout_height="120dp"    android:background="@drawable/item_bg02">    <ImageView        android:id="@+id/id_index_gallery_item_image"        android:layout_width="80dp"        android:layout_height="80dp"        android:layout_alignParentTop="true"        android:layout_centerHorizontal="true"        android:layout_margin="5dp"        android:scaleType="centerCrop" />    <TextView        android:id="@+id/id_index_gallery_item_text"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@id/id_index_gallery_item_image"        android:layout_centerHorizontal="true"        android:layout_marginBottom="5dp"        android:layout_marginTop="5dp"        android:text="some info"        android:textColor="#ff0000"        android:textSize="12dp" /></RelativeLayout>


4、GalleryAdapter.java

/** * Created by jiatao on 2016/06/14 18:26 * Description: 应用RecyclerView的适配器 */public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.ViewHolder> {    private LayoutInflater mInflater;    private List<Integer> mDatas;    public GalleryAdapter(Context context, List<Integer> datats) {        mInflater = LayoutInflater.from(context);        mDatas = datats;    }    /**     * 创建内部静态类,必须继承RecyclerView.ViewHolder。承上启下。     * 上:RecyclerView.Adapter<GalleryAdapter.ViewHolder>     * 下:ViewHolder viewHolder = new ViewHolder(view);     * 详细说明:     *      我们创建的ViewHolder必须继承RecyclerView.ViewHolder,这个RecyclerView.ViewHolder在构造时必须传入一个View,     *      这个View相当于我们ListView getView中的convertView (即:把我们需要inflate的item布局传入)     */    public static class ViewHolder extends RecyclerView.ViewHolder {        ImageView mImg;        TextView mTxt;        public ViewHolder(View view) {            super(view);        }    }    /**     * 获取总条目数,同BaseAdapter     */    @Override    public int getItemCount() {        return mDatas.size();    }    /**     * 创建ViewHolder     */    @Override    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {        View view = mInflater.inflate(R.layout.activity_index_gallery_item, viewGroup, false);        ViewHolder viewHolder = new ViewHolder(view);        viewHolder.mImg = (ImageView) view.findViewById(R.id.id_index_gallery_item_image);        return viewHolder;    }    /**     * 将数据绑定到ViewHolder     */    @Override    public void onBindViewHolder(final ViewHolder viewHolder, final int i) {        viewHolder.mImg.setImageResource(mDatas.get(i));    }}


二、为RecyclerView添加OnItemClickListener回调

1、MainActivity.java

public class MainActivity extends Activity {    private RecyclerView mRecyclerView;    private GalleryAdapter mAdapter;    private List<Integer> mDatas;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        initDatas();//获得数据        initView(); //初始化视图    }    private void initDatas() {        mDatas = new ArrayList<Integer>(Arrays.asList(R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f, R.mipmap.g, R.mipmap.h, R.mipmap.l));    }    private void initView() {        //得到控件        mRecyclerView = (RecyclerView) findViewById(R.id.id_recyclerview_horizontal);        //设置布局管理器        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);        mRecyclerView.setLayoutManager(linearLayoutManager);        //设置适配器        mAdapter = new GalleryAdapter(this, mDatas);        //添加点击监听        mAdapter.setmOnItemClickListener(new GalleryAdapter.OnItemClickListener() {            @Override            public void itemClick(View view, int position) {                Toast.makeText(MainActivity.this, position+"", Toast.LENGTH_SHORT).show();            }        });        mRecyclerView.setAdapter(mAdapter);    }}


2、activity_main.xml

同上

3、activity_index_gallery_item.xml

同上

4、GalleryAdapter.java

/** * Created by jiatao on 2016/06/15 7:26 * Description: 应用RecyclerView的适配器 *  添加OnItemClickListener回调接口,实现对条目的点击事件 */public class GalleryAdapter extends RecyclerView.Adapter<GalleryAdapter.ViewHolder> {    /**********************添加OnItemClickListener回调接口↓↓******************************/    public interface OnItemClickListener{        void itemClick(View view, int position);    }    private OnItemClickListener mOnItemClickListener;    public void setmOnItemClickListener(OnItemClickListener listener){        this.mOnItemClickListener = listener;    }    /**********************添加OnItemClickListener回调接口↑↑******************************/    private LayoutInflater mInflater;    private List<Integer> mDatas;    public GalleryAdapter(Context context, List<Integer> datats) {        mInflater = LayoutInflater.from(context);        mDatas = datats;    }    /**     * 创建内部静态类,必须继承RecyclerView.ViewHolder。承上启下。     * 上:RecyclerView.Adapter<GalleryAdapter.ViewHolder>     * 下:ViewHolder viewHolder = new ViewHolder(view);     * 详细说明:     *      我们创建的ViewHolder必须继承RecyclerView.ViewHolder,这个RecyclerView.ViewHolder在构造时必须传入一个View,     *      这个View相当于我们ListView getView中的convertView (即:把我们需要inflate的item布局传入)     */    public static class ViewHolder extends RecyclerView.ViewHolder {        ImageView mImg;        TextView mTxt;        public ViewHolder(View view) {            super(view);        }    }    /**     * 获取总条目数,同BaseAdapter     */    @Override    public int getItemCount() {        return mDatas.size();    }    /**     * 创建ViewHolder     */    @Override    public ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {        View view = mInflater.inflate(R.layout.activity_index_gallery_item, viewGroup, false);        ViewHolder viewHolder = new ViewHolder(view);        viewHolder.mImg = (ImageView) view.findViewById(R.id.id_index_gallery_item_image);        return viewHolder;    }    /**     * 将数据绑定到ViewHolder     */    @Override    public void onBindViewHolder(final ViewHolder viewHolder, final int position) {        viewHolder.mImg.setImageResource(mDatas.get(position));        //如果设置了点击事件的回调        if(mOnItemClickListener != null){            viewHolder.itemView.setOnClickListener(new View.OnClickListener() {                @Override                public void onClick(View v) {                    mOnItemClickListener.itemClick(viewHolder.itemView, position);                }            });        }    }}


三、自定义RecyclerView实现滚动时内容联动

1、MainActivity.java

public class MainActivity extends Activity {    private GalleryAdapter mAdapter;    private ImageView id_content;    private CustomRecyclerView mCustomRecyclerView;    private List<Integer> mDatas;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        initDatas();//获得数据        initView();//初始化视图    }    private void initDatas() {        mDatas = new ArrayList<Integer>(Arrays.asList(R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f, R.mipmap.g, R.mipmap.h, R.mipmap.l));    }    private void initView() {        //得到控件        id_content = (ImageView) findViewById(R.id.id_content);        mCustomRecyclerView = (CustomRecyclerView) findViewById(R.id.id_recyclerview_horizontal);        //设置布局管理器        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);        mCustomRecyclerView.setLayoutManager(linearLayoutManager);        //设置适配器        mAdapter = new GalleryAdapter(this, mDatas);        //添加点击监听        mAdapter.setOnItemClickListener(new GalleryAdapter.OnItemClickListener() {            @Override            public void itemClick(View v, int position) {                Toast.makeText(MainActivity.this, position+"", Toast.LENGTH_SHORT).show();            }        });        mCustomRecyclerView.setAdapter(mAdapter);        //添加滑动监听        mCustomRecyclerView.setOnItemScrollChangeListener(new CustomRecyclerView.OnItemScrollChangeListener() {            @Override            public void onChange(View view, int position) {                 id_content.setImageResource(mDatas.get(position));            }        });    }}


2、activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <FrameLayout        android:layout_width="fill_parent"        android:layout_height="0dp"        android:layout_weight="1">        <ImageView            android:id="@+id/id_content"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:layout_gravity="center"            android:layout_margin="10dp"            android:scaleType="centerCrop" />    </FrameLayout>    <com.cctvjiatao.recyclerviewgallery.view.CustomRecyclerView        android:id="@+id/id_recyclerview_horizontal"        android:layout_width="match_parent"        android:layout_height="120dp"        android:layout_gravity="bottom"        android:background="#FF0000"        android:scrollbars="none" /></LinearLayout>


3、activity_index_gallery_item.xml

同上

4、GalleryAdapter.java

同上

5、CustomRecyclerView.java

/** * Created by jiatao on 2016/06/15 09:55 * Description: 自定义RecyclerView */public class CustomRecyclerView extends RecyclerView {    private View mCurrentView;    public CustomRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);    }    /**********************添加OnItemScrollChangeListener回调接口相关↓↓******************************/    //定义一个滚动时回调的接口,然后在onTouchEvent中,监听ACTION_MOVE,用户手指滑动时,不断地把当前第一个View回调回去    public interface OnItemScrollChangeListener {        void onChange(View view, int position);    }    private OnItemScrollChangeListener mItemScrollChangeListener;    public void setOnItemScrollChangeListener(OnItemScrollChangeListener listener) {        this.mItemScrollChangeListener = listener;    }    /**********************添加OnItemScrollChangeListener回调接口相关↑↑******************************/    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        mCurrentView = getChildAt(0);        if (mItemScrollChangeListener != null) {            mItemScrollChangeListener.onChange(mCurrentView, getChildLayoutPosition(mCurrentView));//Android 6.0中View.getChildPosition()过时,更新为View.getChildLayoutPosition        }    }    @Override    public boolean onTouchEvent(MotionEvent e) {        if (e.getAction() == MotionEvent.ACTION_MOVE) {            mCurrentView = getChildAt(0);            // Log.e("TAG", getChildLayoutPosition(getChildAt(0)) + "");            if (mItemScrollChangeListener != null) {                mItemScrollChangeListener.onChange(mCurrentView, getChildLayoutPosition(mCurrentView));//Android 6.0中View.getChildPosition()过时,更新为View.getChildLayoutPosition            }        }        return super.onTouchEvent(e);    }}


四、优化与打造真正的Gallery效果效果—— 所用jar包是 recyclerview-v7:23.3.0

1、MainActivity.java

public class MainActivity extends Activity {    private GalleryAdapter mAdapter;    private ImageView id_content;    private CustomRecyclerView mCustomRecyclerView;    private List<Integer> mDatas;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        requestWindowFeature(Window.FEATURE_NO_TITLE);        setContentView(R.layout.activity_main);        initDatas();//获得数据        initView();//初始化视图    }    private void initDatas() {        mDatas = new ArrayList<Integer>(Arrays.asList(R.mipmap.a, R.mipmap.b, R.mipmap.c, R.mipmap.d, R.mipmap.e, R.mipmap.f, R.mipmap.g, R.mipmap.h, R.mipmap.l));    }    private void initView() {        //得到控件        id_content = (ImageView) findViewById(R.id.id_content);        mCustomRecyclerView = (CustomRecyclerView) findViewById(R.id.id_recyclerview_horizontal);        //设置布局管理器        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);        mCustomRecyclerView.setLayoutManager(linearLayoutManager);        //设置适配器        mAdapter = new GalleryAdapter(this, mDatas);        //添加点击监听        mAdapter.setOnItemClickListener(new GalleryAdapter.OnItemClickListener() {            @Override            public void itemClick(View v, int position) {//                Toast.makeText(MainActivity.this, position+"", Toast.LENGTH_SHORT).show();                id_content.setImageResource(mDatas.get(position));            }        });        mCustomRecyclerView.setAdapter(mAdapter);        //添加滑动监听        mCustomRecyclerView.setOnItemScrollChangeListener(new CustomRecyclerView.OnItemScrollChangeListener() {            @Override            public void onChange(View view, int position) {                 id_content.setImageResource(mDatas.get(position));            }        });    }}


2、activity_main.xml

同上

3、activity_index_gallery_item.xml

同上

4、GalleryAdapter.java

同上

5、CustomRecyclerView.java

/** * Created by jiatao on 2016/06/15 09:55 * Description: 自定义RecyclerView,使用 recyclerview-v7-21.0.3 即以上的版本 *  放弃重写onTouchEvent方法,而是让这个类实现RecyclerView.OnScrollListener接口,然后设置监听,在onScrolled里面进行判断。 *  至于优化:使用了一个成员变化存储当前第一个View,只有第一个View发生变化时才回调 */public class CustomRecyclerView extends RecyclerView {    /**********************添加OnItemScrollChangeListener回调接口相关↓↓******************************/    public interface OnItemScrollChangeListener {        void onChange(View view, int position);    }    private OnItemScrollChangeListener mItemScrollChangeListener;    public void setOnItemScrollChangeListener(OnItemScrollChangeListener listener) {        this.mItemScrollChangeListener = listener;    }    /**********************添加OnItemScrollChangeListener回调接口相关↑↑******************************/    private View mCurrentView;    public CustomRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);        this.addOnScrollListener(new MyScrollListener());//从 recyclerview-v7-21.0.3 开始 setOnScrollListener()过时,更新为 addOnScrollListener()    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        mCurrentView = getChildAt(0);        if (mItemScrollChangeListener != null) {            mItemScrollChangeListener.onChange(mCurrentView, getChildLayoutPosition(mCurrentView));//从 recyclerview-v7-21.0.3 开始 getChildPosition()过时,更新为 getChildLayoutPosition        }    }    /**********************添加RecyclerView.OnScrollListener监听相关↓↓******************************/    // 从 recyclerview-v7-21.0.3 开始,RecyclerView.OnScrollListener 已不是接口,而是抽象类了,所以要用如下写法了    //  recyclerview-v7-21.0.3 之前的版本可以使用 public class CustomRecyclerView extends RecyclerView implements RecyclerView.OnScrollListener{……}的写法    private class MyScrollListener extends RecyclerView.OnScrollListener  {        public MyScrollListener() {            super();        }        @Override        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {            super.onScrollStateChanged(recyclerView, newState);        }        @Override        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {            super.onScrolled(recyclerView, dx, dy);            View newView = getChildAt(0);            if(mItemScrollChangeListener != null){                if(newView != null && newView != mCurrentView){                    mCurrentView = newView;                    mItemScrollChangeListener.onChange(mCurrentView, getChildLayoutPosition(mCurrentView));                }            }        }    }    /**********************添加RecyclerView.OnScrollListener回调接口相关↑↑******************************/}


五、优化与打造真正的Gallery效果效果—— 所用jar包是 recyclerview-v7:21.0.3

1、MainActivity.java

同上

2、activity_main.xml

同上

3、activity_index_gallery_item.xml

同上

4、GalleryAdapter.java

同上

5、CustomRecyclerView.java

/** * Created by jiatao on 2016/06/15 09:55 * Description: 自定义RecyclerView,使用 recyclerview-v7-21.0.3 及以下的版本 *  放弃重写onTouchEvent方法,而是让这个类实现RecyclerView.OnScrollListener接口,然后设置监听,在onScrolled里面进行判断。 *  至于优化:使用了一个成员变化存储当前第一个View,只有第一个View发生变化时才回调 */public class CustomRecyclerView extends RecyclerView implements RecyclerView.OnScrollListener {    /**********************添加OnItemScrollChangeListener回调接口相关↓↓******************************/    public interface OnItemScrollChangeListener {        void onChange(View view, int position);    }    private OnItemScrollChangeListener mItemScrollChangeListener;    public void setOnItemScrollChangeListener(OnItemScrollChangeListener listener) {        this.mItemScrollChangeListener = listener;    }    /**********************添加OnItemScrollChangeListener回调接口相关↑↑******************************/    private View mCurrentView;    public CustomRecyclerView(Context context, AttributeSet attrs) {        super(context, attrs);        this.setOnScrollListener(this);//从 recyclerview-v7-21.0.3 开始 setOnScrollListener()过时,更新为 addOnScrollListener()    }    @Override    protected void onLayout(boolean changed, int l, int t, int r, int b) {        super.onLayout(changed, l, t, r, b);        mCurrentView = getChildAt(0);        if (mItemScrollChangeListener != null) {            mItemScrollChangeListener.onChange(mCurrentView, getChildPosition(mCurrentView));//从 recyclerview-v7-21.0.3 开始 getChildPosition()过时,更新为 getChildLayoutPosition        }    }    /**********************添加RecyclerView.OnScrollListener监听相关↓↓******************************/    //  recyclerview-v7-21.0.3 之前的版本可以使用这种 implements RecyclerView.OnScrollListener 的写法    // 从 recyclerview-v7-21.0.3 开始,RecyclerView.OnScrollListener 已不是接口,而是抽象类了,就不能用以下写法,    @Override    public void onScrollStateChanged(int newState) {    }    @Override    public void onScrolled(int dx, int dy) {        View newView = getChildAt(0);        if(mItemScrollChangeListener != null){            if(newView != null && newView != mCurrentView){                mCurrentView = newView;                mItemScrollChangeListener.onChange(mCurrentView, getChildPosition(mCurrentView));            }        }    }    /**********************添加RecyclerView.OnScrollListener回调接口相关↑↑******************************/}




0 0