利用自定义的 RecyclerView 实现相册的滑动功能

本文介绍了如何利用自定义的 RecyclerView 来实现相册的滑动功能,解决了在第9张图片无法显示的问题,并增加了额外功能。通过设置自定义的 RecyclerView,结合适配器和点击事件回调,实现了图片的滑动浏览。同时,文章提到了 RecyclerView 的 OnScrollListener 监听器的使用,以及如何导入相关库避免报错。
        利用自定义的功能实现和上次一样的功能(相册), 《 使用 HorizontalScrollView 实现水平滚动,并点击有相应的反应效果》http://blog.youkuaiyun.com/antimage08/article/details/50493233  这次的自定义解决了上次在第 9 张图片时不能显示的问题,并添加了一些额外的功能。
       关于 RecyclerView 前面的文章已有两篇相应的内容介绍:
《RecyclerView 的简单使用》http://blog.youkuaiyun.com/antimage08/article/details/50010923   
《利用 RecyclerView 实现垂直交错的网格》http://blog.youkuaiyun.com/antimage08/article/details/50199841

       效果如下:



       自定义 RecyclerView 相对简单,用适配器加载下排的小图片,点击图片后,ImageView (大图)作出相应的相应。这里需要点击事件,用接口来实现事件的回调。
       RecyclerView 这个类里面有个 OnScrollListener 监听器,从名字就可以看出它是 RecyclerView 滑动的监听器。这里也用接口进行事件的回调。
       由于要用到 RecyclerView 的 OnScrollListener 。所以还要从 SDK 的目录下把相应的 jar 包导入 libs 目录下。否则可能会报错(我的就报错了(在 build.gradle 中也进行了相应的配置))
 




布局文件 activity_main.xml (这里使用了固定屏幕下方的 RecyclerView 高度的办法。这样感觉比上一篇固定 ImageView 的方法好,因为由于手机的屏幕大小不一。可能会出现较差的效果):
<?xml version="1.0" encoding="utf-8"?>
<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:paddingBottom="5dp"
    android:paddingLeft="5dp"
    android:paddingRight="5dp"
    android:paddingTop="5dp"
    android:orientation="vertical"
    tools:context="com.crazy.recyclerviewtest.MainActivity">

    <LinearLayout
        android:layout_weight="1"
        android:layout_width="match_parent"
        android:layout_height="0dp">

        <ImageView
            android:id="@+id/imageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/bg_01"
            android:scaleType="centerCrop" />
    </LinearLayout>

    <com.crazy.recyclerviewtest.MyRecyclerView
        android:id="@+id/my_recycler"
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:layout_gravity="bottom"
        android:scrollbars="none">
    </com.crazy.recyclerviewtest.MyRecyclerView >

</LinearLayout>



item_image.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/bg_border_two" >

    <ImageView
        android:id="@+id/bottom_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        android:layout_margin="10dp"
        android:stateListAnimator="@animator/image_click"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:src="@drawable/bg_02"
        android:scaleType="centerCrop" />

    <TextView
        android:id="@+id/bottom_text_view"
        android:layout_marginBottom="5dp"
        android:text="没有文字呢"
        android:layout_below="@id/bottom_image"
        android:textSize="12sp"
        android:layout_centerHorizontal="true"
        android:textColor="#f0f"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</RelativeLayout>



MainActivity.java :
package com.crazy.recyclerviewtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.view.View;
import android.widget.ImageView;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MainActivity extends Activity {

    private MyRecyclerView mRecyclerView;
    private ImageView mImageView;
    private MyAdapter myAdapter;
    private List<Bitmap> bitmapList;
    private List<String> mDatas;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }

    private void init() {

        bitmapList = new ArrayList<>(Arrays.asList(
                readBitMap(this, R.drawable.bricks),
                readBitMap(this, R.drawable.dog),
                readBitMap(this, R.drawable.flower),
                readBitMap(this, R.drawable.grass),
                readBitMap(this, R.drawable.stones),
                readBitMap(this, R.drawable.wood),
                readBitMap(this, R.drawable.bg_01),
                readBitMap(this, R.drawable.bg_02),
                readBitMap(this, R.drawable.bg_03),
                readBitMap(this, R.drawable.bg_04),
                readBitMap(this, R.drawable.bg_05),
                readBitMap(this, R.drawable.bg_06),
                readBitMap(this, R.drawable.bg_07)
        ));

        mDatas = new ArrayList<>();
        for (int i = 'A'; i <= 'M'; i++) {
            mDatas.add("" + (char) i);
        }


        mImageView = (ImageView)findViewById(R.id.imageView);

        mRecyclerView = (MyRecyclerView)findViewById(R.id.my_recycler);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        mRecyclerView.setLayoutManager(layoutManager);

        myAdapter = new MyAdapter(this, bitmapList, mDatas);

        mRecyclerView.setAdapter(myAdapter);

        mRecyclerView.setOnItemScrollChangeListener(new MyRecyclerView.OnItemScrollListener() {
            @Override
            public void onItemChange(View view, int position) {
                mImageView.setImageBitmap(bitmapList.get(position));
            }
        });

        myAdapter.setOnItemClickListener(new MyAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(View view, int position) {
                mImageView.setImageBitmap(bitmapList.get(position));
            }
        });

    }

    public static Bitmap readBitMap(Context mContext, int resId) {
        BitmapFactory.Options opt = new BitmapFactory.Options();
        opt.inPreferredConfig = Bitmap.Config.RGB_565;
        opt.inPurgeable = true;
        opt.inInputShareable = true;

        InputStream is = mContext.getResources().openRawResource(resId);
        return BitmapFactory.decodeStream(is, null, opt);
    }

}




