《第一行代码》核心知识点:Android的脸面之UI控件

news2025/2/27 16:13:15

《第一行代码》核心知识点:Android的脸面之UI控件

  • 前言
  • 三、Android的脸面之UI控件
    • 3.1 常用控件介绍
      • 3.1.1 TextView
      • 3.1.2 Button
      • 3.1.3 EditText
      • 3.1.4 ImageView
      • 3.1.5 ProgressBar
      • 3.1.6 AlertDialog
      • 3.1.7 ProgressDialog
    • 3.2 四种基本布局介绍
      • 3.2.1 线性布局
      • 3.2.2 相对布局
      • 3.2.3 帧布局
      • 3.2.4 百分比布局
      • 3.2.5 布局使用小技巧
    • 3.3 创建自定义控件
      • 3.3.1 常用控件与布局的继承结构
      • 3.3.2 自定义标题栏控件
    • 3.4 玩转ListView控件
      • 3.4.1 ListView控件简单案例(每项仅仅展示字符串)
      • 3.4.1 定制ListView子项数据的展示样式
    • 3.5 玩转RecyclerView控件
      • 3.5.1 由于RecyclerView属于新增控件,我们需要引用这个控件
      • 3.5.2 设计每个Item的布局
      • 3.5.3 设计列表中每个Item所包含要素的类
      • 3.5.4 定义适配器
      • 3.5.5 RecyclerView使用该适配器
      • 3.5.6 RecyclerView点击事件
  • 参考书籍:第一行代码

前言

本文讲解Android常用控件(包括ListView、RecyclerView)以及Android中常用几种布局。

三、Android的脸面之UI控件

3.1 常用控件介绍

3.1.1 TextView

文本控件,常用于显示文字。
常用xml属性如下:

  • android:id 标识该控件的id
  • android:layout_width 控件宽度,常取值"match_parent(与屏幕一样宽)"、wrap_content(与文本内容一样宽)、或者固定值
  • android:layout_height 控件宽度,取值与高度类似
  • android:text 显示的文本内容
  • android:textSize 文本字体大小
  • android:textColor 文本颜色
  • 等等

3.1.2 Button

按钮控件,一般用于用户点击操作。
常用xml属性与TextView差不多,其中Button控件的英文字母自动转为大写,可以通过android:textAllCaps="false"属性禁止该特性。

3.1.3 EditText

也是文本控件,但是与TextView控件的区别是,EditText控件允许用户在控件中输入和编辑内容。
常用xml属性与TextView差不多,一般编辑框中都会有提示信息,我们可以使用 android:hint=“info” xml属性设置提示信息。我们也可以通过android:maxLines="2"属性设置最大行数。

3.1.4 ImageView

展示图片的控件。
通过android:src 属性设置展示的图片

3.1.5 ProgressBar

用于在界面上显示一个进度条。
常用xml属性:

  • android:visibility 可以设置控件是否可见,主要有三种值,visible表示可见,这也是默认的设置;invisible表示不可见,但是它仍然占据屏幕控件,类似控件透明了;gone表示不可见,并且不再占屏幕空间。
  • style="@style/Widget.AppCompat.ProgressBar.Horizontal"设置进度条的形状
  • android:max=“100” 设置进度条的最大值,我们可以在程序中调用setProgress()方法修改进度值。

3.1.6 AlertDialog

在当前界面弹出一个对话框,这个对话框置于所有界面元素之上,能够屏蔽掉其它控件的交互能力,一般用于展示向用户进行提示的信息。
使用方法示例代码:

AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("这是一个提示对话框");
dialog.setMessage("请注意一些信息");
dialog.setCancelable(false);//不能通过back键返回
dialog.setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //点击确定后处理的事情
                    }
                });
dialog.setNegativeButton("取消", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        //点击取消后处理的事情
                    }
                });
dialog.show();

3.1.7 ProgressDialog

ProgressDialog会在界面上弹出一个带有进度条的窗口,一般用于显示进度。
使用方法示例代码如下:

ProgressDialog  dialog1=new ProgressDialog(MainActivity.this);
dialog1.setTitle("这是一条进度提示对话框");
dialog1.setMessage("进度提示信息");
dialog1.setCancelable(false);//用户不能通过back键关闭该窗口
dialog1.show();

