1.RecyclerView 

<1>知识点介绍

  RecyclerView 比 ListView 更高级且更具灵活性。 它是一个用于显示庞大数据集的容器,可通过保持有限数量的视图进行非常有效的滚动操作。 如果您有数据集合,其中的元素将因用户操作或网络事件而在运行时发生改变,请使用 RecyclerView 。

  RecyclerView代表的意义是,我只管Recycler View,也就是说RecyclerView只管回收与复用View,其他的你可以自己去设置。可以看出其高度的解耦,给予你充分的定制自由(所以你才可以轻松的通过这个控件实现ListView,GirdView,瀑布流等效果)

  要实现一个RecyclerView,会接触到它的几个小伙伴,其中1、2是必须的。剩下的3、4、5三项,可以让RecyclerView更好看、效果更好。

    (1)想要控制其item们的排列方式,请使用布局管理器LayoutManager

    (2)如果要创建一个适配器,请使用RecyclerView.Adapter

    (3)想要控制Item间的间隔,请使用RecyclerView.ItemDecoration

    (4)想要控制Item增删的动画,请使用RecyclerView.ItemAnimator

    (5)CardView 扩展 FrameLayout 类并让您能够显示卡片内的信息,这些信息在整个平台中拥有一致的呈现方式。CardView 小部件可拥有阴影和圆角。
  

2. 实际案例

<1>先将RecyclerView拖入界面

<2>源码(对应工程名为test17)

使用RecyclerView需在build.gradle中添加声明

implementation 'com.android.support:design:28.0.0'

(1)XML页面布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".recyclerview.Recycler2Activity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"> <Button
android:id="@+id/button_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="添加" /> <Button
android:id="@+id/button_delete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="删除" /> <Button
android:id="@+id/button_list"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="list" /> <Button
android:id="@+id/button_grid"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="grid" /> <Button
android:id="@+id/button_flow"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="flow" /> </LinearLayout> <android.support.v7.widget.RecyclerView
android:id="@+id/recycler_test1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1" /> </LinearLayout>

(2)适配器源码

package com.lucky.test17.recyclerview;

import android.content.Context;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast; import com.lucky.test17.R; import java.util.ArrayList; public class MyRecyclerViewAdapter extends RecyclerView.Adapter<MyRecyclerViewAdapter.MyViewHolder> { private final Context content;
private final ArrayList<String> datas; //构造方法
public MyRecyclerViewAdapter(Context content, ArrayList<String> datas) {
this.content=content;
this.datas=datas;
} @NonNull
@Override
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
View viewItem=View.inflate(content, R.layout.item_recycle,null);
return new MyViewHolder(viewItem);
} //数据与view绑定
@Override
public void onBindViewHolder(@NonNull MyViewHolder myViewHolder, int i) {
//根据位置得到对应的数据
String str=datas.get(i);
myViewHolder.textView.setText(str);
} //得到总条数
@Override
public int getItemCount() {
return datas.size();
} class MyViewHolder extends RecyclerView.ViewHolder{
ImageView imageView;
TextView textView; public MyViewHolder(@NonNull View itemView) {
super(itemView);
imageView=itemView.findViewById(R.id.image1);
textView=itemView.findViewById(R.id.test1);
itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(content,"data=="+datas.get(getLayoutPosition()),Toast.LENGTH_SHORT).show();
}
});
}
}
}

(3)分割线源码(直接调用即可)

