在上一篇blog Android5.0之RecyclerView 中大致讲解了RecyclerView的使用。
既然RecyclerView能够实现我们梦寐以求的横向ListView效果,那么我们也应该可以使用RecyclerView实现复杂的Gallery效果吧?
答案显然是可以的。众所周知自从Gallery有众多问题被Google遗弃后,通常实现Gallery效果的方法都是viewpager+Fragment,这样实现起来代码多不说,也有不少问题需要各种设置来解决,对于新手来说,可能不是很容易理解。
今天我给大家讲解下简单的RecyclerView实现gallery效果,我这里只讲解如何监听RecyclerView的滚动和点击事件,都是用接口形式来实现监听。至于Fragment左右切换这部分我就不详细说,demo也不会放上这部分的内容。
好,我们先来看看效果图:
要实现Gallery画廊效果,首先得对RecyclerView增加Scroll监听,自定义一个Recyclerview继承系统的Recyclerview,代码如下:
package com.hjhrq1991.gallery; import android.content.Context; import android.support.v7.widget.RecyclerView; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class MyRecyclerView extends RecyclerView { /** * 当前屏幕第一个item */ private View mCurrentView; /** * 滚动事件监听接口 */ private OnItemScrollChangeListener mItemScrollChangeListener; public MyRecyclerView(Context context, AttributeSet attrs) { super(context, attrs); } public void setOnItemScrollChangeListener( OnItemScrollChangeListener mItemScrollChangeListener) { this.mItemScrollChangeListener = mItemScrollChangeListener; } /** * 滚动事件监听接口 */ public interface OnItemScrollChangeListener { void onChange(View view, int position); } /** * 监听layout的上下左右变化 */ @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); // 据我所知,不在屏幕范围内的item会被回收掉重用,屏幕当前显示的第一个item即为childAt(0) mCurrentView = getChildAt(0); if (mItemScrollChangeListener != null) { mItemScrollChangeListener.onChange(mCurrentView, getChildPosition(mCurrentView)); } } /** * 触摸事件监听,小编不才,对TouchEvent事件分发这块还不是很熟悉,所以这里虽然写了,但是没有触发onTouchEvent。 * 望某位大大修改了告知我一声 */ @Override public boolean onTouchEvent(MotionEvent e) { if (e.getAction() == MotionEvent.ACTION_MOVE) { mCurrentView = getChildAt(0); // Log.e("TAG", getChildPosition(getChildAt(0)) + ""); if (mItemScrollChangeListener != null) { mItemScrollChangeListener.onChange(mCurrentView, getChildPosition(mCurrentView)); } } return super.onTouchEvent(e); } }主要监听左右滚动时item的变化,当上一个item0滑出屏幕时,系统就会回收排到最后,而刚才为item1的item,因为前面没有item,成为item。因此我们在这里通过getChildAt(0)来得到当前第一个item。
写完接口我们就可以再layout里使用自定义的RecyclerView,那么问题来了,要怎么使用这个接口呢?如果滚动到最后一个item,当前屏幕有多个item,只能取到item0,那么其他几个item怎么得到呢?
这时候我们就需要给RecyclerView添加点击事件,在上一篇blog我提到我会使用接口来实现onItemClick事件。由于Adapter里其他部分都一样,我就不摆那么多代码,详情请看我上一篇blog的Adapter实现:
/** * item点击事件的实现 */ class OnItemClick implements View.OnClickListener { private ViewHolder viewHolder; private int position; public OnItemClick(ViewHolder viewHolder,int position) { this.viewHolder = viewHolder; this.position = position; } @Override public void onClick(View v) { mOnItemClickLitener.onItemClick(viewHolder.itemView, position); } } /** * 写一个onitemclick的接口,并在activity实现这个接口,通过此接口实现事件的回调 */ public interface OnItemClickLitener { void onItemClick(View view, int position); } private OnItemClickLitener mOnItemClickLitener; public void setOnItemClickLitener(OnItemClickLitener onItemClickLitener) { this.mOnItemClickLitener = onItemClickLitener; }
并在Activity实现onitemClick事件和onItemScrollChangeListener事件。
package com.hjhrq1991.gallery; import android.app.Activity; import android.os.Bundle; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.view.View; import android.view.Window; import android.widget.Button; import android.widget.TextView; import com.hjhrq1991.adapter.TestAdaper; import com.hjhrq1991.adapter.TestAdaper.OnItemClickLitener; import com.hjhrq1991.bean.TestInfo; import com.hjhrq1991.gallery.MyRecyclerView.OnItemScrollChangeListener; import java.util.ArrayList; import java.util.List; import java.util.Random; public class MainActivity extends Activity implements View.OnClickListener, OnItemScrollChangeListener, OnItemClickLitener { private int TASK_TEXT = 0; private int TASK_DRAWABLE = 1; private int TASK_CHEXKBOX = 2; private MyRecyclerView mrecylerView; private Button mAddBtn; private TextView mTxt; private TestAdaper mAdapter; private List<TestInfo> mList = new ArrayList<TestInfo>(); private int[] drawable = { R.drawable.icon00, R.drawable.icon01, R.drawable.icon02, R.drawable.icon03, R.drawable.icon04, R.drawable.icon05, R.drawable.icon06, R.drawable.icon07, R.drawable.icon08 }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); init(); getParams(); showDate(); } private void init() { mrecylerView = (MyRecyclerView) findViewById(R.id.rvlist); mAddBtn = (Button) findViewById(R.id.add); mTxt = (TextView) findViewById(R.id.content); mAddBtn.setOnClickListener(this); } @Override public void onClick(View v) { TestInfo info = new TestInfo(TASK_TEXT, "这是纯文本"); mAdapter.addToList(info, 3); } /** * 设置数据源 */ private void getParams() { for (int i = 0; i < 20; i++) { Random mRandom = new Random(); int n = mRandom.nextInt(8); TestInfo info1 = new TestInfo(TASK_TEXT, "这是纯文本" + i); TestInfo info2 = new TestInfo(TASK_DRAWABLE, drawable[n], "这是图片" + i); TestInfo info3 = new TestInfo(TASK_CHEXKBOX, drawable[n], "这是复选框" + i, "打钩" + i); mList.add(info1); mList.add(info2); mList.add(info3); } } private void showDate() { // 创建一个线性布局管理器 LinearLayoutManager layoutManager = new LinearLayoutManager(this); layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); // 设置 mrecylerView.getRecycledViewPool().setMaxRecycledViews(0, 3); // 设置布局管理器 mrecylerView.setLayoutManager(layoutManager); // 创建Adapter,并指定数据集 mAdapter = new TestAdaper(this, mList); // 设置Adapter mrecylerView.setAdapter(mAdapter); // 设置默认动画 mrecylerView.setItemAnimator(new DefaultItemAnimator()); // 个人喜欢代码整洁点,因此喜欢实现这个接口,传递当前对象过去,而不喜欢通过new一个接口来实现 mrecylerView.setOnItemScrollChangeListener(this); mAdapter.setOnItemClickLitener(this); } /** * item点击事件 */ @Override public void onItemClick(View view, int position) { // TODO Auto-generated method stub mTxt.setText(mList.get(position).getContent()); } /** * item滑动事件 */ @Override public void onChange(View view, int position) { // TODO Auto-generated method stub mTxt.setText(mList.get(position).getContent()); } }
附上demo下载地址:
demo下载地址
如有转载,请注明出处:http://blog.csdn.net/hjhrq1991