数据处理完成后,我们可以调用 dialog1.dismiss();方法关闭窗口

3.2 四种基本布局介绍

布局是一种可以放置很多控件或布局的容器。布局就像是控件位置的顶层设计者,它可以按照一定的规律调整内部控件的位置,不然控件随意乱放,界面应该很难整洁精美。布局与控件的关系如图所示。
在这里插入图片描述

3.2.1 线性布局

线性布局(LinearLayout)可以将控件按照垂直或者水平方向排列。

  • 垂直方向 xml属性:android:orientation=“vertical”
  • 水平方向 xml属性:android:orientation=“horizontal”
  • android:layout_gravity与android:gravity的区别?
    android:layout_gravity是控件在布局中的对齐方式,而android:gravity是文字在控件中的对齐方式。需要注意的是,当LinearLayout的排列方向是horizontal时,只有垂直方向上的对齐方式才会生效,因为此时水平方向上的长度是不固定的,每添加一个控件,水平方向上的长度都会改变,因而无法指定该方向上的对齐方式。同样的道理,当LinearLayout的排列方向是vertical时,只有水平方向上的对齐方
  • android:layout_weight你真的会了吗?
    系统会首先计算LinearLayout下所有控件的android:layout_weight总值,然后每个控件所占大小的比例就是用该控件的android:layout_weight除以刚计算到的总值。例如,LinearLayout下有一个EditText控件,一个Button控件,如果想让EditText占据屏幕宽度的3/5,Button占据屏幕宽度的2/5,只需要将EditText的 layout_weight改成3,Button的 layout_weight改成2就可以了。

3.2.2 相对布局

相对布局(RelativeLayout)可以通过设置各个控件之间的相对位置让控件出现在布局的任何位置。

相对于父布局进行定位的常用xml属性:

  • android:layout_alignParentLeft 该控件是否在父布局的左侧
  • android:layout_alignParentRight 该控件是否在父布局的右侧
  • android:layout_alignParentTop 该控件是否在父布局的上侧
  • android:layout_alignParentBottom 该控件是否在父布局的下侧

相对于控件进行定位的常用xml属性:

  • android:layout_above 值为另一个控件的id,表明该控件在另一个控件的上方
  • android:layout_below 值为另一个控件的id,表明该控件在另一个控件的下方
  • android:layout_toLeftOf 值为另一个控件的id,表明该控件在另一个控件的左侧
  • android:layout_toRightOf 值为另一个控件的id,表明该控件在另一个控件的右侧
  • android:layout_alignLeft 值为另一个控件的id,表明该控件的左边缘另一个控件的左边缘对齐
  • android:layout_alignRight 值为另一个控件的id,表明该控件的右边缘另一个控件的右边缘对齐
  • android:layout_alignTop 值为另一个控件的id,表明该控件的上边缘另一个控件的上边缘对齐
  • android:layout_alignBottom 值为另一个控件的id,表明该控件的下边缘另一个控件的下边缘对齐

3.2.3 帧布局

帧布局(FrameLayout)所有的控件都默认摆放在布局的左上角。
帧布局也可以使用android:layout_gravity指定控件在布局中的对齐方式。

3.2.4 百分比布局

上面介绍的三种布局,我们发现只有LinearLayout支持使用layout_weight实现按比例指定控件大小的功能,其它两种布局都不支持。

因此Android为了使得相对布局和帧布局也支持按比例指定控件大小的功能,引入了PercentRelativeLayout和PercentFrameLayout两个布局,这两个布局是在RelativeLayout和FrameLayout的基础上去掉了使用wrap_content,match_parent等方式指定控件大小,而是允许直接指定控件在布局中所占的百分比

百分比布局属于新增布局,我们需要在build.grade中添加百分比布局的依赖就可以使用了。

  implementation "androidx.percentlayout:percentlayout:1.0.0"

在这里插入图片描述

百分比布局,常用xml属性:

  • app:layout_widthPercent 值为百分比,通过百分比指定控件宽度
  • -app:layout_heightPercent 值为百分比,通过百分比指定控件高度

3.2.5 布局使用小技巧

如果有个布局(比如标题栏)要在各个界面重复使用,我们就可以通过include将这个布局引入到各个界面。
在这里插入图片描述

