(3)Android常见界面控件

article/2025/10/13 7:55:41

文章目录

    • 3.1 简单控件的使用
      • 3.1.1 TextView控件
      • 3.1.2 EditText控件
      • 3.1.3 Button控件
        • 方法一:布局文件中指定点击事件(不常用)
        • 方法二:使用内部匿名类实现点击事件
        • 方法三:使用Activity实现OnClickListener接口
        • 全部实现代码举例
      • 3.1.4 ImageView控件
      • 3.1.5 RadioButton控件
        • 设置监听事件
      • 3.1.6 CheckBox控件
        • 代码举例
      • 3.1.7 Toast类
      • 3.1.8 实战演练—实现注册界面效果
        • 创建样式
        • 放置界面控件
        • 实现注册功能
        • 示例图
    • 3.2 列表控件的使用
      • 3.2.1 ListView控件的使用
        • BaseAdapter
        • SimpleAdapter
        • ArrayAdapter
      • 3.2.3 实战演练-购物商城
        • list_item.xml----用于定义ListView单个条目的布局
        • MainActivity.java
        • 优化ListView控件
      • 3.2.4 RecyclerView控件的使用
        • 优越性:
    • 3.3自定义控件
        • onMeasure()方法
        • onDraw()方法
        • onLayout()方法
        • 举例

3.1 简单控件的使用

Android界面上有很多的输入框,文字,图片,按钮等,这些都是Android提供的一些简单的控件来显示这些信息

3.1.1 TextView控件

用于显示文字信息,可在XML文件中设置其样式,相关属性如图

image-20220323184647478

image-20220323184717910

<TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="hello"android:textSize="20dp"android:id="@+id/tv_1"/>

3.1.2 EditText控件

表示编辑框,是TextView控件类的子类,下图是除TextView外其他的属性

image-20220323185357792

<TextViewandroid:id="@+id/tv_1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="姓名"android:textSize="50dp"android:layout_margin="20dp"/>
<EditTextandroid:layout_below="@id/tv_1"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入姓名:"android:layout_margin="20dp"/>

image-20220323185842545

3.1.3 Button控件

Button控件表示按钮,继承自TextView控件类,既可以显示文本,也可以显示图片,可以执行点击操作(理论上所有控件都可以设置点击事件)

通过以下属性来设置Button的点击事件,这句代码在XML中,需要在对应的Activity中设置一个方法名为click的点击事件方法,也就是与属性值同名

一下为三种方法实现点击事件

方法一:布局文件中指定点击事件(不常用)

android:onClick = "click"
   //Activity中的代码public void click(View view){Log.w("MainActivity","yes");}

方法二:使用内部匿名类实现点击事件

在Activity中使用内部匿名类实现点击操作