MyAdapter.java :
package com.crazy.recyclerviewtest;

import android.content.Context;
import android.graphics.Bitmap;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by antimage on 2016/1/11.
 */
public class MyAdapter extends RecyclerView.Adapter<MyAdapter.CrazyViewHolder> {

    private List<Bitmap> bitmapList;
    private LayoutInflater inflater;
    private List<String> mDatas;

    private OnItemClickListener mOnItemClickListener;

    public interface OnItemClickListener {
        void onItemClick(View view, int position);
    }

    public void setOnItemClickListener(OnItemClickListener mOnItemClickListener) {
        this.mOnItemClickListener = mOnItemClickListener;
    }

    public MyAdapter(Context context, List<Bitmap> bitmapList, List<String> mDatas) {
        inflater = LayoutInflater.from(context);
        if (bitmapList == null || mDatas == null) {
            bitmapList = new ArrayList<>();
            mDatas = new ArrayList<>();
        } else {
            this.bitmapList = bitmapList;
            this.mDatas = mDatas;
        }
    }

    @Override
    public CrazyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = inflater.inflate(R.layout.item_image, parent, false);
        CrazyViewHolder cViewHolder = new CrazyViewHolder(view);

        cViewHolder.smallImage = (ImageView) view.findViewById(R.id.bottom_image);
        cViewHolder.textView = (TextView)view.findViewById(R.id.bottom_text_view);

        return cViewHolder;
    }

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

        holder.smallImage.setImageBitmap(bitmapList.get(position));
        holder.textView.setText(mDatas.get(position));

        if (mOnItemClickListener != null) {

            holder.itemView.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    mOnItemClickListener.onItemClick(holder.itemView, position);
                }
            });

        }
    }

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

    public class CrazyViewHolder extends RecyclerView.ViewHolder {

        ImageView smallImage;
        TextView textView;

        public CrazyViewHolder(View itemView) {
            super(itemView);
        }
    }
}




MyRecyclerView.java :
package com.crazy.recyclerviewtest;

import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.OnScrollListener;
import android.util.AttributeSet;
import android.view.View;

public class MyRecyclerView extends RecyclerView implements OnScrollListener {

	/* 当前第一个View*/
	private View firstView;

	private OnItemScrollListener mOnItemScrollListener;

	public interface OnItemScrollListener {
		void onItemChange(View view, int position);
	}

	public void setOnItemScrollChangeListener(OnItemScrollListener mOnItemScrollListener) {
		this.mOnItemScrollListener = mOnItemScrollListener;
	}

	public MyRecyclerView(Context context, AttributeSet attrs) {
		super(context, attrs);
		// 滚动时,上面的 ImageView 也要发生变化,注册监听器
		this.setOnScrollListener(this);
	}

	@Override
	protected void onLayout(boolean changed, int l, int t, int r, int b) {
		super.onLayout(changed, l, t, r, b);

		firstView = getChildAt(0);
		if (mOnItemScrollListener != null) {
			mOnItemScrollListener.onItemChange(firstView, getChildPosition(firstView));
		}
	}

	@Override
	public void onScrollStateChanged(int arg0) {

	}

	@Override
	public void onScrolled(int arg0, int arg1) {
		View newView = getChildAt(0);
		// 滚动时发生变化才回调
		if (mOnItemScrollListener != null) {
			if (newView != null && newView != firstView) {
				firstView = newView ;
				mOnItemScrollListener.onItemChange(firstView, getChildPosition(firstView));
			}
		}
	}
}




点击图片产生相应效果的 XML :

bg_border.xml :
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">

    <solid android:color="#0CC"/>
</shape>



bg_border_two.xml :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    
    <item
        android:drawable="@drawable/bg_border"
        android:state_pressed="true"/>
    <item android:drawable="@android:color/white" />

</selector>



image_click.xml :
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_enabled="true"
        android:state_pressed="true">
        <set android:ordering="together">
            <objectAnimator
                android:duration="@android:integer/config_shortAnimTime"
                android:propertyName="scaleX"
                android:valueTo="0.8"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="@android:integer/config_shortAnimTime"
                android:propertyName="scaleY"
                android:valueTo="0.8"
                android:valueType="floatType" />
        </set>
    </item>

    <item>
        <set android:ordering="together">
            <objectAnimator
                android:duration="@android:integer/config_shortAnimTime"
                android:propertyName="scaleX"
                android:valueTo="1.0"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="@android:integer/config_shortAnimTime"
                android:propertyName="scaleY"
                android:valueTo="1.0"
                android:valueType="floatType" />
        </set>
    </item>
</selector>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值