2.6、滚动控件-RecylerView

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

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

扩展性也不是很好

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

实现横向滚动是做不到的

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

是一个增强版的ListView

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

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

目前官方更推荐使用RecyclerView

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

1、基本用法

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

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

再first_activity中:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<
android.support.v7.widget.RecyclerView
android:id="@+id/recyler_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
</android.support.v7.widget.RecyclerView> </LinearLayout>

新建一个适配类

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

public class FruitAdaperRecyler extends RecyclerView.Adapter<FruitAdaperRecyler.ViewHolder> {
private List<Fruit> fruitList; @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,null,false);
ViewHolder viewHolder = new ViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
Fruit fruit = fruitList.get(position);
holder.textView.setText(fruit.getName());
holder.imageView.setImageResource(fruit.getId()); }
@Override
public int getItemCount() {
return fruitList.size();
} //自定义的内部类
class ViewHolder extends RecyclerView.ViewHolder{
//布局文件中的两个控件
ImageView imageView;
TextView textView;
public ViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.image_view);
textView = (TextView) itemView.findViewById(R.id.text_view);
}
} //构造器
public FruitAdaperRecyler(List<Fruit> fruits){
this.fruitList = fruits;
}
}

首先定义一个内部类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中的代码:

public class MainActivity extends AppCompatActivity {
private List<Fruit> fruitList = new ArrayList<>(); private void initFruit(){
Fruit apple = new Fruit("Apple1",R.drawable.qq);
fruitList.add(apple);
Fruit apple1 = new Fruit("Apple2",R.drawable.qq);
fruitList.add(apple1);
Fruit apple2 = new Fruit("Apple3",R.drawable.qq);
fruitList.add(apple2);
Fruit apple3 = new Fruit("Apple4",R.drawable.qq);
fruitList.add(apple3);
Fruit apple4 = new Fruit("Apple5",R.drawable.qq);
fruitList.add(apple4);
Fruit apple5 = new Fruit("Apple6",R.drawable.qq);
fruitList.add(apple5);
Fruit apple6 = new Fruit("Apple7",R.drawable.qq);
fruitList.add(apple6);
} @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.firstlayout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
actionBar.hide();
}
//初始化
initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(linearLayoutManager);
FruitAdaperRecyler fruitAdaperRecyler = new
FruitAdaperRecyler(fruitList); recyclerView.setAdapter(fruitAdaperRecyler);
}
}

使用initFruit进行初始化数据

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

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

再进行创建FruitAdapterRecyler的实例

并且将水果的数据传入

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

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

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

再实现的过程中逻辑清晰

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

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

适用于纵向滚动的场景

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

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="100dp"
android:layout_height="match_parent"> <ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/text_view"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </LinearLayout>

将LinerLayout改成垂直方向的排列

此时设置的宽度时100dp

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

进行修改代码:

 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.firstlayout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
actionBar.hide();
}
//初始化
initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view); LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); recyclerView.setLayoutManager(linearLayoutManager);
FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList); recyclerView.setAdapter(fruitAdaperRecyler);
}

之加入了一行代码

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

此时的设置表示横向排列

默认是纵向排列

处LInearLayoutManager之外

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

前者可以实现网格布局

后者可以实现瀑布流布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"> <ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" />
<TextView
android:id="@+id/text_view"
android:layout_marginTop="10dp"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content" /> </LinearLayout>

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.firstlayout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null){
actionBar.hide();
}
//初始化
initFruit(); RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyler_view);

StaggeredGridLayoutManager
staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
FruitAdaperRecyler fruitAdaperRecyler = new FruitAdaperRecyler(fruitList);
recyclerView.setAdapter(fruitAdaperRecyler);
}
StaggeredGridLayoutManager staggeredGridLayoutManager =  new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);

第一个参数用于指定列数

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

结果展示:

3、点击事件:

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

代码如下:

public class FruitAdaperRecyler extends RecyclerView.Adapter<FruitAdaperRecyler.ViewHolder> {
private List<Fruit> fruitList; @Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.fruit_item,null,false);
final ViewHolder viewHolder = new ViewHolder(view); //点击事件的监听
viewHolder.fruitView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getAdapterPosition();
Fruit fruit = fruitList.get(position);
Toast.makeText(v.getContext(),"clicked:"+fruit.getName(),Toast.LENGTH_LONG).show();
}
});
viewHolder.imageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int position = viewHolder.getAdapterPosition();
Fruit fruit = fruitList.get(position);
Toast.makeText(v.getContext(),"click image :" + fruit.getName(),Toast.LENGTH_LONG).show();
}
});
return viewHolder;
} @Override
public void onBindViewHolder(ViewHolder holder, int position) {
Fruit fruit = fruitList.get(position);
holder.textView.setText(fruit.getName());
holder.imageView.setImageResource(fruit.getId()); } @Override
public int getItemCount() {
return fruitList.size();
} //自定义的内部类
class ViewHolder extends RecyclerView.ViewHolder{
//布局文件中的两个控件
ImageView imageView;
TextView textView;
View fruitView; public ViewHolder(View itemView) {
super(itemView);
fruitView=itemView;
imageView = (ImageView) itemView.findViewById(R.id.image_view);
textView = (TextView) itemView.findViewById(R.id.text_view);
}
} //构造器
public FruitAdaperRecyler(List<Fruit> fruits){
this.fruitList = fruits;
}
}

首先是在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. Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构

    Hadoop源码学习笔记(5) ——回顾DataNode和NameNode的类结构 之前我们简要的看过了DataNode的main函数以及整个类的大至,现在结合前面我们研究的线程和RPC,则可以进一步 ...

  2. windbg .net 程序的死锁检测 常用方法(个人备份笔记)

    //死锁检测 .load sosex.dll :> !dlk :> !mk -a The mk command displays a call stack of the currently ...

  3. Spring系列之——使用模板快速搭建springboot项目

    1 在官网https://start.spring.io/生成spring boot的模板 2 IDEA导入模板,设置如下勾选项,其他选项卡为默认值 3 idea呈现 4 新增controller类 ...

  4. 粘性页脚 Sticky Footer 最佳方式

    前段时间工作中遇到粘性页脚的需求,以前用过JS控制过,最后发现flex布局是解决这类问题的好帮手. 粘性页脚:即使没有足够的内容填充页面,也要将页脚固定到窗口的底部. <!DOCTYPE htm ...

  5. BZOJ2960:跨平面

    题面 BZOJ Sol 对该平面图的对偶图建图后就是最小树形图,建一个超级点向每个点连 \(inf\) 边即可 怎么转成对偶图,怎么弄出多边形 把边拆成两条有向边,分别挂在两个点上 每个点的出边按角度 ...

  6. HDU P2222 Keywords Search

    In the modern time, Search engine came into the life of everybody like Google, Baidu, etc.Wiskey als ...

  7. 【转载】windows 下重置 mysql 的 root 密码

      今天发现 WordPress 连接不上数据库,登录 window server 服务器查看,所有服务均运行正常. 使用 root 账号登录 mysql 数据库,结果提示密码不匹配.我突然意识到,服 ...

  8. PHP实用系统函数之数组篇

    PHP中十分实用的系统函数 array array_merge 说明:array  array_merge ( array $array1 [, array $... ] ) 将一个或多个数组的单元合 ...

  9. PHP之SimpleXML函数

    使用php创建XML文件十分简单,使用SimpleXML那就更简便了,同时读取XML文件也十分方便.XML文件是直接在浏览器中打开,以自定义标签的方式直观简洁的方式展示给读者. 1.创建XML文件 h ...

  10. Ajax实现表格实时编辑

    如果我们的对于一个表格中所有的数据都能在本页进行操作那该是多酷炫的一件事(用起来炒鸡爽)! 用Ajax就可以实现这个功能啦.废话不多说,下面贴出我写的demo吧哈哈.我用的TP框架(3.2)比较习惯啦 ...