3.3 创建自定义控件

3.3.1 常用控件与布局的继承结构

常用控件与布局的继承结构如下图所示。从图中可以看到所有控件都是直接或者间接的继承自View,所有布局都是直接或间接继承自ViewGroup。同理我们也可以利用上面的继承结构自定义我们的控件。
在这里插入图片描述

3.3.2 自定义标题栏控件

  1. 编写标题栏xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <Button
        android:id="@+id/title_back"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:text="Back"
        android:layout_gravity="center"
        android:textColor="#fff"/>

    <TextView
        android:id="@+id/title_text"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:layout_weight="1"
        android:gravity="center"
        android:text="title Text"
        android:textColor="@color/black"
        android:textSize="24sp"/>

    <Button
        android:id="@+id/title_edit"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:layout_gravity="center"
        android:text="Edit"
        android:textColor="@color/white"/>

</LinearLayout>
  1. 自定义标题栏类继承自LinearLayout
public class TitleLayout  extends LinearLayout {
    public TitleLayout(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        //获取并填充布局
        View view = LayoutInflater.from(context).inflate(R.layout.title, this);
        Button back = view.findViewById(R.id.title_back);
        Button edit=view.findViewById(R.id.title_edit);

        back.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "返回", Toast.LENGTH_SHORT).show();
            }
        });
        edit.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(context, "编辑", Toast.LENGTH_SHORT).show();
            }
        });

    }
}

3.4 玩转ListView控件

ListView数据有众多子项构成,每个子项代表一行数据,用于展示较多的数据,它根据设备屏幕大小展示部分数据,剩余部分的数据通过用户下拉展示。

3.4.1 ListView控件简单案例(每项仅仅展示字符串)

  1. 定义布局
<?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"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/list_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</LinearLayout>
  1. 将ListView与待展示的数据进行绑定,完成数据展示
public class MainActivity extends AppCompatActivity {

    //1. 设置待展示的数据
    private String[] data={"苹果","苹果","苹果","苹果","苹果","苹果","苹果","苹果",
            "苹果","苹果","苹果","苹果","苹果","苹果","苹果","苹果",
            "苹果","苹果","苹果","苹果","苹果","苹果","苹果","苹果"};
                @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //通过适配器,将ListView与待展示的数据进行绑定
        //android.R.layout.simple_list_item_1是Android内置简单xml布局,此处用于展示每项数据的布局
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,data);
        ListView listView = findViewById(R.id.list_view);
        listView.setAdapter(adapter);
     }
}

3.4.1 定制ListView子项数据的展示样式

子项数据的展示样式也是通过布局设定的,因此我们只需要编写Item布局样式,然后将该布局样式与ListView关联即可。

核心点:继承已有的适配器如ArrayAdapter,自定义适配器,并重写getView方法

假设我们ListView中每项包括水果名称及对应图片,定制ListViews过程如下:

  1. 自定义一个包含每项所需属性的实体类
public class Fruit {
    private String name;//水果名称
    private int imgID;//图片资源ID

    public Fruit(String name, int imgID) {
        this.name = name;
        this.imgID = imgID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImgID() {
        return imgID;
    }

    public void setImgID(int imgID) {
        this.imgID = imgID;
    }
}

  1. 编写每项数据展示的布局样式
<?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">

    <ImageView
        android:id="@+id/fruit_img"
        android:layout_width="wrap_content"
        android:layout_weight="1"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/fruit_name"
        android:layout_weight="1"
        android:gravity="center_vertical"
        android:layout_marginLeft="10dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>
  1. 定义适配器继承自ArrayAdapter,用于将ListView与待展示的每项数据进行绑定
public class FruitAdapter extends ArrayAdapter<Fruit> {

    /**
     * 展示每项数据的xml布局ID
     */
    private int resourceID;

    public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
        super(context, resource, objects);
        this.resourceID=resource;
    }

