2.6、滚动控件-RecylerView

ListView虽然使用的效果很好但是也是有缺点的

不使用一些技巧来提升它的运行效率,性能就非常差

扩展性也不是很好

只能实现数据的纵向滚动效果

实现横向滚动是做不到的

Android提供一个更强大的滚动控件---RecylerView

是一个增强版的ListView

不仅可以轻松实现和ListView同样效果

还优化了ListView中 存在的不足之处

目前官方更推荐使用RecyclerView

未来会有更多的程序主键从ListView转向RecyclerView

1、基本用法

首先再app/build.gradle文件中引入:

  1. compile 'com.android.support:recyclerview-v7:23.4.0'

再first_activity中:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout
  3. xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent">
  6. <android.support.v7.widget.RecyclerView
  7. android:id="@+id/recyler_view"
  8. android:layout_width="match_parent"
  9. android:layout_height="match_parent">
  10. </android.support.v7.widget.RecyclerView>
  11.  
  12. </LinearLayout>

新建一个适配类

继承RecyclerView.Adapter,并且将泛型指定为内部类ViewHolder

  1. public class FruitAdaperRecyler extends RecyclerView.Adapter<FruitAdaperRecyler.ViewHolder> {
  2. private List<Fruit> fruitList;
  3.  
  4. @Override
  5. public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  6. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,null,false);
  7. ViewHolder viewHolder = new ViewHolder(view);
  8. return viewHolder;
  9. }
  10. @Override
  11. public void onBindViewHolder(ViewHolder holder, int position) {
  12. Fruit fruit = fruitList.get(position);
  13. holder.textView.setText(fruit.getName());
  14. holder.imageView.setImageResource(fruit.getId());
  15.  
  16. }
  17. @Override
  18. public int getItemCount() {
  19. return fruitList.size();
  20. }
  21.  
  22. //自定义的内部类
  23. class ViewHolder extends RecyclerView.ViewHolder{
  24. //布局文件中的两个控件
  25. ImageView imageView;
  26. TextView textView;
  27. public ViewHolder(View itemView) {
  28. super(itemView);
  29. imageView = (ImageView) itemView.findViewById(R.id.image_view);
  30. textView = (TextView) itemView.findViewById(R.id.text_view);
  31. }
  32. }
  33.  
  34. //构造器
  35. public FruitAdaperRecyler(List<Fruit> fruits){
  36. this.fruitList = fruits;
  37. }
  38. }

首先定义一个内部类ViewHolder

需要继承RecyclerHolder

然后再构造参数中要传入一个view参数

这个参数通常就是RecyclerView子项的最外层布局

那么就可以通过findViewById()方法获取到布局中的ImageView和TextView的实例

FruitAdaperRecyler类中有一个构造函数就是将要展示的数据传进来

并且复制给一个全局变量,后续的操作都是在全局变量的基础上进行的

FruitAdaperRecyler继承RecyclerView.Adapter就需要实现其中的三个方法

1、omCreateViewHolder()方法就是用于创建viewholder的实例,再方法中将fruit_item布局加载进来

  然后创建一个viewHolder实例,并把加载出来的布局传入传入到构造函数中

  最后将viewHolder的实例返回

2、onBinbViewHolder()方法用于对Recycler子项的数据进行赋值,会在每一个子项被滚动到屏幕内时执行

  这里通过position参数可以获得到当前的Fruit的实例,然后进行设置id和name

3、getItemCount()就是返回REcyclerView一共有多少个子项,直接返回数据源的长度即可

