版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
【移动应用开发技术】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. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年湖南省张家界市中小学教师招聘考试试卷带答案
- 2026年保密基本知识考试题目及答案
- 2026年安徽淮南市中考生物试卷及答案
- 高中政治 (道德与法治)人教统编版必修1 中国特色社会主义习近平新时代中国特色社会主义思想教案设计
- Unit 9 Why Don't You Treat Today教学设计初中英语北京课改版北京出版社2007八年级下册-北京课改版北京出版社
- 传统篆刻工具与刻制技巧【课件文档】
- 人教新目标 (Go for it) 版八年级下册Section A第2课时教学设计
- 中国进出口银行校招试题及答案
- 传统农具的艺术价值与收藏研究【课件文档】
- 风湿性疾病病人的护理教学设计中职专业课-内科护理-医学类-医药卫生大类
- 手卫生培训手卫生的依从性PPT
- 过磅单模板完整版
- LY/T 2445-2015绿化用表土保护技术规范
- GB/T 5483-1996石膏和硬石膏
- GB/T 18051-2000潜油电泵振动试验方法
- 第五章资本主义世界的经济恢复与政治调整
- 大班音乐《数高楼》课件
- 《12345政务便民服务热线工作表态发言》
- 电工基础知识PPT
- DB14-T 2557-2022水利工程质量管理规范 第4部分:施工单位
- 山东省济南市各县区乡镇行政村村庄村名居民村民委员会明细及行政区划代码
评论
0/150
提交评论