    //该方法在每个子项被滚动到屏幕内的时候调用
    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        //1. 获取该项数据
        Fruit fruit = getItem(position);
        //2. 获取该项用到的控件
        View view=LayoutInflater.from(getContext()).inflate(resourceID, parent, false);
        ImageView fruitImg = view.findViewById(R.id.fruit_img);
        TextView fruitName = view.findViewById(R.id.fruit_name);
        //3. 为每个控件设置相应的数据
        fruitImg.setImageResource(fruit.getImgID());
        fruitName.setText(fruit.getName());
        return view;
    }
}
  1. 使用自定义的ListView
public class MainActivity extends AppCompatActivity {

    private String[] data={"苹果","苹果","苹果","苹果","苹果","苹果","苹果","苹果",
            "苹果","苹果","苹果","苹果","苹果","苹果","苹果","苹果",
            "苹果","苹果","苹果","苹果","苹果","苹果","苹果","苹果"};

    private List<Fruit> fruits=new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //初始化要展示的数据
        initFruits();
        //1. 自定义的适配器中传入上下文,子项布局,子项数据集
        FruitAdapter fruitAdapter = new FruitAdapter(this, R.layout.fruit_item, fruits);
        ListView listView = findViewById(R.id.list_view);
        //2. 将适配器添加到ListView中
        listView.setAdapter(fruitAdapter);
        //3. 定义点击每个子项时的事件
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Fruit fruit = fruits.get(position);
                Toast.makeText(MainActivity.this,fruit.getName(),Toast.LENGTH_SHORT).show();
            }
        });

    }

    private void initFruits()
    {
        for (String datum : data) {
            fruits.add(new Fruit(datum,R.mipmap.apple));
        }
    }
}

上面第3步定义的适配器中会重复加载布局,并且重复调用findViewById,这会影响ListView展示数据的效率,下面进阶的适配器类解决了以上问题。

public class FruitAdapter extends ArrayAdapter<Fruit> {

    /**
     * 展示每项数据的xml布局ID
     */
    private int resourceID;

    public FruitAdapter(@NonNull Context context, int resource, @NonNull List<Fruit> objects) {
        super(context, resource, objects);
        this.resourceID=resource;
    }


    @NonNull
    @Override
    public View getView(int position, @Nullable View convertView, @NonNull ViewGroup parent) {
        //获取子项数据
        Fruit fruit = getItem(position);
        View view;
        ViewHolder viewTemp;
        //如果子项的布局未获取,则获取布局并临时保存布局中的子view
        if (convertView==null)
        {
            //获取布局
            view = LayoutInflater.from(getContext()).inflate(resourceID, parent, false);
            //获取布局中的控件并缓存到ViewHolder类中
            viewTemp=new ViewHolder();
            viewTemp.fruitImg=view.findViewById(R.id.fruit_img);
            viewTemp.fruitName=view.findViewById(R.id.fruit_name);
            //将缓存的布局中的控件通过setTag保存下来
            view.setTag(viewTemp);
        }
        //如果子项的布局已经获取,则直接拿到布局,不要重复获取
        else
        {
            //直接拿到布局,不要重复获取
            view=convertView;
            //通过getTag获取保存的布局中的控件
            viewTemp= (ViewHolder) view.getTag();
        }
        ImageView fruitImg = viewTemp.fruitImg;
        TextView fruitName = viewTemp.fruitName;
        //为子项中的控件设置相应的数据
        fruitImg.setImageResource(fruit.getImgID());
        fruitName.setText(fruit.getName());
        return view;
    }

    //包含子项所有控件的类,用于缓存对象
    class ViewHolder
    {
        ImageView fruitImg;
        TextView fruitName;
    }
}

3.5 玩转RecyclerView控件

ListView具有以下缺点:

  1. 需要开发者使用一些技巧提高它的效率,否则性能非常差
  2. 扩展性不好,如它只能实现纵向滚动,无法实现横向滚动

针对ListView的确定,Android提供了RecyclerView,它可以说是ListView的增强版,它本身对性能进行了内部优化,并且可以由用户来设定布局,可以方便实现横向滚动的效果等。

3.5.1 由于RecyclerView属于新增控件,我们需要引用这个控件

dependencies {
    //...
    implementation 'androidx.recyclerview:recyclerview:1.2.1'
    //...
}

3.5.2 设计每个Item的布局

如每个Item展示水果图片及名称

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_margin="5dp"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/fruit_img"
        android:layout_gravity="center_vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/fruit_name"
        android:layout_gravity="left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</LinearLayout>