package com.lucky.test17.recyclerview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.v4.content.ContextCompat;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.View; /**
* @DateTime: 2016-07-21 17:55
* @Author: duke
* @Deacription: recyclerview万能分割线
*/
public class RecycleViewDivider extends RecyclerView.ItemDecoration { private Paint mPaint;//如果需要用画笔手绘
private Drawable mDrawableDivider;//如果需要绘制给定的drawable
private int mPaintDividerLength = 2;//分割线宽度或高度
private DrawType drawType;//用画笔绘制颜色,还是绘制特定的drawable
/**
* 注意:列表的方向
* LinearLayoutManager.VERTICAL或LinearLayoutManager.HORIZONTAL
*/
private int mOrientation;
//系统默认的分割线
private static final int[] ATTRS = new int[]{android.R.attr.listDivider}; /**
* 自定义分割线
*
* @param context
* @param orientation 列表方向
* @param drawableId 分割线图片
*/
public RecycleViewDivider(Context context, int orientation, int drawableId) {
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
throw new IllegalArgumentException("请输入正确的参数!");
}
mOrientation = orientation;
if (drawableId == -100) {
//获取系统的样式
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDrawableDivider = a.getDrawable(0);
a.recycle();
} else {
mDrawableDivider = ContextCompat.getDrawable(context, drawableId);
}
//表明绘制drawable
drawType = DrawType.USEDRAWABLE;
} /**
* @param context 上下文
* @param orientation 列表方向
*/
public RecycleViewDivider(Context context, int orientation) {
this(context, orientation, -100);
} /**
* 自定义分割线
* @param orientation 列表方向
* @param dividerHeight 分割线高度
* @param dividerColor 分割线颜色
*/
public RecycleViewDivider(int orientation, int dividerHeight, int dividerColor) {
if (orientation != LinearLayoutManager.VERTICAL && orientation != LinearLayoutManager.HORIZONTAL) {
throw new IllegalArgumentException("请输入正确的参数!");
}
mOrientation = orientation;
if (dividerHeight != -100) {
//分割线高度
mPaintDividerLength = dividerHeight;
}
//创建特定画笔
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setColor(dividerColor);
mPaint.setStyle(Paint.Style.FILL);
//表明绘制用paint
drawType = DrawType.USEPAINT;
} /**
* 自定义分割线
*
* @param orientation 列表方向
* @param dividerColor 分割线颜色
*/
public RecycleViewDivider(int orientation, int dividerColor) {
this(orientation, -100, dividerColor);
} /**
* 看图说话:get Item Offsets,获得item的偏移量。此方法用来控制item的偏移
* @param outRect
* @param view
* @param parent
* @param state
*/
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
super.getItemOffsets(outRect, view, parent, state);
/**
* 列表的方向为横向,画分割线就是纵向的,需要确定的是child的右边偏移值
* 留出空间画分割线
*/
if (this.mOrientation == LinearLayoutManager.HORIZONTAL)
switch (drawType) {
case USEPAINT:
outRect.set(0, 0, mPaintDividerLength, 0);
break;
case USEDRAWABLE:
outRect.set(0, 0, mDrawableDivider.getIntrinsicWidth(), 0);
break;
}
/**
* 列表的方向为纵向,画分割线就是横向的,需要确定的是child的下边偏移值
* 留出空间画分割线
*/
else if (this.mOrientation == LinearLayoutManager.VERTICAL)
switch (drawType) {
case USEPAINT:
outRect.set(0, 0, 0, mPaintDividerLength);
break;
case USEDRAWABLE:
outRect.set(0, 0, 0, mDrawableDivider.getIntrinsicHeight());
break;
}
} /**
* 绘制分割线
* @param c
* @param parent
* @param state
*/
@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
super.onDraw(c, parent, state);
if (mOrientation == LinearLayoutManager.VERTICAL) {
//列表是纵向的,需要绘制横向的分割线
drawHorizontal(c, parent);
} else {
//列表是横向的,需要绘制纵向的分割线
drawVertical(c, parent);
}
} /**
* 绘制横向 item 分割线。左、上、右都是可计算的,下需要获取给定的高度值
* @param canvas
* @param parent
*/
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
//左边:到父容器的left内间距位置值
final int left = parent.getPaddingLeft();
//右边:到父容器的right内间距位置值
final int right = parent.getMeasuredWidth() - parent.getPaddingRight();
final int childSize = parent.getChildCount();
//循环绘制每条分割线
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
//上边:具体的某条分割线的左边以child的(bottom+bottomMargin)位置值
final int top = child.getBottom() + layoutParams.bottomMargin;
//下边:根据类型判断
int bottom;
switch (drawType){
case USEPAINT://构造方法声明使用画笔绘制
//下边:top加上指定的高度
bottom = top + mPaintDividerLength;
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
break;
case USEDRAWABLE://构造方法声明使用drawable
if (mDrawableDivider != null) {
//下边:top加上指定的高度
bottom = top + mDrawableDivider.getIntrinsicHeight();
mDrawableDivider.setBounds(left, top, right, bottom);
mDrawableDivider.draw(canvas);
}
break;
}
}
}
/**
* 绘制纵向 item 分割线。上、下、左都是可计算的,右侧需要获取给定的宽度值
* @param canvas
* @param parent
*/
private void drawVertical(Canvas canvas, RecyclerView parent) {
//上边:到父容器的top内间距位置值
final int top = parent.getPaddingTop();
//下边:到父容器的bottom内间距位置值
final int bottom = parent.getMeasuredHeight() - parent.getPaddingBottom();
final int childSize = parent.getChildCount();
//循环绘制每条分割线
for (int i = 0; i < childSize; i++) {
final View child = parent.getChildAt(i);
RecyclerView.LayoutParams layoutParams = (RecyclerView.LayoutParams) child.getLayoutParams();
//左边:具体的某条分割线的左边以child的(right+rightMargin)位置值
final int left = child.getRight() + layoutParams.rightMargin;
//右边:根据类型判断
int right;
switch (drawType){
case USEPAINT://构造方法声明使用画笔绘制
//右边:left加上指定的宽度
right = left + mPaintDividerLength;
if (mPaint != null) {
canvas.drawRect(left, top, right, bottom, mPaint);
}
break;
case USEDRAWABLE://构造方法声明使用drawable
if (mDrawableDivider != null) {
//右边:left加上指定的宽度
right = left + mDrawableDivider.getIntrinsicWidth();
mDrawableDivider.setBounds(left, top, right, bottom);
mDrawableDivider.draw(canvas);
}
break;
}
}
}
public static enum DrawType {
USEPAINT(1),//用画笔画
USEDRAWABLE(2); //画特定的drawable
private final int type;
DrawType(int type) {
this.type = type;
}
public int getType() {
return type;
}
}
}

