从Android 5.0开始,谷歌公司推出了RecylerView控件,当看到RecylerView这个新控件的时候,大部分人会首先发出一个疑问,recylerview是什么?为什么会有recylerview也就是说recylerview的优点是什么?recylerview怎么用?等等,下面我们将深入解析recylerview。

1.RecyclerView是什么?

RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,这一点从它的名字Recyclerview即回收view也可以看出。看到这也许有人会问,不是已经有ListView了吗,为什么还要RecyclerView呢?这就牵扯到第二个问题了。

2.RecyclerView的优点是什么?

根据官方的介绍RecyclerView是ListView的升级版,既然如此那RecyclerView必然有它的优点,现就RecylerView相对于ListView的优点罗列如下:
① RecyclerView封装了viewholder的回收复用,也就是说RecyclerView标准化了ViewHolder,编写Adapter面向的是ViewHolder而不再是View了,复用的逻辑被封装了,写起来更加简单。
② 提供了一种插拔式的体验,高度的解耦,异常的灵活,针对一个Item的显示RecyclerView专门抽取出了相应的类,来控制Item的显示,使其的扩展性非常强。例如:你想控制横向或者纵向滑动列表效果可以通过LinearLayoutManager这个类来进行控制(与GridView效果对应的是GridLayoutManager,与瀑布流对应的还StaggeredGridLayoutManager等),也就是说RecyclerView不再拘泥于ListView的线性展示方式,它也可以实现GridView的效果等多种效果。你想控制Item的分隔线,可以通过继承RecyclerView的ItemDecoration这个类,然后针对自己的业务需求去抒写代码。
③ 可以控制Item增删的动画,可以通过ItemAnimator这个类进行控制,当然针对增删的动画,RecyclerView有其自己默认的实现。

recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this );
//设置布局管理器
recyclerView.setLayoutManager(layoutManager);
//设置为垂直布局,这也是默认的
layoutManager.setOrientation(OrientationHelper. VERTICAL);
//设置Adapter
recyclerView.setAdapter(recycleAdapter);
//设置分隔线
recyclerView.addItemDecoration( new DividerGridItemDecoration(this ));
//设置增加或删除条目的动画
recyclerView.setItemAnimator( new DefaultItemAnimator());

1
2
3
4
5
6
7
8
9
10
11
12
13
14
1
2
3
4
5
6
7
8
9
10
11
12
13
14
可以看到对RecylerView的设置过程,比ListView要复杂一些,虽然代码抒写上有点复杂,但它的扩展性是极高的。在了解了RecyclerView的一些控制之后,紧接着来看看它的Adapter的写法,RecyclerView的Adapter与ListView的Adapter还是有点区别的,RecyclerView.Adapter,需要实现3个方法:
a) onCreateViewHolder()
这个方法主要生成为每个Item inflater出一个View,但是该方法返回的是一个ViewHolder。该方法把View直接封装在ViewHolder中,然后我们面向的是ViewHolder这个实例,当然这个ViewHolder需要我们自己去编写。直接省去了当初的convertView.setTag(holder)和convertView.getTag()这些繁琐的步骤。

b) onBindViewHolder()
这个方法主要用于适配渲染数据到View中。方法提供给你了一viewHolder而不是原来的convertView。

c) getItemCount()
这个方法就类似于BaseAdapter的getCount方法了,即总共有多少个条目。接下来通过几个小的实例帮助大家更深入的了解RecyclerView的用法。

例子1:用RecyclerView实现一个图片滚动的列表
代码如下:

public class MainActivity extends ActionBarActivity {

private RecyclerView mRecyclerView;
private List<Integer> mDatas;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
// 得到控件
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
// 设置布局管理器
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
mRecyclerView.setLayoutManager(layoutManager);
// 设置适配器
mRecyclerView.setAdapter(new MyRecyclerAdapter(this, mDatas));

}