3.5.3 设计列表中每个Item所包含要素的类

如每项展示水果图片及图片名

package com.example.recyclerviewtest;

public class Fruit {
    private String name;
    private int imgID;

    public Fruit(String name, int imgID) {
        this.name = name;
        this.imgID = imgID;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getImgID() {
        return imgID;
    }

    public void setImgID(int imgID) {
        this.imgID = imgID;
    }
}

3.5.4 定义适配器

首先适配器类继承自 RecyclerView.Adapter,其次在适配器类内定义内部类继承自RecyclerView.ViewHolder(这类似我们对ListView优化时的操作),然后在构造函数中传入数据,最后重写onCreateViewHolder(加载布局),onBindViewHolder(绑定数据),getItemCount(获取数据数量)三个方法。

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

    //继承RecyclerView.ViewHolder,为其添加列表属性
    static class ViewHolder extends RecyclerView.ViewHolder{

        ImageView fruitImage;
        TextView fruitName;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            fruitImage = itemView.findViewById(R.id.fruit_img);
            fruitName = itemView.findViewById(R.id.fruit_name);
        }
    }

    private List<Fruit> fruitList;

    //构造函数中传入数据
    public FruitAdapter(List<Fruit> fruitList)
    {
        this.fruitList=fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        //加载Item的布局
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fruit_item, viewGroup, false);
        //临时存储每个Item中的要素
        ViewHolder viewHolder = new ViewHolder(view);
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        //获取指定位置的数据 
        Fruit fruit = fruitList.get(i);
        //设置数据
        viewHolder.fruitImage.setImageResource(fruit.getImgID());
        viewHolder.fruitName.setText(fruit.getName());
    }

    @Override
    public int getItemCount() {
        return fruitList.size();
    }
}

3.5.5 RecyclerView使用该适配器

开发者可以通过setLayoutManager控制展示数据的布局类型及方向

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        initFruits();
        RecyclerView recyclerView = findViewById(R.id.recycle_view);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this);
        linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        //通过设置RecyclerView的布局,可以控制滚动的方向
        recyclerView.setLayoutManager(linearLayoutManager);
        FruitAdapter fruitAdapter = new FruitAdapter(fruits);
        //通过适配器绑定数据
        recyclerView.setAdapter(fruitAdapter);
    }

3.5.6 RecyclerView点击事件

RecyclerView点击事件是在适配器类重写的onCreateViewHolder方法中注册,虽然它写法上比ListView稍复杂,但是它更加灵活,可以很方便的控制子项里的任意要素的点击。对第4步定义的适配器类进行改造,添加点击事件,示例代码如下

public class FruitAdapter extends RecyclerView.Adapter<FruitAdapter.ViewHolder> {

    //继承RecyclerView.ViewHolder,为其添加列表属性
    static class ViewHolder extends RecyclerView.ViewHolder{

        ImageView fruitImage;
        TextView fruitName;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);

            fruitImage = itemView.findViewById(R.id.fruit_img);
            fruitName = itemView.findViewById(R.id.fruit_name);
        }
    }

    private List<Fruit> fruitList;

    //构造函数中传入数据
    public FruitAdapter(List<Fruit> fruitList)
    {
        this.fruitList=fruitList;
    }

    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
        //加载Item的布局
        View view = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fruit_item, viewGroup, false);
        //临时存储每个Item中的要素
        ViewHolder viewHolder = new ViewHolder(view);
        //=============================新增点击事件 start=============================
        //为图片添加点击事件
        viewHolder.fruitImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //获取当前点击图片的索引
                int position = viewHolder.getAdapterPosition();
                //根据索引获取数据
                Fruit fruit = fruitList.get(position);
                Toast.makeText(v.getContext(), "你点击了"+fruit.getName(), Toast.LENGTH_SHORT).show();
            }
        });
        //=============================新增点击事件 end=============================
        return viewHolder;
    }

    @Override
    public void onBindViewHolder(@NonNull ViewHolder viewHolder, int i) {
        //获取指定位置的数据 
        Fruit fruit = fruitList.get(i);
        //设置数据
        viewHolder.fruitImage.setImageResource(fruit.getImgID());
        viewHolder.fruitName.setText(fruit.getName());
    }

    @Override
    public int getItemCount() {
        return fruitList.size();
    }
}