mainAcctivity中的代码:

  1. public class MainActivity extends AppCompatActivity {
  2. private List<Fruit> fruitList = new ArrayList<>();
  3.  
  4. private void initFruit(){
  5. Fruit apple = new Fruit("Apple1",R.drawable.qq);
  6. fruitList.add(apple);
  7. Fruit apple1 = new Fruit("Apple2",R.drawable.qq);
  8. fruitList.add(apple1);
  9. Fruit apple2 = new Fruit("Apple3",R.drawable.qq);
  10. fruitList.add(apple2);
  11. Fruit apple3 = new Fruit("Apple4",R.drawable.qq);
  12. fruitList.add(apple3);
  13. Fruit apple4 = new Fruit("Apple5",R.drawable.qq);
  14. fruitList.add(apple4);
  15. Fruit apple5 = new Fruit("Apple6",R.drawable.qq);
  16. fruitList.add(apple5);
  17. Fruit apple6 = new Fruit("Apple7",R.drawable.qq);
  18. fruitList.add(apple6);
  19. }
  20.  
  21. @Override
  22. protected void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.firstlayout);
  25. ActionBar actionBar = getSupportActionBar();
  26. if (actionBar != null){
  27. actionBar.hide();
  28. }
  29. //初始化
  30. initFruit();
  31.  
  32. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);
  33. LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
  34. recyclerView.setLayoutManager(linearLayoutManager);
  35. FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
  36. recyclerView.setAdapter(fruitAdaperRecyler);
  37. }
  38. }

使用initFruit进行初始化数据

再onCreate()方法中首先获取RecyclerView的实例

然后创建一个LinearLayoutManager对象,在这里是线性布局的意思

再进行创建FruitAdapterRecyler的实例

并且将水果的数据传入

醉胡调用RecyclerView的setAdapter()方法来完成适配器的设置

此时RecyrView和数据之间的关联建立完成

实现了和ListView几乎一样的效果

再实现的过程中逻辑清晰

2、实现横向滚动和瀑布流布局

文件中的布局元素都是水平排列的

适用于纵向滚动的场景

实现横向滚动则需要改成垂直排列

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="100dp"
  5. android:layout_height="match_parent">
  6.  
  7. <ImageView
  8. android:id="@+id/image_view"
  9. android:layout_width="wrap_content"
  10. android:layout_height="wrap_content"
  11. android:layout_gravity="center_horizontal"
  12.  
  13. />
  14. <TextView
  15. android:id="@+id/text_view"
  16. android:layout_marginTop="10dp"
  17. android:layout_gravity="center_horizontal"
  18. android:layout_width="wrap_content"
  19. android:layout_height="wrap_content" />
  20.  
  21. </LinearLayout>

将LinerLayout改成垂直方向的排列

此时设置的宽度时100dp

将宽度指定为固定的值可以有效的包裹文字,防止其过长或者过短的美观问题

进行修改代码:

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.firstlayout);
  5. ActionBar actionBar = getSupportActionBar();
  6. if (actionBar != null){
  7. actionBar.hide();
  8. }
  9. //初始化
  10. initFruit();
  11.  
  12. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);
  13.  
  14. LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
  15. linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
  16.  
  17. recyclerView.setLayoutManager(linearLayoutManager);
  18. FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
  19.  
  20. recyclerView.setAdapter(fruitAdaperRecyler);
  21. }

之加入了一行代码

调用LinearLayoutManager的setOrientation()方法来设置不久排列的排列方向

此时的设置表示横向排列

默认是纵向排列

处LInearLayoutManager之外

还提供了GridLayoutManagerStaggeredGridLayoutManager这两种内置的布局排列方式

前者可以实现网格布局

后者可以实现瀑布流布局

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="match_parent"
  5. android:layout_height="wrap_content"
  6. android:layout_margin="5dp">
  7.  
  8. <ImageView
  9. android:id="@+id/image_view"
  10. android:layout_width="wrap_content"
  11. android:layout_height="wrap_content"
  12. android:layout_gravity="center_horizontal"
  13.  
  14. />
  15. <TextView
  16. android:id="@+id/text_view"
  17. android:layout_marginTop="10dp"
  18. android:layout_gravity="center_horizontal"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content" />
  21.  
  22. </LinearLayout>

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4. setContentView(R.layout.firstlayout);
  5. ActionBar actionBar = getSupportActionBar();
  6. if (actionBar != null){
  7. actionBar.hide();
  8. }
  9. //初始化
  10. initFruit();
  11.  
  12. RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);

  13. StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
  14. recyclerView.setLayoutManager(staggeredGridLayoutManager);
  15. FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
  16. recyclerView.setAdapter(fruitAdaperRecyler);
  17. }
  1. StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);