(4)主屏幕源码

package com.lucky.test17.recyclerview;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout; import com.lucky.test17.R; import java.util.ArrayList; public class Recycler2Activity extends AppCompatActivity { private Button button_add;
private Button button_delete;
private Button button_list;
private Button button_grid;
private Button button_flow;
private RecyclerView recyclerView;
private ArrayList<String> datas;
private MyRecyclerViewAdapter myAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recycler2);
initview();
initdata(); //设置RecyclerView的适配器
myAdapter=new MyRecyclerViewAdapter(Recycler2Activity.this,datas);
recyclerView.setAdapter(myAdapter); //设置分割线
recyclerView.addItemDecoration(new RecycleViewDivider(Recycler2Activity.this,LinearLayout.VERTICAL)); } //设置数据集合
private void initdata() {
datas=new ArrayList<>();
for (int i = 0; i <100 ; i++) {
datas.add("content_"+i);
}
} private void initview() {
button_add=findViewById(R.id.button_add);
button_delete=findViewById(R.id.button_delete);
button_list=findViewById(R.id.button_list);
button_grid=findViewById(R.id.button_grid);
button_flow=findViewById(R.id.button_flow);
recyclerView=findViewById(R.id.recycler_test1); button_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { }
});
button_delete.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) { }
});
button_list.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//使用布局管理器LayoutManager,实现list效果
recyclerView.setLayoutManager(new LinearLayoutManager(Recycler2Activity.this,LinearLayoutManager.VERTICAL,false));
}
});
button_grid.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//使用布局管理器LayoutManager,实现Grid效果
recyclerView.setLayoutManager(new GridLayoutManager(Recycler2Activity.this,3,GridLayoutManager.VERTICAL,false));
}
});
button_flow.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//使用布局管理器LayoutManager,实现瀑布流效果
recyclerView.setLayoutManager(new StaggeredGridLayoutManager(4,StaggeredGridLayoutManager.VERTICAL));
}
});
}
}

<3>效果图:

2.ListView组件(了解,可以用RecyclerView 组件替换)

<1>介绍

<2>XML属性

3.Spinner(下拉列表框)

<1>简介

<2>xml 文件配置

(1)列表下拉框里的内容可以写在strings.xml文件中

<resources>
<string name="app_name">zjzyhq</string>
<string-array name="riskrank">
<item>----</item>
<item>红</item>
<item>橙</item>
<item>黄</item>
<item>蓝</item>
</string-array>
</resources>

(2)在屏幕布局文件中

<Spinner
android:entries="@array/riskrank"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