参考书籍:第一行代码

链接:https://pan.baidu.com/s/1aXtOQCXL6qzxEFLBlqXs1Q?pwd=n5ag
提取码:n5ag

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/24654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更强悍 更智能!飞凌嵌入式FET3588-C核心板震撼发布!

为提升AIoT领域终端设备的处理能力以及智能化程度&#xff0c;飞凌嵌入式与瑞芯微强强联手&#xff0c;正式推出FET3588-C核心板&#xff01; 1、国芯之光 品质之选 FET3588-C核心板基于Rockchip新一代旗舰RK3588处理器开发设计&#xff0c;采用先进的8nm制程工艺&#xff0c; …

【软考软件评测师】第三十一章 操作系统综合知识

【软考软件评测师】第三十一章 操作系统综合知识 第三十一章 操作系统综合知识【软考软件评测师】第三十一章 操作系统综合知识第一部分 知识点集锦1.嵌入式操作系统1&#xff09;可裁剪性2&#xff09;实时性3&#xff09;统一的接口4&#xff09;弱交互性5&#xff09;更好的…

EasyExcel使用详解与源码解读

EasyExcel使用详解1、EasyExcel简单介绍64M内存20秒读取75M(46W行25列)的Excel&#xff08;3.0.2版本&#xff09;2、EasyExcel和POI数据处理能力对比3、使用EasyExcel读写Excel、web上传/下载3.1、写EXCEL3.2、读EXCEL3.3、web上传、下载4、EasyExcel源码解读5、总结1、EasyEx…

AdsPower VS Dolphin,哪款指纹浏览器性价比更高?

现在指纹浏览器已经成为了跨境人必备的账号安全工具&#xff0c;市面上的指纹浏览器也非常多&#xff0c;但其实真正专业的寥寥无几。现在市场上比较出名的浏览器有AdsPower、Dolphin、multilogin。为了比较出AdsPower和Dolphin功能上的差异&#xff0c;龙哥特地去下载使用了这…

三、nginx设置浏览器缓存[expires]

一、浏览器缓存 解释&#xff1a;浏览器缓存极大缓解了带宽压力&#xff0c;提高了用户体验。 访问页面-查看是否有缓存&#xff0c;如果没有过期&#xff0c;直接击中缓存&#xff0c;不向服务器发送请求访问页面-查看是否有缓存&#xff0c;如果过期&#xff0c;向服务器发送…

如何给async await批量添加try…catch?

如何给async await批量添加try…catch&#xff1f;async和await是什么&#xff1f;如何给async await批量添加try…catchbabel插件的实现思路插件的基本格式示例寻找await节点向上查找 async 函数添加用户选项babel插件的安装使用其他参考资料async和await是什么&#xff1f; …

深紫色粉末BHQ-1 NHS,916753-61-2,NHS修饰是合成后与一个伯氨基的共轭

英文名称&#xff1a;BHQ-1 NHS CAS&#xff1a;916753-61-2 外观&#xff1a;深紫色粉末 分子式&#xff1a;C30H31N7O7 分子量&#xff1a;601.62 储存条件&#xff1a;-20C&#xff0c;避光避湿 结构式&#xff1a; 凯新生物产品简介&#xff1a; NHS修饰是合成后与一…

程序员必知必会网络传输之TCP/IP协议族,共864页的详解文档让你原地起飞!

我们现实网络无处不在&#xff0c;我们被庞大的虚拟网络包围&#xff0c;但我们却对它是怎样把我们的信息传递并实现通信的&#xff0c;我们并没有了解过&#xff0c;那么当我们在浏览器中出入一段地址&#xff0c;按下回车这背后都会发生什么&#xff1f; 比如说一般场景下&a…

ubuntu18.04安装QT5

ubuntu18.04安装QT5 1、说明 QT界面本不应该做为一个很高的知识点&#xff0c;问题是&#xff0c;越来越多的程序实验&#xff0c;需要界面支持&#xff0c;或用界面显得更加方便&#xff0c;因而专门启动该栏目专门介绍QT方法。因为体系比较庞大&#xff0c;因此&#xff0c;需…