mbtn1.setOnClickListener(new View.OnClickListener() {//按钮1点击事件,使用方法二匿名内部类@Overridepublic void onClick(View view) {mbtn1.setText("按钮1被点击");}});

方法三:使用Activity实现OnClickListener接口

使用当前Activity实现View.OnClickListener接口,可以实现点击事件,实现代码在下面

全部实现代码举例

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="20dp"><Buttonandroid:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/btn1"android:text="按钮1"/><Buttonandroid:layout_below="@id/btn1"android:layout_width="match_parent"android:layout_height="wrap_content"android:id="@+id/btn2"android:onClick="click"android:text="按钮2"/><Buttonandroid:id="@+id/btn3"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@id/btn2"android:text="按钮3" /></RelativeLayout>

MainActivity

package cn.itcast.animalconnection;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;import java.nio.BufferUnderflowException;public class MainActivity extends AppCompatActivity implements View.OnClickListener{private Button mbtn1,mbtn2,mbtn3;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mbtn1 = findViewById(R.id.btn1);//找到xml中的Button控件与Button变量一一对应mbtn2 = findViewById(R.id.btn2);mbtn3 = findViewById(R.id.btn3);mbtn3.setOnClickListener(this);//设置按钮3的监听按钮事件mbtn1.setOnClickListener(new View.OnClickListener() {//按钮1点击事件,使用方法二匿名内部类@Overridepublic void onClick(View view) {mbtn1.setText("按钮1被点击");}});}public void click(View view)//按钮2点击事件,使用方法一,在xml中指定了onClick属性{mbtn2.setText("按钮2被点击");}@Overridepublic void onClick(View v)//按钮3点击事件,使用方法三,实现OnClickListener接口{switch (v.getId()){case R.id.btn3:mbtn3.setText("按钮3被点击");}}
}

image-20220323213834517

3.1.4 ImageView控件

ImageView控件表示图片,继承自View,可以加载各种图片资源,常用属性如下

image-20220323214202197

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="20dp"android:orientation="vertical"><ImageViewandroid:layout_width="100dp"android:layout_height="100dp"android:background="@drawable/s"/><ImageViewandroid:layout_width="100dp"android:layout_height="100dp"android:background="@drawable/w"/><ImageViewandroid:layout_width="100dp"android:layout_height="100dp"android:background="@drawable/q"/>
</LinearLayout>

image-20220323214902220

注意点:

android:background="@drawable/w"设置的背景,默认拉伸显示

android:src="@drawable/w"设置的是前景,默认原图显示

3.1.5 RadioButton控件

RadioButton表示单选按钮,是Button的一个子类,每一个单选按钮都有选中和未选中两种状态,都是通过android:checked属性指定的

在Android程序中,该控件经常与RadioGroup配合使用,实现单选按钮的功能,RadioGroup是单选组合框,RadioGroup继承自LinearLayout,可以使用android:orientation属性控制RadioButton的排列方向

    <RadioGroupandroid:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><RadioButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""/><RadioButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""/></RadioGroup>

image-20220323220434984

设置监听事件

参考代码

//MainActivity
public class MainActivity extends AppCompatActivity{private RadioGroup mrg1;private TextView mtv1;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mrg1 = findViewById(R.id.rg_1);mtv1 = findViewById(R.id.tv_1);//设置监听事件mrg1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {@Overridepublic void onCheckedChanged(RadioGroup radioGroup, int i) {//i就是状态为选中的那个单选按钮的idif(i == R.id.rb_1){mtv1.setText("你的性别是:男");}else{mtv1.setText("你的性别是:女");}}});}
}

3.1.6 CheckBox控件

CheckBox表示复选框,是Button的子类,选中的属性和单选按钮是一样的

与单选框类似,但不需要包含在RadioGroup中

代码举例

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="20dp"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="选择你的性别:"android:textSize="15sp"/><CheckBoxandroid:id="@+id/cb_1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="羽毛球"/><CheckBoxandroid:id="@+id/cb_2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="篮球"/><CheckBoxandroid:id="@+id/cb_3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="乒乓球"/><TextViewandroid:id="@+id/tv_1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="你的兴趣爱好是"android:textSize="20sp"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:id="@+id/tv_2"android:textSize="20sp"/>
</LinearLayout>

MainActivity

package cn.itcast.animalconnection;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.TextView;import java.nio.BufferUnderflowException;public class MainActivity extends AppCompatActivity implements CompoundButton.OnCheckedChangeListener{private TextView hobby;//输出TextView控件private String hobbys;//存放输出内容@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);CheckBox mcb1 = findViewById(R.id.cb_1);CheckBox mcb2 = findViewById(R.id.cb_2);CheckBox mcb3 = findViewById(R.id.cb_3);mcb1.setOnCheckedChangeListener((CompoundButton.OnCheckedChangeListener) this);//找到对应控件,需要转换一下类型mcb2.setOnCheckedChangeListener((CompoundButton.OnCheckedChangeListener) this);mcb3.setOnCheckedChangeListener((CompoundButton.OnCheckedChangeListener) this);hobby = findViewById(R.id.tv_2);hobbys = new String();}@Overridepublic void onCheckedChanged(CompoundButton buttonview,boolean ischecked)//监听事件,两个参数表示被点击的控件和控件的状态,实现对应接口{String motion = buttonview.getText().toString();//被点击控件的文字if(ischecked){if(!hobbys.contains(motion))//字符串中没有这个文字就加入,下面else没有就删除{hobbys = hobbys + motion;hobby.setText(hobbys);}}else{if (hobbys.contains(motion)){hobbys = hobbys.replace(motion,"");//替换字符串hobby.setText(hobbys);}}}
}

image-20220323224311620

3.1.7 Toast类

Toast类是android提供的轻量级信息提醒机制,用于向用户提示即时消息,显示在应用程序的最上层,显示一段时间后自动消失不会打断当前操作,也不会获得焦点

Toast.makeText(Context,Text,time).show();//需要调用show()方法才会显示
  • Context:表示应用程序环境信息,即当前组件的上下文环境,Context是一个抽象类,若在Activity中使用,可以将参数设置为``Activity.this`
  • Text:提示的字符串信息
  • Time:表示显示时间的长短,属性值包括两个固定的参数

3.1.8 实战演练—实现注册界面效果

目标:实现一个注册演示界面,通过日志返回注册信息

创建样式

下面是示例创建的样式,我实际没有使用这些样式,都是一个一个打上去的,这个样式不知道为什么覆盖了其他的默认属性值

themes.xml

<resources xmlns:tools="http://schemas.android.com/tools"><!-- Base application theme. --><style name="Theme.仿连连看" parent="Theme.MaterialComponents.DayNight.Bridge"><!-- Primary brand color. --><item name="titleTextColor">@android:color/white</item><item name="colorPrimary">@color/purple_500</item><item name="colorPrimaryVariant">@color/purple_700</item><item name="colorOnPrimary">@color/white</item><!-- Secondary brand color. --><item name="colorSecondary">@color/teal_200</item><item name="colorSecondaryVariant">@color/teal_700</item><item name="colorOnSecondary">@color/white</item><!-- Status bar color. --><item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item><!-- Customize your theme here. --></style>
<!--    竖分割线样式--><style name="hline"><item name="android:layout_width">match_parent</item><item name="android:layout_height">1dp</item><item name="android:background">@android:color/white</item></style>
<!--    横分割线样式--><style name="vline"><item name="android:layout_width">1dp</item><item name="android:layout_height">match_parent</item><item name="android:background">@android:color/white</item></style>
<!--    文本样式1--><style name="tvOne"><item name="android:layout_width">0dp</item><item name="android:layout_height">match_parent</item><item name="android:layout_weight">1</item><item name="android:drawablePadding">8dp</item><item name="android:gravity">center_horizontal</item><item name="android:paddingTop">40dp</item><item name="android:textColor">@android:color/white</item><item name="android:textSize">15sp</item></style>
<!--    文本样式2--><style name="tvTwo"><item name="android:layout_width">wrap_content</item><item name="android:layout_height">wrap_content</item><item name="android:layout_marginLeft">20dp</item><item name="android:textColor">@android:color/white</item><item name="android:textSize">15sp</item></style>
<!--    输入框样式--><style name="teOne"><item name="android:layout_width">match_parent</item><item name="android:layout_height">wrap_content</item><item name="android:layout_marginTop">30dp</item><item name="android:background">@null</item><item name="android:textColor">@android:color/black</item></style>
</resources>

放置界面控件

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_margin="20dp"android:orientation="vertical"><TextViewandroid:layout_marginTop="20dp"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="注册"android:textSize="35sp"android:layout_gravity="center_horizontal"/><LinearLayoutandroid:layout_marginTop="30dp"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><EditTextandroid:id="@+id/name"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:hint="输入账号名:"/><EditTextandroid:id="@+id/email"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:hint="输入邮箱:"/><EditTextandroid:id="@+id/pwd"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"android:hint="输入密码"android:password="true"/></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_marginTop="20dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="性别:"android:textSize="20sp"android:layout_marginRight="20dp"android:layout_marginLeft="10dp"/><RadioGroupandroid:id="@+id/sex"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"><RadioButtonandroid:id="@+id/man"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""android:layout_marginRight="20dp"/><RadioButtonandroid:id="@+id/woman"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text=""/></RadioGroup></LinearLayout><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="20dp"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="请选择兴趣爱好:"android:textSize="20sp"/><CheckBoxandroid:id="@+id/sing"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="唱歌"/><CheckBoxandroid:id="@+id/dance"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="跳舞"/><CheckBoxandroid:id="@+id/read"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="读书"/></LinearLayout><CheckBoxandroid:id="@+id/fage"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="我已确认信息无误"android:textColor="#00BCD4"android:layout_marginTop="20dp"/><Buttonandroid:id="@+id/login"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="注册"android:layout_margin="30dp"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_horizontal"android:text="--其他登陆方式--"/><LinearLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="horizontal"android:layout_marginTop="20dp"android:layout_marginLeft="40dp"android:layout_marginRight="40dp"><LinearLayoutandroid:layout_width="wrap_content"android:layout_weight="1"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@drawable/w"android:layout_gravity="center_horizontal"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="QQ"android:layout_gravity="center_horizontal"/></LinearLayout><LinearLayoutandroid:layout_weight="1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@drawable/s"android:layout_gravity="center_horizontal"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="微信"android:layout_gravity="center_horizontal"/></LinearLayout><LinearLayoutandroid:layout_weight="1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"><ImageViewandroid:layout_width="30dp"android:layout_height="30dp"android:src="@drawable/q"android:layout_gravity="center_horizontal"/><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="游客"android:layout_gravity="center_horizontal"/></LinearLayout></LinearLayout></LinearLayout>
</LinearLayout>

实现注册功能

package cn.itcast.animalconnection;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Color;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.nio.BufferUnderflowException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener,CompoundButton.OnCheckedChangeListener{private EditText ed_name,ed_pwd,ed_email;private Button btn_submit;private String name,email,pwd,sex,hobbys;private RadioGroup rg_sex;private CheckBox cb_sing,cb_dance,cb_read,flge;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);init();}private void init(){ed_name = findViewById(R.id.name);ed_email = findViewById(R.id.email);ed_pwd = findViewById(R.id.pwd);btn_submit = findViewById(R.id.login);rg_sex = findViewById(R.id.sex);cb_sing = findViewById(R.id.sing);cb_dance = findViewById(R.id.dance);cb_read = findViewById(R.id.read);flge = findViewById(R.id.fage);btn_submit.setOnClickListener(this);//提交cb_sing.setOnCheckedChangeListener(this);//复选框cb_dance.setOnCheckedChangeListener(this);cb_read.setOnCheckedChangeListener(this);hobbys = new String();rg_sex.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {//单选控件设置监听事件@Overridepublic void onCheckedChanged(RadioGroup radioGroup, int i) {switch (i){case R.id.man:sex = "男";break;case R.id.woman:sex = "女";break;}}});}private void getDate()//获取界面信息{name = ed_name.getText().toString();email = ed_email.getText().toString();pwd = ed_pwd.getText().toString();}@Overridepublic void onClick(View view) //提交按钮{switch (view.getId()) {case R.id.login:getDate();if (TextUtils.isEmpty(name))Toast.makeText(MainActivity.this, "请输入名字", Toast.LENGTH_LONG).show();else if (TextUtils.isEmpty(email))Toast.makeText(MainActivity.this, "请输入邮箱", Toast.LENGTH_LONG).show();else if (TextUtils.isEmpty(pwd))Toast.makeText(MainActivity.this, "请输入密码", Toast.LENGTH_LONG).show();else if (TextUtils.isEmpty(sex))Toast.makeText(MainActivity.this, "请选择性别", Toast.LENGTH_LONG).show();else if (TextUtils.isEmpty(hobbys))Toast.makeText(MainActivity.this, "请选择兴趣爱好", Toast.LENGTH_LONG).show();else if (!flge.isChecked())//确认复选框{Toast.makeText(MainActivity.this, "请选择确认无误", Toast.LENGTH_LONG).show();flge.setTextColor(Color.parseColor("#FF3030"));}else{Toast.makeText(MainActivity.this, "注册成功", Toast.LENGTH_LONG).show();Log.i("MainActiity","注册的用户信息:"+" 名字:"+name+"邮箱:"+email+"密码:"+pwd+"性别:"+sex+"兴趣爱好:"+hobbys);}break;}}@Overridepublic void onCheckedChanged(CompoundButton compoundButton, boolean b)//复选框设置监听事件{String motion = compoundButton.getText().toString();if(b){if(!hobbys.contains(motion))hobbys = hobbys + motion;}else{if(!hobbys.contains(motion))hobbys = hobbys + motion;}}
}

示例图

image-20220324175732867

3.2 列表控件的使用

日常生活中,淘宝,微信等应用程序,通常会在页面中展示很多的条目,并且每一个条目的风格一致,这种数据方式就是通过ListView或RecyclerView控件实现的

3.2.1 ListView控件的使用

ListView是一个比较常用的控件,以列表的形式展示数据内容,能够根据列表的高度自适应屏幕显示,ListView的属性如下图

image-20220324190912574

<ListViewandroid:layout_width="match_parent"android:layout_height="match_parent"android:listSelector="#fefefe" >
</ListView>

###3.2.2 常用数据适配器

为ListView添加数据的时候会用到数据适配器,数据适配器是数据与视图之间沟通的桥梁,类似一个转换器,将复杂的数据转换成用户可以接受的方式进行呈现,下面是几个常用的数据适配器

BaseAdapter

BaseAdapter是一个基本适配器,实际上是一个抽象类,通常在自定义数据适配器的时候会继承自这个类,该类的抽象方法如下

image-20220324191928227

SimpleAdapter

SimpleAdapter继承自BaseAdapter,实现了四个抽象方法,并进行封装,使用SimpleAdapter进行数据适配的时候只需要在构造函数传入对应的参数即可

public SimpleAdapter(Context context,List<? extends Map<String,?>>data,int resource,String[] from,int[] to);
  • context :上下文对象
  • data :数据集合,data中的每一项对应ListView条目中的数据
  • resource :Item布局的资源id
  • from :Map集合中的key值
  • to :Item布局中对应的控件

ArrayAdapter

ArrayAdapter是BaseAdapter的子类,ArrayAdapter控件通常用于适配TextView控件,例如Android中的设置菜单

构造方法如下

public ArrayAdapter(Context context,int resource);
public ArrayAdapter(Context context,int resource,int textViewResourceId);
public ArrayAdapter(Context context,int resource,T[] objects);
public ArrayAdapter(Context context,int resource,List<T>objects);
public ArrayAdapter(Context context,int resource,int textViewResourceId,List<T> objects);
  • context:上下文对象
  • resource:Item布局的资源id
  • textViewResourceId:Item布局中相应TextView控件的id
  • T[] objects:需要适配数组类型的数据
  • Listobjects:需要适配List类型的数据

设置数据适配器到ListView控件举例

ListView mListView = (ListView)findViewById(R.id.lv);
BaseAdapter madapter = new BaseAdapter();
mListView.setAdapter(madapter);

3.2.3 实战演练-购物商城

####activity_main.xml----创建ListView控件

<?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"android:padding="20dp"android:orientation="vertical"><TextViewandroid:layout_width="match_parent"android:layout_height="wrap_content"android:text="购物商城"android:gravity="center_horizontal"android:background="#DA8282"/><ListViewandroid:id="@+id/lv_1"android:layout_width="match_parent"android:layout_height="wrap_content"></ListView>
</LinearLayout>

list_item.xml----用于定义ListView单个条目的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:padding="16dp"><ImageViewandroid:id="@+id/iv"android:layout_width="120dp"android:layout_height="90dp"android:layout_centerVertical="true" /><RelativeLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginLeft="10dp"android:layout_toRightOf="@+id/iv"android:layout_centerVertical="true"><TextViewandroid:id="@+id/title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="桌子"android:textSize="20sp"android:textColor="#000000" /><TextViewandroid:id="@+id/tv_price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="价格:"android:textSize="20sp"android:layout_marginTop="10dp"android:layout_below="@+id/title"android:textColor="#FF8F03" /><TextViewandroid:id="@+id/price"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="1000"android:textSize="20sp"android:layout_below="@+id/title"android:layout_toRightOf="@+id/tv_price"android:textColor="#FF8F03"android:layout_marginTop="10dp"/></RelativeLayout>
</RelativeLayout>

MainActivity.java

package cn.itcast.test2;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {private ListView mlistview;private String[] titles = {"桌子","苹果","蛋糕","线衣","猕猴桃","围巾"};private String[] prices = {"1800元","10元","300元","350元","500元","10元","280元"};private int[] icons ={R.drawable.a,R.drawable.b,R.drawable.c,R.drawable.a,R.drawable.b,R.drawable.c};//图片集合@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);mlistview = findViewById(R.id.lv_1);MyBaseAdapter madapter = new MyBaseAdapter();mlistview.setAdapter(madapter);}class MyBaseAdapter extends BaseAdapter//实现抽象类,不然不能使用{@Overridepublic int getCount() {//获取条目的总数return titles.length;}@Overridepublic Object getItem(int i) {//返回条目的数据对象return titles[i];}@Overridepublic long getItemId(int i) {//返回条目的idreturn i;}@Overridepublic View getView(int i, View view, ViewGroup viewGroup) {//获取条目的视图View v = View.inflate(MainActivity.this,R.layout.list_item,null);//创建视图对象TextView title = v.findViewById(R.id.title);//引入控件对象TextView price = v.findViewById(R.id.price);ImageView iv = v.findViewById(R.id.iv);title.setText(titles[i]);price.setText(prices[i]);iv.setBackgroundResource(icons[i]);return v;}}
}
image-20220326212033368

优化ListView控件

当运行上述程序的时候,当ListView控件上加载的item过多,并且快速滑动屏幕的时候就会产生卡顿,出现的原因如下

  • 滑出屏幕区域的item会被销毁,滑入的会创建,当滑动屏幕的时候就会不断销毁创建
  • 不断执行findViewById()方法初始化控件,每创建一个对象都需要执行这个方法

优化:

在item出屏幕的时候,item会先以缓存的形式暂时保存,getView()方法中的第二个参数就是旧的对象,就可以修改getView()方法利用原来的旧对象来刷新新的信息,就可以有效减少频繁的创建销毁对象,具体修改的代码如下

MyBaseAdapter类下的getView()方法

public View getView(int i, View view, ViewGroup viewGroup) {//获取条目的视图,第二个参数代表滑出的itemViewHolder holder = null;if(view == null){view = View.inflate(MainActivity.this,R.layout.list_item,null);//获取item样式holder = new ViewHolder();holder.title = view.findViewById(R.id.title);holder.price = view.findViewById(R.id.price);holder.iv = view.findViewById(R.id.iv);view.setTag(holder);}else//如果有旧对象{holder = (ViewHolder) view.getTag();//获得缓存中的ViewHolder类的对象}holder.title.setText(titles[i]);holder.price.setText(prices[i]);holder.iv.setBackgroundResource(icons[i]);return view;}

3.2.4 RecyclerView控件的使用

此控件用于在有限的空间内显示大量数据,与ListView类似,该控件以列表的形式展示数据,数据通过数据适配器加载,但是这个控件比ListView更加强大

优越性:

  • RecyclerView控件可以通过LayoutManner类实现横向和竖向的列表效果,瀑布流效果和GridView效果,而ListView只能实现竖直的列表效果
  • RecyclerView控件使用RecyclerView.Adapter,该数据适配器将BaseAdapter中的getView()方法拆分成onCreateViewHoulder()方法和OnBindViewHoulder()方法,强制使用ViewHoulder类,使得代码编写更加规范化
  • RecyclerView控件复用Item对象的工作由自己实现
  • RecyclerView控件可以通过setItemAnimator()方法设置动画效果

3.3自定义控件

通常在Android开发过程中,都不直接使用View控件,而是使用它的子类,最简单的自定义控件就是创建一个继承View类或其他子类的类,并重写该类的构造方法,示例代码如下

class Customview extends View{public Customview(Context context){super(context);}public Customview(Context context, AttributeSet attrs){super(context, attrs);}
}

如果想要创建一个该类的对象,则需要使用到第一个构造函数,如果需要在布局文件中引用该自定义类,则需要使用到该类的第二个构造方法

我们可以在自定义控件中通过重写指定方法来添加额外的样式和功能,自定义控件常用的三个方法具体介绍如下

onMeasure()方法

该方法用于测量尺寸,在该方法中可以设置控件本身或者是其子控件的宽高

onMeasure(int widthMeasureSpec,int heightMeasureSpec);

第一个参数表示获取父容器指定该控件的宽度,第二个则是高度

这两个参数不仅包含属性值,还包括父容器的测量模式,测量模式分为三种

  • EXACTLY:当自定义控件的宽高值设置为具体值的时候使用,如100dp,match_parent
  • AT_MOST:当自定义控件的宽高值为wrap_content时使用
  • UNSPECIFIED:当父容器没有指定自定义控件的宽高值时使用

注意点:虽然这两个参数是父容器为该控件指定的宽高,但是该控件还需要通过设置setMeasureDimension(int,int)来设置宽高

onDraw()方法

该方法用于绘制图像

onDraw(Canvas canvas);

canans表示画布,经常与Paint类配合使用,通过Paint类可以在Canans中绘制图像

onLayout()方法

onLayout()方法,用于指定布局中子控件的位置,该方法通常在ViewGroup容器中重写

onLayout(boolean changed,int left,int top,int right,int bottom);

第一个参数表示自定义控件的大小和位置是否发生改变,剩下的四个控件代表与父容器的左边,顶部,右边,底部的距离

举例

使用自定义控件在界面中画一个图形

CircleView.java

package cn.itcast.myapplication;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;public class CircleView extends View {public CircleView(Context context) {super(context);}public CircleView(Context context, AttributeSet attrs) {super(context, attrs);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);int r = getMeasuredWidth() / 2;//获取半径int centerX = getLeft() + r;int centerY = getTop() + r;Paint paint = new Paint();paint.setColor(Color.RED);//设置颜色为红色canvas.drawCircle(centerX, centerY, r, paint);//调用画笔绘制}
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"><cn.itcast.myapplication.CircleViewandroid:layout_width="100dp"android:layout_height="100dp" /></RelativeLayout>

注意点:一个java源文件只能设置一个public类,这里的CircleView自定义控件类必须单独放在一个源文件中,如果不加public属性放在主函数类对应的java源文件中也是不行的,当在布局文件中创建一个子对象控件的时候是检测不到的


http://chatgpt.dhexx.cn/article/A6elp7fl.shtml

相关文章

dreamweaver2020中文版

教程&#xff1a; 1、解压下载获得Dreamweaver 2020中文特别版&#xff0c;双击运行它。 2、由于其默认安装路劲为C盘系统盘&#xff0c;因此这里小编选择自定义。 3、选择想要安装的组件。 4、等待安装完成。 5、当向导安装结束后&#xff0c;点击完成。 6、最后双击桌面快捷…

Dreamweaver(Dw)2021软件下载及安装教程并创建一个网页

1.在微信搜索公众号软件星君&#xff08;如图&#xff09; 2. 2.点开链接找到里面的下载链接复制&#xff08;要求windows10&#xff09; 2、系统必须是Windows 10 64bit 3、保证电脑中有任意一款解压软件 安装步骤 1.找到下载好的安装包&#xff0c;并双击打开【Dw 2021 安装…

Dreamweaver 安装破解

Dreamweaver CS6 Mac破解版 发表于 2013 年 2 月 28 日 介于之前小子分享的Mac版的Adobe的PS CS6和Illustrator CS6&#xff0c;有用户要求小子分享下Dreamweaver&#xff0c;小子当然乐意效劳。 Dreamweaver CS6 是世界顶级软件厂商Adobe推出的一套拥有可视化编辑界面&#x…

Dreamweaver2021下载安装

下载路径见如下百度云盘 链接&#xff1a;https://pan.baidu.com/s/1mB6S0xw3KWxPnbOxfQNu7Q 提取码&#xff1a;k1pg 安装 我是从一个公众号学到的&#xff0c;里边有挺多常见工具软件以及详细安装方法。

coreldraw2021全名和序列号 cdr2021安装下载图文教程

CorelDRAW2021一套完整的专业图形设计应用程序开始正确的设计之旅&#xff0c;包括矢量插图、布局、照片编辑等 - 专为您选择的平台而设计。使用 CorelDRAW随时随地在 Windows 或 Mac 上制作独特的插图、广告牌、徽标等。通过 CorelDRAW与客户和同事进行协作&#xff0c;收集一…

Dreamweaver 安装 激活

来源地址&#xff1a;http://jingyan.baidu.com/article/e75aca8575e076142fdac65d.html 怎么安装和激活Dreamweaver cs6详细教程 1 安装Dreamweaver cs6之前&#xff0c;大家要从官网下载Dreamweaver cs6软件&#xff0c;这里我就不介绍怎么下载了。下载后解压压缩包&#xff…

dw怎样用css设置背景图片,dreamweaver

dreamweaverCSS使用教程&#xff1a;定义CSS样式背景属性 背 景 属 性 【定义 CSS 样式背景属性】使用“CSS 样式定义”对话框的“背景”类别可以定义 CSS 样式的背景设置。可以对网页中的任何元素应用背景属性。例如&#xff0c;创建一个样式&#xff0c;将背景颜色或…

CorelDRAW2021标准版 序列号授权码

作为一个设计师没有CorelDRAW用的日子真的是难过&#xff0c;最好用的就是CorelDRAW 2021的增强中文版&#xff0c;拥有极强的插件&#xff0c;为作图方便了不少&#xff01;CorelDRAW作为世界一流的平面矢量绘图软件&#xff0c;被专业设计人员广泛使用&#xff0c;软件使用直…

Adobe Dreamweaver的使用教程

1.打开Adobe Dreamweaver软件 2.打开后的界面 3.新建一个站点&#xff0c;保存网页文件&#xff0c;图片&#xff0c;视频等 4.输入站点的名字和保存的路径 5.新建html文件 6.选择设计模式 7.制作你所需要的结果 8.保存网页&#xff0c;才能在浏览器中预览 9.保存网页&#xff…

Dreamweaver2019版安装教程

吐槽一下 学校机房软件跟新换代也太慢了 软件甚至还是使用CS4古董级 Edition 连H5都不能创建 软件Edition日新月异 百家争鸣的时代 不过自己也高不到哪去&#xff01;使用的Adobe Dreamweaver CS6 前面也发表了低Edition的安装教程 如需考虑低版本请点击传送门 抛弃的原因&a…

Adobe Dreamweaver(DW)安装教程(附安装包下载地址)

一、安装包获取 1.百度网盘获取 链接&#xff1a;https://pan.baidu.com/s/1PqFChWBwSaZ6hLmD8uNY1Q?_at_1645531154665 提取码&#xff1a;0007 提示&#xff1a;如果链接失效请在评论区留言 2.同时给大家分享一个作者自己获取资源的方式&#xff1a;关注公众号 ” 稻田…

Adobe Dreamweaver 2021下载安装教程

软件介绍 Adobe Dreamweaver 2021是专业的网站设计软件&#xff0c;使用可为处理各种Web文档提供灵活的环境。Dreamweaver 2021一款非常受欢迎的网页设计软件&#xff0c;是该系列的全新版本&#xff0c;可以帮助广大学生、程序员制作出精美的网页&#xff0c;在全新的Dreamwe…

Dreamweaver CS6破解教程[序列号+破解补丁]

Adobe Dreamweaver CS6中文简体版下载地址&#xff1a;Dreamweaver CS6中文简体版下载[带破解] 该教程将不断更新&#xff0c;最新版请猛击&#xff1a;http://www.itxueyuan.org/view/6317.html 破解之前的准备 1) 序列号 这里为大家生成了两个&#xff0c;可以通过软件验证&a…

coreldraw2021永久序列号和激活注册教程

CorelDRAW2021最新中文版又叫做CDR图形设计软件&#xff0c;这个软件的功能相信使用过的朋友都非常的了解&#xff0c;因为它是超级给力的平面设计软件&#xff0c;为您提供丰富的功能和工具&#xff0c;让大家能够进行专业的矢量图绘制&#xff0c;并进行相关的布局、图像处理…

SQL|数据插入|触发器

一次插入多条信息 SQL34 链接地址&#xff1a;https://www.nowcoder.com/practice/51c12cea6a97468da149c04b7ecf362e?tpId82&&tqId29802&rp1&ru/ta/sql&qru/ta/sql/question-ranking 题目描述&#xff1a; 题目已经先执行了如下语句: drop table if ex…

SQLServer触发器的创建和使用

触发器也是和之前写的数据库函数和存储过程类似&#xff0c; 可以看做是一种特殊的数据库函数&#xff0c;只不过由系统调用&#xff0c;我们也需要表明调用的实际和规则 触发器的主体&#xff08;也可以说是触发器的使用范围&#xff09; 表table视图view库database服务器se…

SQL server 创建触发器详解

触发器定义&#xff1a;一种特殊类型的存储过程&#xff0c;不同于存储过程。存储过程 调用名称执行&#xff0c;触发器的调用 通过事件触发 自动调用执行 。 触发器分类&#xff1a;1、DML触发器 数据库再创建触发器时会在内存中创建了两个专用表﹕Inserted表和Deleted表。这…

sqlserver触发器

为了更好的强制业务规则和保证数据的完整性&#xff0c;sql server为我们提供了两种机制&#xff0c;它们分别是约束(主键约束、外键约束、Not Null约束、唯一约束以及检查约束)和触发器。在触发器中&#xff0c;我们可以查询其他表&#xff0c;也可以包含复杂的Transact-SQL语…

SQLServer 触发器

今天修复K3系统生产出库单&#xff0c;审核、返审核 领料数量一直不变&#xff0c;没有相应改变&#xff0c;K3是16年买的&#xff0c;没有源码开发文档和表结构&#xff0c;只能在sqlserver中添加sql语句监视,看审核后改变那个表的状态和数据源sql语句&#xff0c;用触发器改变…

Mac 解压rar 文件

Mac 解压rar 文件 第一种方法&#xff1a; 下载下面链接中的软件&#xff0c;安装好就可以直接用了。 http://baijiahao.baidu.com/s?id1604390455412644388&wfrspider&forpc 安装过程中&#xff0c;一直点击下一步即可 第二种方法&#xff1a; https://blog.csd…