Android RecyclerView组件和 Spinner(下拉列表框)的更多相关文章

  1. android新组件RecyclerView使用介绍和进阶使用,替用Gallery

    简介: RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用 ...

  2. 【转】android新组件RecyclerView使用介绍和进阶使用,替用Gallery

    简介: RecyclerView是support-v7包中的新组件,是一个强大的滑动组件,与经典的ListView相比,同样拥有item回收复用的功能,但是直接把viewholder的实现封装起来,用 ...

  3. Android最新组件RecyclerView,替代ListView

    转载请注明出处:http://blog.csdn.net/allen315410/article/details/40379159 万众瞩目的android最新5.0版本号不久前已经正式公布了,对于我 ...

  4. android基础组件---->Spinner的使用

    Spinner提供了一个快速的方式从集合中选择值.在默认状态下,一个Spinner显示的是当前选择的值.触摸Spinner会显示一个下拉菜单,用户可以从中选择一个值.今天我们就开始Spinner的学习 ...

  5. 登陆界面综合实例+spinner下拉列表框详解

      点击确定: 点击修改:     想到Spinner下拉按钮可以通过两种方法生成 方法一: 1.在array数组里面定义数组 代码如下: <resources> <st <? ...

  6. Android RecyclerView初体验

    很早之前就听说过RecyclerView这个组件了,但一直很忙没时间学习.趁着周末,就花了一天时间来学习RecyclerView. 准备工作 在Android Studio里新建一个Android项目 ...

  7. [Android]RecyclerView的简单演示样例

    去年google的IO上就展示了一个新的ListView.它就是RecyclerView. 下面是官方的说明,我英语能力有限,只是我大概这么理解:RecyclerView会比ListView更具有拓展 ...

  8. Android业务组件化之子模块SubModule的拆分以及它们之间的路由Router实现

    前言: 前面分析了APP的现状以及业务组件化的一些探讨(Android业务组件化之现状分析与探讨),以及通信的桥梁Scheme的使用(Android业务组件化之URL Scheme使用),今天重点来聊 ...

  9. Android业务组件化之现状分析与探讨

    前言: 从个人经历来说的话,从事APP开发这么多年来,所接触的APP的体积变得越来越大,业务的也变得越来越复杂,总来来说只有一句话:这是一个APP臃肿的时代!所以为了告别APP臃肿的时代,让我们进入一 ...

随机推荐

  1. copyWithZone详解

    [copyWithZone详解] NSObject实现了-copy.+copy.+copyWithZone方法.代码如下: + (id)copy { return (id)self; } + (id) ...

  2. Resin 的watchdog(看门狗)介绍和resin负载均衡实现

    为了稳定和安全,Resin使用一个独立的watchdog进程来启动和监视Resin服务器.watchdog连续你检测Resin服务器的状态,如果其没有反应或者迟钝,将会重启Resin服务器进程.大多数 ...

  3. 前端性能分析:分析百度和sogou

    先用httpwatch录制这两个网站:www.baidu.com  www.sogou.com 由上图可以看到: 百度用时0.278s 发送7831B 接收36620B 13个请求 搜狗       ...

  4. jsoup 的简单应用

    导入相关jar包 package jsoup.zr.com.utils; import java.io.IOException; import java.util.List; import org.j ...

  5. Hadoop完全分布式环境搭建(四)——基于Ubuntu16.04安装和配置Hadoop大数据环境

    [系统环境] [安装配置概要] 1.上传hadoop安装文件到主节点机器 2.给文件夹设置权限 3.解压 4.拷贝到目标文件夹 放在/opt文件夹下,目录结构:/opt/hadoop/hadoop-2 ...

  6. 10.IN 操作符

    IN 操作符 IN 操作符允许我们在 WHERE 子句中规定多个值. SQL IN 语法 SELECT column_name(s) FROM table_name WHERE column_name ...

  7. javascript总结17:javascript 函数简介

    1 释义:函数是由事件驱动的或者当它被调用时执行的可重复使用的代码块. 2 格式:通过 function  关键字. function test(){ alert("您好"); } ...

  8. [Lua快速了解一下]Lua运行

    -Lua的Hello World print("Hello World") 分号可选 -类似python,进入Lua后再shell中打命令执行语句也可 > print(&qu ...

  9. arcconf工具相关命令V1.0

    arcconf工具相关命令V1.0 清除当前所有raid配置 Arcconf  delete  1  array  all       #删除所有逻辑盘 Arcconf  uninit  1  all ...

  10. linux系统下ipmitool添加BMC帐号密码

    需求:已知BMC帐号id2为root管理员帐号,添加id5bmc帐号 工具:ipmitool version 1.8.14 系统:CentOS release 6.6 (Final) 1,通过yum安 ...