在腾讯云 TKE 上部署 EMQX MQTT 服务器集群

云进入以「应用为中心」的云原生阶段&#xff0c;Operator 模式的出现&#xff0c;为 Kubernetes 中的自动化任务创建配置与管理提供了一套行之有效的标准规范。针对大规模分布式物联网 MQTT 消息服务器 EMQX 全生命期管理的自动化管理工具 EMQX Kubernetes Operator&#xff0…

11.数组的分类和定义

1.数组的概念 数组是若干个相同类型 的变量在内存中有序存储的集合。 int a[10];//定义了一个整型的数组a&#xff0c;a是数组的名字&#xff0c;数组中有10个元素&#xff0c;每个元素的类型都是int类型&#xff0c;而且在内存中连续存储。 这十个元素分别是a[0] , a[1] , … …

[附源码]java毕业设计鲜花销售管理系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

同花顺_代码解析_技术指标_Z_2

本文通过对同花顺中现成代码进行解析&#xff0c;用以了解同花顺相关策略设计的思想 目录 ZNZ_CYC ZNZ_CYD ZNZ_CYDD ZNZ_CYDK ZNZ_CYE1 ZNZ_CYF1 ZNZ_CYMR ZNZ_CYOBV ZNZ_CYQKL ZNZ_CYQKR ZNZ_CYR ZNZ_CYS ZNZ_DKBL ZNZ_CYC 指南针成本均线 技术分析非常重视成…

【PinkCAx】可视化工具开发记录与总结

-----------PinkCAx----------- 仅以此篇&#xff0c;记录我的一次可视化软件开发尝试点滴。 简介 PinkCAx是一款采用Python语言编写的&#xff0c;基于QT5VTK架构的三维可视化工具。 该工具目前的功能如下&#xff1a; 基本操作 网格文件的打开与保存&#xff08;支持STL、P…

Packet Tracer - 确定 DR 和 BDR

地址分配表 设备 接口 IP 地址 子网掩码 RA G0/0 192.168.1.1 255.255.255.0 Lo0 192.168.31.11 255.255.255.255 RB G0/0 192.168.1.2 255.255.255.0 Lo0 192.168.31.22 255.255.255.255 RC G0/0 192.168.1.3 255.255.255.0 Lo0 192.168.31.33 255.25…

sqli-labs/Less-38

这一关有变成了get请求的题目了 我们先判断一下是否属于数字型注入 输入如下 id1 and 12 回显如下 属于字符型 然后判断一下是单引还是双引 输入1 报错了 从报错信息可知 这是一个单引号注入型 我们去佐证一下呗 输入1-- 回显如下 可以 确实是单引号注入型 然后我选择使用…

SeriLog日志框架的应用

C#中当前流行的日志框架有NLog、Log4Net、及SeriLog&#xff0c;在这里我们简单介绍SeriLog日志框架的应用 1、日志基础 &#xff08;1&#xff09;、日志等级 &#xff08;2&#xff09;、日志接收器 序号 接收器 说明 1 Console 输出到控制台 2 Debug 输出到VS的Debug窗口 3…

TCP沾包问题

TCP流式协议&#xff1a;所谓流式协议&#xff0c;即协议的内容是像流水一样的字节流&#xff0c;内容与内容之间没有明确的分界标志&#xff0c;需要我们人为地去给这些协议划分边界。 我们说 TCP 是流式协议究竟意味着什么&#xff1f; - 云社区 - 腾讯云 (tencent.com) 网…

DJ12-1 8086系列指令系统-1

指令&#xff1a;能够被计算机识别并执行的二进制代码。 指令系统&#xff1a;所有指令的集合。 指令按功能分类&#xff1a;数据传送类、算术运算类、逻辑运算和移位、串操作、控制转移类、处理器控制。 一、8086 指令格式 1. 指令的一般格式 在《计组》里面&#xff0c;我…

计算机网络——第六章笔记(2)

TCP 连接的建立 三次握手建立连接&#xff1a; 1、一方&#xff08;server&#xff09;被动地等待一个进来的连接请求 2、另一方&#xff08;the client&#xff09;通过发送连接请求&#xff0c;设置一些参数 3、服务器方回发确认应答 4、应答到达请求方&#xff0c;请求方最…