【移动应用开发技术】Android中怎么通过自定义RecyclerView控件实现Gallery效果_第1页
【移动应用开发技术】Android中怎么通过自定义RecyclerView控件实现Gallery效果_第2页
【移动应用开发技术】Android中怎么通过自定义RecyclerView控件实现Gallery效果_第3页
【移动应用开发技术】Android中怎么通过自定义RecyclerView控件实现Gallery效果_第4页
【移动应用开发技术】Android中怎么通过自定义RecyclerView控件实现Gallery效果_第5页
已阅读5页,还剩14页未读 继续免费阅读

付费下载

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

【移动应用开发技术】Android中怎么通过自定义RecyclerView控件实现Gallery效果

这期内容当中在下将会给大家带来有关Android中怎么通过自定义RecyclerView控件实现Gallery效果,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。1、RecyclerView的基本用法首先主Activity的布局文件:<RelativeLayout

xmlns:android="/apk/res/android"

xmlns:tools="/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>Item的布局文件:<?xml

version="1.0"

encoding="utf-8"?>

<RelativeLayout

xmlns:android="/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:textColor="#ff0000"

android:text="some

info"

android:textSize="12dp"

/>

</RelativeLayout>数据适配器:package

com.example.zhy_horizontalscrollview03;

import

java.util.List;

import

android.content.Context;

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;

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;

}

public

static

class

ViewHolder

extends

RecyclerView.ViewHolder

{

public

ViewHolder(View

arg0)

{

super(arg0);

}

ImageView

mImg;

TextView

mTxt;

}

@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;

}

/**

*

设置值

*/

@Override

public

void

onBindViewHolder(final

ViewHolder

viewHolder,

final

int

i)

{

viewHolder.mImg.setImageResource(mDatas.get(i));

}

}可以看到数据适配器与BaseAdapter比较发生了相当大的变化,主要有3个方法:getItemCount这个不用说,获取总的条目数onCreateViewHolder创建ViewHolderonBindViewHolder将数据绑定至ViewHolder可见,RecyclerView对ViewHolder也进行了一定的封装,但是如果你仔细观察,你会发出一个疑问,ListView里面有个getView返回View为Item的布局,那么这个Item的样子在哪控制?其实是这样的,我们创建的ViewHolder必须继承RecyclerView.ViewHolder,这个RecyclerView.ViewHolder的构造时必须传入一个View,这个View相当于我们ListViewgetView中的convertView(即:我们需要inflate的item布局需要传入)。还有一点,ListView中convertView是复用的,在RecyclerView中,是把ViewHolder作为缓存的单位了,然后convertView作为ViewHolder的成员变量保持在ViewHolder中,也就是说,假设没有屏幕显示10个条目,则会创建10个ViewHolder缓存起来,每次复用的是ViewHolder,所以他把getView这个方法变为了onCreateViewHolder。有兴趣的自己打印下Log,测试下。最后在Activity中使用:package

com.example.zhy_horizontalscrollview03;

import

java.util.ArrayList;

import

java.util.Arrays;

import

java.util.List;

import

android.app.Activity;

import

android.os.Bundle;

import

android.support.v7.widget.LinearLayoutManager;

import

android.support.v7.widget.RecyclerView;

import

android.view.Window;

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.drawable.a,

R.drawable.b,

R.drawable.c,

R.drawable.d,

R.drawable.e,

R.drawable.f,

R.drawable.g,

R.drawable.h,

R.drawable.l));

}

}使用起来也很方便,唯一的区别就是要设置LayoutManager,目前只有一个实现类,就是LinearLayoutManager,可以设置为水平或者垂直。最后效果图:效果很不错,这就是RecyclerView的基本用法了,但是你会发现一个坑爹的地方,竟然没有提供setOnItemClickListener这个回调,要不要这么坑爹。。。2、为RecyclerView添加OnItemClickListener回调虽然它没有提供,但是添加个OnItemClickListener对我们来说还不是小菜一碟~我决定在Adapter中添加这个回调接口:package

com.example.zhy_horizontalscrollview03;

import

java.util.List;

import

android.content.Context;

import

android.support.v7.widget.RecyclerView;

import

android.view.LayoutInflater;

import

android.view.View;

import

android.view.View.OnClickListener;

import

android.view.ViewGroup;

import

android.widget.ImageView;

import

android.widget.TextView;

public

class

GalleryAdapter

extends

RecyclerView.Adapter<GalleryAdapter.ViewHolder>

{

/**

*

ItemClick的回调接口

*

@author

zhy

*

*/

public

interface

OnItemClickLitener

{

void

onItemClick(View

view,

int

position);

}

private

OnItemClickLitener

mOnItemClickLitener;

public

void

setOnItemClickLitener(OnItemClickLitener

mOnItemClickLitener)

{

this.mOnItemClickLitener

=

mOnItemClickLitener;

}

private

LayoutInflater

mInflater;

private

List<Integer>

mDatas;

public

GalleryAdapter(Context

context,

List<Integer>

datats)

{

mInflater

=

LayoutInflater.from(context);

mDatas

=

datats;

}

public

static

class

ViewHolder

extends

RecyclerView.ViewHolder

{

public

ViewHolder(View

arg0)

{

super(arg0);

}

ImageView

mImg;

TextView

mTxt;

}

@Override

public

int

getItemCount()

{

return

mDatas.size();

}

@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;

}

@Override

public

void

onBindViewHolder(final

ViewHolder

viewHolder,

final

int

i)