第一个参数用于指定列数

第二个参数用于指定布局的排列方向

结果展示:

3、点击事件:

所有的点击事件都有具体的View去注册

代码如下:

  1. public class FruitAdaperRecyler extends RecyclerView.Adapter<FruitAdaperRecyler.ViewHolder> {
  2. private List<Fruit> fruitList;
  3. @Override
  4. public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
  5. View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,null,false);
  6. final ViewHolder viewHolder = new ViewHolder(view);
  7. //点击事件的监听
  8. viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
  9. @Override
  10. public void onClick(View v) {
  11. int position = viewHolder.getAdapterPosition();
  12. Fruit fruit = fruitList.get(position);
  13. Toast.makeText(v.getContext(),"clicked:"+fruit.getName(),Toast.LENGTH_LONG).show();
  14. }
  15. });
  16. viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
  17. @Override
  18. public void onClick(View v) {
  19. int position = viewHolder.getAdapterPosition();
  20. Fruit fruit = fruitList.get(position);
  21. Toast.makeText(v.getContext(),"click image :" + fruit.getName(),Toast.LENGTH_LONG).show();
  22. }
  23. });
  24. return viewHolder;
  25. }
  26. @Override
  27. public void onBindViewHolder(ViewHolder holder, int position) {
  28. Fruit fruit = fruitList.get(position);
  29. holder.textView.setText(fruit.getName());
  30. holder.imageView.setImageResource(fruit.getId());
  31. }
  32. @Override
  33. public int getItemCount() {
  34. return fruitList.size();
  35. }
  36. //自定义的内部类
  37. class ViewHolder extends RecyclerView.ViewHolder{
  38. //布局文件中的两个控件
  39. ImageView imageView;
  40. TextView textView;
  41. View fruitView;
  42. public ViewHolder(View itemView) {
  43. super(itemView);
  44. fruitView=itemView;
  45. imageView = (ImageView) itemView.findViewById(R.id.image_view);
  46. textView = (TextView) itemView.findViewById(R.id.text_view);
  47. }
  48. }
  49. //构造器
  50. public FruitAdaperRecyler(List<Fruit> fruits){
  51. this.fruitList = fruits;
  52. }
  53. }

首先是在ViewHolder中添加了fruitView变量来保存子项最外层的布局实例

然后再onCreateViewHolder()方法中注册点击事件

首先是获取用户点击的position

然后通过position获取用户拿到享用的Fruit实例

最后将内容进行显示

点击文字和图片都可以正常的进行打印显示的信息