private void initData() {
mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.kenan1,
R.drawable.kenan2, R.drawable.kenan3, R.drawable.kenan4,
R.drawable.kenan5, R.drawable.kenan6, R.drawable.kenan7,
R.drawable.kenan8));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public class DividerItemDecoration extends ItemDecoration {

public DividerItemDecoration() {
super();
// TODO Auto-generated constructor stub
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
State state) {
// TODO Auto-generated method stub
super.getItemOffsets(outRect, view, parent, state);
}

@Override
@Deprecated
public void onDraw(Canvas c, RecyclerView parent) {
// TODO Auto-generated method stub
super.onDraw(c, parent);
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.MyHolder> {

private Context mContext;
private List<Integer> mDatas;

public MyRecyclerAdapter(Context context, List<Integer> datas) {
super();
this.mContext = context;
this.mDatas = datas;
}

@Override
public int getItemCount() {
// TODO Auto-generated method stub
return mDatas.size();
}

@Override
// 填充onCreateViewHolder方法返回的holder中的控件
public void onBindViewHolder(MyHolder holder, int position) {
// TODO Auto-generated method stub
holder.imageView.setImageResource(mDatas.get(position));
}

@Override
// 重写onCreateViewHolder方法,返回一个自定义的ViewHolder
public MyHolder onCreateViewHolder(ViewGroup arg0, int arg1) {
// 填充布局
View view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
MyHolder holder = new MyHolder(view);
return holder;
}

// 定义内部类继承ViewHolder
class MyHolder extends ViewHolder {

private ImageView imageView;

public MyHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.iv_item);
}

}

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
效果如下:
这里写图片描述

3.为RecyclerView添加OnItemClickListener回调

效果很不错,这就是RecyclerView的基本用法了,但细心的你会发现,竟然没有提供setOnItemClickListener这个回调,也就是无法响应点击事件,然而在日常开发中,响应点击事件无疑都是必须的,虽然它没有提供,苏州楼凤:www.jsgren.com/forum-43-1.html但是我们可以手动添加OnItemClickListener,我们可以在Adapter中添加这个回调接口:

例子2:可以点击的RecyclerView
在原工程基础上对Adapter进行修改,添加OnItemClickListener接口,由于具体点击后的逻辑是交给MainActivity去确定的,所以我们定义抽象的OnItemClickListener接口,里面有一个抽象方法,用于设置被点击后的逻辑:

//item的回调接口
public interface OnItemClickListener{
void onItemClick(View view,int Position);
}
1
2
3
4
1
2
3
4
对外暴露一个设置点击监听器的方法,其中传入需要OnItemClickListener接口

//定义一个设置点击监听器的方法
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
this.mItemClickListener = itemClickListener;
}
1
2
3
4
1
2
3
4
在绑定ViewHolder的逻辑之中,对RecyclerView的每一个itemView设置点击事件:

@Override
// 填充onCreateViewHolder方法返回的holder中的控件
public void onBindViewHolder(final MyHolder holder, final int position) {
// TODO Auto-generated method stub
holder.imageView.setImageResource(mDatas.get(position));
//如果设置了回调,则设置点击事件
if(mItemClickListener != null){
holder.itemView.setOnClickListener(new OnClickListener() {

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

}
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
最后粘上Adapter的全部代码,其他代码均和例子1一样

public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.MyHolder> {

private Context mContext;
private List<Integer> mDatas;
private OnItemClickListener mItemClickListener;

public MyRecyclerAdapter(Context context, List<Integer> datas) {
super();
this.mContext = context;
this.mDatas = datas;
}
//item的回调接口
public interface OnItemClickListener{
void onItemClick(View view,int Position);
}
//定义一个设置点击监听器的方法
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
this.mItemClickListener = itemClickListener;
}
@Override
public int getItemCount() {
// TODO Auto-generated method stub
return mDatas.size();
}

@Override
// 填充onCreateViewHolder方法返回的holder中的控件
public void onBindViewHolder(final MyHolder holder, final int position) {
// TODO Auto-generated method stub
holder.imageView.setImageResource(mDatas.get(position));
//如果设置了回调,则设置点击事件
if(mItemClickListener != null){
holder.itemView.setOnClickListener(new OnClickListener() {

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

}
});
}
}

@Override
// 重写onCreateViewHolder方法,返回一个自定义的ViewHolder
public MyHolder onCreateViewHolder(ViewGroup viewgroup, int i) {
// 填充布局
View view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
MyHolder holder = new MyHolder(view);
return holder;
}

// 定义内部类继承ViewHolder
class MyHolder extends ViewHolder {

private ImageView imageView;

public MyHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.iv_item);
}

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
效果如下:
这里写图片描述

4.自定义RecyclerView实现滚动时内容联动

例子3:RecyclerView制作相册效果
效果:在原工程的基础上进行修改,改成相册效果,即上面显示一张大图,下面的RecyclerView做为图片切换的指示器。

首先修改下布局:

<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:orientation="vertical"
tools:context="com.example.recyclerviewdemo.MainActivity" >

<ImageView
android:id="@+id/iv_group"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_margin="10dp"
android:layout_weight="1"
android:scaleType="centerCrop"
android:src="@drawable/ic_launcher" />

<!--
<FrameLayout
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1" >

<ImageView
android:id="@+id/iv_group"
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.recyclerviewdemo.MyRecyclerView
android:id="@+id/recyclerview"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_centerVertical="true"
android:layout_gravity="bottom" />

</LinearLayout>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
添加一个显示大图的区域,把RecyclerView改为自己定义的。
然后看我们自定义RecyclerView的代码:

public class MyRecyclerView extends RecyclerView {

private onItemScrollChangeListener mItemScrollChangeListener;
private View mCurrentView;

public MyRecyclerView(Context context, AttributeSet attrs) {
super(context, attrs);
// TODO Auto-generated constructor stub
}

// 回调的接口
public interface onItemScrollChangeListener {
void onChange(View view, int position);
}

// 对外暴露设置滚动接口的方法
public void setOnItemScrollChangeListener(
onItemScrollChangeListener itemScrollChangeListener) {
this.mItemScrollChangeListener = itemScrollChangeListener;
}

@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
// TODO Auto-generated method stub
super.onLayout(changed, l, t, r, b);
mCurrentView = getChildAt(0);
if (mItemScrollChangeListener != null) {
mItemScrollChangeListener.onChange(mCurrentView,
getChildPosition(mCurrentView));
}
}

@Override
public boolean onTouchEvent(MotionEvent e) {
// TODO Auto-generated method stub

if (e.getAction() == MotionEvent.ACTION_MOVE) {
mCurrentView = getChildAt(0);
if (mItemScrollChangeListener != null) {
mItemScrollChangeListener.onChange(mCurrentView,
getChildPosition(mCurrentView));
}
}
return super.onTouchEvent(e);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
最主要是重写onLayout,onTouchEvent方法,并设置滚动监听的回调,还有向外界暴露监听器的逻辑。

然后是Adapter的代码

public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.MyHolder> {

private Context mContext;
private List<Integer> mDatas;
//private OnItemClickListener mItemClickListener;

public MyRecyclerAdapter(Context context, List<Integer> datas) {
super();
this.mContext = context;
this.mDatas = datas;
}
/*//item的回调接口
public interface OnItemClickListener{
void onItemClick(View view,int Position);
}
//定义一个设置点击监听器的方法
public void setOnItemClickListener(OnItemClickListener itemClickListener) {
this.mItemClickListener = itemClickListener;
}*/
@Override
public int getItemCount() {
// TODO Auto-generated method stub
return mDatas.size();
}

@Override
// 填充onCreateViewHolder方法返回的holder中的控件
public void onBindViewHolder(final MyHolder holder, final int position) {
// TODO Auto-generated method stub
holder.imageView.setImageResource(mDatas.get(position));
/*//如果设置了回调,则设置点击事件
if(mItemClickListener != null){
holder.itemView.setOnClickListener(new OnClickListener() {

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

}
});
}*/
}

@Override
// 重写onCreateViewHolder方法,返回一个自定义的ViewHolder
public MyHolder onCreateViewHolder(ViewGroup viewgroup, int i) {
// 填充布局
View view = LayoutInflater.from(mContext).inflate(R.layout.item, null);
MyHolder holder = new MyHolder(view);
return holder;
}

// 定义内部类继承ViewHolder
class MyHolder extends ViewHolder {

private ImageView imageView;

public MyHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.iv_item);
}

}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
定义了一个滚动时回调的接口,然后在onTouchEvent中,监听ACTION_MOVE,用户手指滑动时,不断把当前第一个View回调回去
关于为什么getChildAt(0)和getChildPosition()可用,苏州楼凤起初我以为有getFirstVisibleItem这个方法,后来发现么有;但是发现了getRecycledViewPool()看名字我觉得是Viewholder那个缓存队列,我想那么直接取这个队列的第一个不就是我要的View么,后来没有成功。我就观察它内部的View,最后发现,第一个显示的始终是它第一个child,至于getChildPosition这个看方法就看出来了。
效果如下:
这里写图片描述

5.RecyclerView实现瀑布流

例子4:用RecyclerView打造瀑布流效果
其中大部分内容实现和基本的RecyclerView使用是一样的,就不多叙述了,就一个地方不同,就是我们在适配器中绑定ViewHolder的方法中需要重新给我们的itemView布局设置height,这里是生成随机数来设置高度的。

//得到随机item的高度
private void getRandomHeight(List<Integer> datas) {
heights = new ArrayList<Integer>();
for (int i = 0; i < datas.size(); i++) {
heights.add((int) (200+Math.random()*100));
}
}
1
2
3
4
5
6
7
1
2
3
4
5
6
7
在onBindViewHolder方法中:

@Override
// 填充onCreateViewHolder方法返回的holder中的控件
public void onBindViewHolder(final MyHolder holder, int position) {
// TODO Auto-generated method stub
//得到item的LayoutParams布局参数
ViewGroup.LayoutParams params= holder.itemView.getLayoutParams();
//把随机的高度赋予item布局
params.height = heights.get(position);
//把params设置给item布局
holder.itemView.setLayoutParams(params);
//为控件绑定数据
holder.imageView.setImageResource(mDatas.get(position));
//如果设置了监听那么它就不为空,然后回调相应的方法
if(onItemClickListener!=null){
holder.itemView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//得到当前点击item的位置pos
int position = holder.getLayoutPosition();
//把事件交给我们实现的接口那里处理
onItemClickListener.onOnItemClick(holder.itemView, position);
}
});
holder.itemView.setOnLongClickListener(new OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
//得到当前点击item的位置pos
int position = holder.getLayoutPosition();
//把事件交给我们实现的接口那里处理
onItemClickListener.onOnItemClick(holder.itemView, position);
return true;
}
});
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
最后附上项目完整代码:

public class MainActivity extends ActionBarActivity {

private RecyclerView mRecyclerView;
private List<Integer> mDatas;
private MyRecyclerAdapter adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initData();
// 得到控件
mRecyclerView = (RecyclerView) findViewById(R.id.recyclerview);
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
//设置RecyclerView布局管理器为2列垂直排布
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(layoutManager);

adapter = new MyRecyclerAdapter(this, mDatas);
mRecyclerView.setAdapter(adapter);
adapter.setOnItemClickListener(new onItemClickListener() {

@Override
public void onOnItemClick(View view, int position) {
// TODO Auto-generated method stub
Toast.makeText(MainActivity.this, "点击了:"+position, Toast.LENGTH_SHORT).show();
}

@Override
public void onLongClick(View view, int position) {
//长按删除
mDatas.remove(position);
adapter.notifyItemRemoved(position);
}
});

}

private void initData() {
mDatas = new ArrayList<Integer>(Arrays.asList(R.drawable.kenan1,
R.drawable.kenan2, R.drawable.kenan3, R.drawable.kenan4,
R.drawable.kenan5, R.drawable.kenan6, R.drawable.kenan7,
R.drawable.kenan8,R.drawable.kenan1,
R.drawable.kenan2, R.drawable.kenan3, R.drawable.kenan4));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class MyRecyclerAdapter extends Adapter<MyRecyclerAdapter.MyHolder> {

private Context mContext;
private List<Integer> mDatas;
private List<Integer> heights;
private onItemClickListener onItemClickListener;
public MyRecyclerAdapter(Context context, List<Integer> datas) {
super();
this.mContext = context;
this.mDatas = datas;
getRandomHeight(this.mDatas);
}

public interface onItemClickListener{
//条目被点击时触发的回调
void onOnItemClick(View view,int position);
//长按时触发的回调
void onLongClick(View view,int position);
}

public void setOnItemClickListener(onItemClickListener onItemClickListener) {
this.onItemClickListener = onItemClickListener;
}
@Override
public int getItemCount() {
// TODO Auto-generated method stub
return mDatas.size();
}

@Override
// 填充onCreateViewHolder方法返回的holder中的控件
public void onBindViewHolder(final MyHolder holder, int position) {
// TODO Auto-generated method stub
//得到item的LayoutParams布局参数
ViewGroup.LayoutParams params= holder.itemView.getLayoutParams();
//把随机的高度赋予item布局
params.height = heights.get(position);
//把params设置给item布局
holder.itemView.setLayoutParams(params);
//为控件绑定数据
holder.imageView.setImageResource(mDatas.get(position));
//如果设置了监听那么它就不为空,然后回调相应的方法
if(onItemClickListener!=null){
holder.itemView.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
//得到当前点击item的位置pos
int position = holder.getLayoutPosition();
//把事件交给我们实现的接口那里处理
onItemClickListener.onOnItemClick(holder.itemView, position);
}
});
holder.itemView.setOnLongClickListener(new OnLongClickListener() {

@Override
public boolean onLongClick(View v) {
//得到当前点击item的位置pos
int position = holder.getLayoutPosition();
//把事件交给我们实现的接口那里处理
onItemClickListener.onOnItemClick(holder.itemView, position);
return true;
}
});
}
}