{

viewHolder.mImg.setImageResource(mDatas.get(i));

//如果设置了回调,则设置点击事件

if

(mOnItemClickLitener

!=

null)

{

viewHolder.itemView.setOnClickListener(new

OnClickListener()

{

@Override

public

void

onClick(View

v)

{

mOnItemClickLitener.onItemClick(viewHolder.itemView,

i);

}

});

}

}

}很简单,创建一个接口,提供一个设置入口,然后在onBindViewHolder中判断即可。最后在主Activity中设置监听:mAdapter

=

new

GalleryAdapter(this,

mDatas);

mAdapter.setOnItemClickLitener(new

OnItemClickLitener()

{

@Override

public

void

onItemClick(View

view,

int

position)

{

Toast.makeText(MainActivity.this,

position+"",

Toast.LENGTH_SHORT)

.show();

}

});

mRecyclerView.setAdapter(mAdapter);好了,这样就行了,看效果图:效果还是不错的,接下来我想改成相册效果,即上面显示一张大图,下面的RecyclerView做为图片切换的指示器。3、自定义RecyclerView实现滚动时内容联动首先修改下布局:布局文件:<LinearLayout

xmlns:android="/apk/res/android"

xmlns:tools="/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"

android:src="@drawable/ic_launcher"

/>

</FrameLayout>

<com.example.zhy_horizontalscrollview03.MyRecyclerView

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>添加一个显示大图的区域,把RecyclerView改为自己定义的。然后看我们自定义RecyclerView的代码:package

com.example.zhy_horizontalscrollview03;

import

android.content.Context;

import

android.support.v7.widget.RecyclerView;

import

android.util.AttributeSet;

import

android.view.MotionEvent;

import

android.view.View;

public

class

CopyOfMyRecyclerView

extends

RecyclerView

{

public

CopyOfMyRecyclerView(Context

context,

AttributeSet

attrs)

{

super(context,

attrs);

}

private

View

mCurrentView;

/**

*

滚动时回调的接口

*/

private

OnItemScrollChangeListener

mItemScrollChangeListener;

public

void

setOnItemScrollChangeListener(

OnItemScrollChangeListener

mItemScrollChangeListener)

{

this.mItemScrollChangeListener

=

mItemScrollChangeListener;

}

public

interface

OnItemScrollChangeListener

{

void

onChange(View

view,

int

position);

}

@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));

}

}

@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);

}

}定义了一个滚动时回调的接口,然后在onTouchEvent中,监听ACTION_MOVE,用户手指滑动时,不断把当前第一个View回调回去~关于我咋知道getChildAt(0)和getChildPosition()可用,起初我以为有getFirstVisibleItem这个方法,后来发现么有;但是发现了getRecycledViewPool()看名字我觉得是Viewholder那个缓存队列,我想那么直接取这个队列的第一个不就是我要的View么,后来没有成功。我就观察它内部的View,最后发现,第一个显示的始终是它第一个child,至于getChildPosition这个看方法就看出来了。现在的效果:和我之前那个例子的效果是一模一样的,不过,我还想做一些改变,我觉得Gallery或者说相册的指示器,下面可能1000来张图片,我不仅喜欢手指在屏幕上滑动时,图片会自动切换。我还希望,如果我给指示器一个加速度,即使手指离开,下面还在滑动,上面也会联动。而且我还想做些优化,直接在ACTION_MOVE中回调,触发的频率太高了,理论上一张图片只会触发一次~~4、优化与打造真正的Gallery效果既然希望手指离开还能联动,那么不仅需要ACTION_MOVE需要监听,还得监听一个加速度,速度到达一定值,然后继续移动~~再理一理,需要这么麻烦么,不是能滚动么,那么应该有OnScrollListener啊,小看一把,果然有,哈哈哈~天助我也,下面看修改后的代码:package

com.example.zhy_horizontalscrollview03;

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

mCurrentView;

private

OnItemScrollChangeListener

mItemScrollChangeListener;

public

void

setOnItemScrollChangeListener(

OnItemScrollChangeListener

mItemScrollChangeListener)

{

this.mItemScrollChangeListener

=

mItemScrollChangeListener;

}

public

interface

OnItemScrollChangeListener

{

void

onChange(View

view,

int

position);

}

public

MyRecyclerView(Context

context,

AttributeSet

attrs)

{

super(context,

attrs);

//

TODO

Auto-generated

constructor

stub

this.setOnScrollListener(this);

}

@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));

}

}

@Override

public

void

onScrollStateChanged(int

arg0)

{

}

/**

*

*

滚动时,判断当前第一个View是否发生变化,发生才回调

*/

@Override

public

void

onScrolled(int

arg0,

int

arg1)

{

View

newView

=

getChildAt(0);

if

(mItemScrollChangeListener

!=

null)

{

if

(newView

!=

null

&&

newView

!=

mCurrentView)

{

mCurrentView

=

newView

;

mItemScrollChangeListener.onChange(mCurrentView,

getChildPosition(mCurrentView));

}

}

}

}我放弃了重写onTouchEvent方法,而是让这个类实现RecyclerView.OnScrollListener接口,然后设置监听,在onScrolled里面进行判断。至于优化:我使用了一个成员变化存储当前第一个View,只有第一个View发生变化时才回调~~太完美了~看MainActivity:package

com.example.zhy_horizontalscrollview03;

import

java.util.ArrayList;

import

java.util.Arrays;

import

java.util.List;

import

android.app.Activity;

import

android.os.Bundle;

import

android.support.v7.widget.LinearLayoutManager;

import

android.support.v7.widget.RecyclerView;

import

android.view.View;

import

android.view.Window;

import

android.widget.ImageView;

import

android.widget.Toast;

import

com.example.zhy_horizontalscrollview03.GalleryAdapter.OnItemClickLitener;

import

com.example.zhy_horizontalscrollview03.MyRecyclerView.OnItemScrollChangeListener;

public

class

MainActivity

extends

Acti

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论