2、Android-UI(RecyclerView)的更多相关文章

  1. 十二、Android UI开发专题(转)

    http://dev.10086.cn/cmdn/bbs/viewthread.php?tid=18736&page=1#pid89255Android UI开发专题(一) 之界面设计 近期很 ...

  2. 4、Android UI测试

    为你的APP进行UI测试是为了确保不出现意料之外的结果,提升用户的体验.如果你需要验证你的APP UI的正确性,你需要养成创建UI测试的习惯. Espresso测试框架是由Android Testin ...

  3. 90、 Android UI模板设计

    第一步:自定义xml属性 新建一个android项目,在values文件夹中新建一个atts.xml的文件,在这个xml文件中声明我们一会在使用自定义控件时候需要指明的属性.atts.xml < ...

  4. 19、android面试题整理(自己给自己充充电吧)

    (转载,出处丢失,请原作者原谅,如有意见,私信我我会尽快删除本文) JAVA 1.GC是什么? 为什么要有GC?GC是垃圾收集的意思(Gabage Collection),内存处理是编程人员容易出现问 ...

  5. 为什么说android UI操作不是线程安全的

    转载于:http://blog.csdn.net/lvxiangan/article/details/17218409#t2 UI线程及Android的单线程模型原则 使用Worker线程 Commu ...

  6. Android UI开发第二十八篇——Fragment中使用左右滑动菜单

    Fragment实现了Android UI的分片管理,尤其在平板开发中,好处多多.这一篇将借助Android UI开发第二十六篇——Fragment间的通信. Android UI开发第二十七篇——实 ...

  7. Android UI系列-----时间、日期、Toasts和进度条Dialog

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  8. 【转】Android UI系列-----时间、日期、Toasts和进度条Dialog

    原文网址:http://www.cnblogs.com/xiaoluo501395377/p/3421727.html 您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注 ...

  9. Android UI 切图命名规范、标注规范及单位描述(转载)

    本文转自:https://blog.csdn.net/klxh2009/article/details/74938009 很多UI设计师做APP切图都会有两套,一套是Android的,一套是IOS的. ...

  10. MAUI与Blazor共享一套UI,媲美Flutter,实现Windows、macOS、Android、iOS、Web通用UI

    1. 前言 距离上次发<MAUI初体验:爽>一文已经过去2个月了,本计划是下半年或者明年再研究MAUI的,现在计划提前啦,因为我觉得MAUI Blazor挺有意思的:在Android.iO ...

随机推荐

  1. 使用重绘项美化WinForm中的控件

    如果你觉得项目中的ComboBox.ListBox或其它的Winforms控件不能满足你的显示要求,包括窗体在内很多控件都支持重绘修改显示样式.下面的示例完成对ComBox数据项的重绘,希望能起到抛砖 ...

  2. java四则运算----前缀、中缀、后缀表达式

    接到一个新需求,需要实现可配置公式,然后按公式实现四则运算. 刚拿到需求,第一反应就是用正则匹配‘(’,‘)’,‘+’,‘-’,‘*’,‘/’,来实现四则运算,感觉不复杂. 然后开始coding.发现 ...

  3. 初学Node.js

    下载Node.js,官方网址:https://nodejs.org/en/download/ 可根据根据自己的电脑配置来下载相当于的Node.js 下载完成后使用Windows键+R 输入cmd 输入 ...

  4. POJ P2318 TOYS与POJ P1269 Intersecting Lines——计算几何入门题两道

    rt,计算几何入门: TOYS Calculate the number of toys that land in each bin of a partitioned toy box. Mom and ...

  5. Ubuntu,忘记了root密码,怎么重置?

    进入单用户模式: 1.开机到grub时,用上下键移到第二行的恢复模式,按e(注意不是回车) 即Ubuntu,With Linux 3.2.0-23-generic(recovery mode) 2.把 ...

  6. js只对等号左边的进行变量提升

    ### 只对等号左边的进行变量提升 > =:赋值,左边是变量,右边都应该是值 ```javascript //之前 i%2 === 0?item.className = 'c1':item.cl ...

  7. queue_monitor

    red_4 droptail_4

  8. [翻译] ABCIntroView

    ABCIntroView ABCIntroView is an easy to use onboarding which allows you to introduce your users to t ...

  9. TCP协议那些事

    tcp三次握手                                     tcp四次挥手   tcp十种状态 tcp的2MSL问题 说明 2MSL即两倍的MSL,TCP的TIME_WAI ...

  10. 猴子选大王【PHP】

    目录 猴子选大王 指针解决 数组压栈 猴子选大王 一群猴子排成一圈,按1,2,...,n依次编号.然后从第1只开始数,数到第m只,把它踢出圈,从它后面再开始数,再数到第m只,在把它踢出去...,如此不 ...