@Override
// 重写onCreateViewHolder方法,返回一个自定义的ViewHolder
public MyHolder onCreateViewHolder(ViewGroup viewGroup, int arg1) {
// 填充布局
View view = LayoutInflater.from(mContext).inflate(R.layout.item,viewGroup, false);
MyHolder holder = new MyHolder(view);
return holder;
}

// 定义内部类继承ViewHolder
class MyHolder extends ViewHolder {

private ImageView imageView;
public MyHolder(View view) {
super(view);
imageView = (ImageView) view.findViewById(R.id.iv_item);
}

}
//得到随机item的高度
private void getRandomHeight(List<Integer> datas) {
heights = new ArrayList<Integer>();
for (int i = 0; i < datas.size(); i++) {
heights.add((int) (200+Math.random()*100));
}
}
}

一篇博客理解Recyclerview的使用的更多相关文章

  1. Hello World -- 第一篇博客

    今年注定是不寻常的一年,因为技术,接触了许多大牛.通过一篇篇博文,看到了大牛们勤奋好学.孜孜不倦的精神,于是决定也开个博客,向大牛学习. 博客开了,写点什么呢?奈何肚子里墨水不多,吐出来也多是白沫,不 ...

  2. C博客作业00—我的第一篇博客

    C博客作业00-我的第一篇博客 1. 你对网络专业或者计算机专业了解是怎样? 泛泛了解 - 原先只知道网络工程隶属于计算机工程学院,与院中其他专业一样,同样都需要学习大量的计算机基础知识,然后再分支学 ...

  3. [书籍]值得纪念的第100篇博客,推荐一些看过的UI书籍

    1. 前言 来到博客园11年,这两年闲下来了才有时间写写博客,不知不觉终于写到第100篇博客了.回顾过去发表的博客,居然大部分都与UI相关.明明我本来从事的是Oracle的相关开发,明明我当初的目标是 ...

  4. 从SAP社区上的一篇博客开始,聊聊SAP产品命名背后的那份情怀

    最近Jerry在SAP社区上看到一篇博客:It's Steampunk now. 博客原文:https://blogs.sap.com/2019/08/20/its-steampunk-now/ 什么 ...

  5. Hello World -- 第一篇博客 -- 活着的意义

    今年注定是不寻常的一年,因为技术,接触了许多大牛.通过一篇篇博文,看到了大牛们勤奋好学.孜孜不倦的精神,于是决定也开个博客,向大牛学习. 博客开了,写点什么呢?奈何肚子里墨水不多,吐出来也多是白沫,不 ...

  6. 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段 | 百篇博客分析OpenHarmony源码 | v71.01

    子曰:"我非生而知之者,好古,敏以求之者也." <论语>:述而篇 百篇博客系列篇.本篇为: v71.xx 鸿蒙内核源码分析(Shell编辑篇) | 两个任务,三个阶段 ...

  7. 鸿蒙内核源码分析(文件句柄篇) | 深挖应用操作文件的细节 | 百篇博客分析OpenHarmony源码 | v69.01

    百篇博客系列篇.本篇为: v69.xx 鸿蒙内核源码分析(文件句柄篇) | 深挖应用操作文件的细节 | 51.c.h.o 文件系统相关篇为: v62.xx 鸿蒙内核源码分析(文件概念篇) | 为什么说 ...

  8. 鸿蒙内核源码分析(字符设备篇) | 字节为单位读写的设备 | 百篇博客分析OpenHarmony源码 | v67.01

    百篇博客系列篇.本篇为: v67.xx 鸿蒙内核源码分析(字符设备篇) | 字节为单位读写的设备 | 51.c.h.o 文件系统相关篇为: v62.xx 鸿蒙内核源码分析(文件概念篇) | 为什么说一 ...

  9. 鸿蒙内核源码分析(根文件系统) | 先挂到`/`上的文件系统 | 百篇博客分析OpenHarmony源码 | v66.01

    百篇博客系列篇.本篇为: v66.xx 鸿蒙内核源码分析(根文件系统) | 先挂到/上的文件系统 | 51.c.h.o 文件系统相关篇为: v62.xx 鸿蒙内核源码分析(文件概念篇) | 为什么说一 ...

