AndroidL-RecyclerView应用之实现Gallery画廊

在上一篇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。
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;
    }

在adapter当中写一个onItemClickListener接口,和onItemScrollChangeListener一样,都实现接口的数据回调,取得当前item所在list的position。

并在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());
	}

}

写到这里,基本上Gallery画廊效果出来了,手指滚动listview或者点击item都可以引来上面的textview的变化。如果我们把textview更改为fragment,加上fragment的左右切换,就可以实现一个完整的Gallery了。不过这一步我就不做了,留给大家去尝试。另外这个demo里有个地方写的不是很好,如果我还没修改而你又改好了,希望您和我说下,我修改下给各位童鞋们学习。

附上demo下载地址:

demo下载地址


如有转载,请注明出处:http://blog.csdn.net/hjhrq1991



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值