随机推荐

  1. html初始化页面和a标签无下划线

    body, div, p, h1, h2, h3, h4, h5, h6, ul, ol, li, dl, dd, dt, img, form { padding:0px; margin:0px; b ...

  2. sql传入组合字符串批量操作

    批量操作时我们可以传入一个有规律的ID或则是其他唯一值字段的组合字符串,然后:select/update/inset......where  字段 in(传入的组合字符串),而且很多时候我们还涉及到其 ...

  3. 【Linux_Fedora_应用系列】_1_如何安装音乐播放器和mp3解码

    因为安装环境的不同,Fedora在安装后会安装不同的软件包.通常在安装的时候有多种选择: 1.桌面环境: 适合个人日常使用,安装包含办公软件(Fedora 默认安装Open Office).娱乐影音软 ...

  4. Python实现装饰模式的一段代码

    # 实现装饰模式的一段代码 import functools def log(func): @functools.wraps(func) def wrapper(*args,**kw): print( ...

  5. 更新整理本人所有博文中提供的代码与工具(Java,2013.10)

    为了更方便地管理博文中涉及的各种代码与工具资源,现在把这些资源迁移到 Google Code 中,有兴趣者可前往下载. Java 1.<高效 Java Web 应用开发框架 JessMA v3. ...

  6. GJM :用JIRA管理你的项目(三)基于LDAP用户管理 [转载]

    感谢您的阅读.喜欢的.有用的就请大哥大嫂们高抬贵手"推荐一下"吧!你的精神支持是博主强大的写作动力以及转载收藏动力.欢迎转载! 版权声明:本文原创发表于 [请点击连接前往] ,未经 ...

  7. Atitit.atiRI  与 远程调用的理论and 设计

    Atitit.atiRI  与 远程调用的理论and 设计 1. 怎么做到透明化远程服务调用?1 2. 2  怎么对消息进行编码和解码1 2.1.  确定消息数据结构dsl1 2.1.1. 消息里为什 ...

  8. WinDbg调试.NET程序入门

    俗话说:万事开头难! 自从来到新公司遇到性能问题后,需要想办法解决这个问题,但是一直没有合适的性能分析工具,然后找到StevenChennet 大神帮忙,他用WinDbg工具远程帮我分析了一个 dum ...

  9. Reapp - 下一代的 Hybrid App 开发框架

    Reapp 与 React Native 有着惊人的相似之处,二者都使用 React 来创建应用程序用户界面的框架.然而,在底层机制上这两个框架之间却具有明显的哲学差异.React Native 将 ...

  10. 小技巧,如何在Label中显示图片

    这个需求其实是有的,比如QQ聊天界面里面发送的信息,可以用label来显示文字(也可以用button显示),但是有时候用户可能会发送图片.如果能让Label遇到文字就显示文字,遇到图片就显示图片就好了 ...