文章目录

  • 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文件中设置其样式,相关属性如图

<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外其他的属性

<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"/>

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被点击");}}
}

3.1.4 ImageView控件

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

<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>

注意点:

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>

设置监听事件

参考代码

//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);}}}
}

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;}}
}

示例图

3.2 列表控件的使用

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

3.2.1 ListView控件的使用

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

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

###3.2.2 常用数据适配器

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

BaseAdapter

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

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;}}
}

优化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源文件中也是不行的,当在布局文件中创建一个子对象控件的时候是检测不到的

(3)Android常见界面控件相关推荐

  1. Android 常见界面控件(ListView、RecyclerView、自定义View篇)

    Android 常见界面控件(ListView.RecyclerView.自定义View篇) 目录 3.3 ListView的使用 3.3.1 ListView控件的简单使用 3.3.2 常用数据适配 ...

  2. Android常见界面控件(基础入门)

    Android本意指"机器人",Google公司将Android的标识设计为一个绿色机器人, 表示Android系统符合环保概念,是一个轻薄短小,功能强大的移动系统,是第一个真正为 ...

  3. CH3-Android常见界面控件

    目标 掌握简单控件的使用,能够独立搭建一个注册界面 掌握ListView控件与RecyclerView控件的使用,能独立搭建列表界面 掌握自定义控件的定义方式,能够自定义一个简单的控件 ​ 几乎每一个 ...

  4. android播放视频控件,视频播放控件VideoView的基本使用

    在Android的界面控件中有一个视频播放控件,可以直接在手机上面开辟一个视频播放的UI,播放视频,下面ATAAW.COM大概介绍下视频控件VideoView的使用,由于视频播放是属于Android多 ...

  5. android选项菜单源代码,Android应用程序----UI界面控件(菜单menu)

    菜单是应用程序中非常重要的组成部分,能够在不占用界面空间的前提下,为应用程序提供了统一的功能和设置界面,并为程序开发人员提供了易于使用的编程接口 Android系统支持三种菜单 选项菜单(Option ...

  6. android组件圆角,Android实现圆角控件

    Android实现圆角控件 在Android开发过程中,控件的使用是最常见.最基本的.但是我们都知道,在Android中的控件都是矩形的,而在实际项目中,我们的UI设计师经常会使用一些圆角的控件.那么 ...

  7. android的属性如何使用方法,Android第二大控件,EditText的属性和使用方法

    原标题:Android第二大控件,EditText的属性和使用方法 EditText与TextView非常相似,它甚至与TextView 共用了绝大部分XML属性和方法.EditText与TextVi ...

  8. Android常见界面布局

    第2章 Android常见界面布局 第2章 Android常见界面布局 2.1 View视图 2.2 界面布局编写方式 2.2.1 在XML文件中编写布局 2.2.2 在Java代码中编写布局 2.3 ...

  9. Android活动,控件,碎片,广播,数据库小总结

    系统架构与开发环境搭建 3月2日Android Activities代码练习 3月5日 Intent的应用与传值 3月9日 1:显式Intent与隐式Intent的区别         显式Inten ...

  10. (转)基于MVC4+EasyUI的Web开发框架形成之旅--界面控件的使用

    http://www.cnblogs.com/wuhuacong/p/3317223.html 在前面介绍了两篇关于我的基于MVC4+EasyUI技术的Web开发框架的随笔,本篇继续介绍其中界面部分的 ...

最新文章

  1. python 列表、字典转json字符串
  2. 系统试运行报告是谁写的_最新标准:水污染源在线监测系统(CODCr、NH3N 等)安装技术规范(1)...
  3. 数据挖掘学习笔记之人工神经网络(二)
  4. 如何用深度学习做自然语言处理?这里有份最佳实践清单
  5. 7 php程序的调试方法_PHP程序错误调试方法 让php显示错误提示
  6. C++primer CH12智能指针
  7. WebAPI(part9)--下拉菜单及留言案例
  8. 第一:MySQL+MyBatis实现对测试用例数据的读取(接口自动化落地)
  9. Oracle Solaris 本地安全漏洞2
  10. 笨方法学python 习题41
  11. 在windows下编译gmplib并使用vs2010成功调用
  12. 沙箱-简单实现支付宝网页支付功能
  13. 51单片机入门——LED灯
  14. 再说《提督的决断4》
  15. Vue实例化对象挂载到元素上的方法
  16. Pycharm 使用多个光标进行编辑
  17. 浏览器实现pdf下载、ms http下载、IE不兼容
  18. 搭建游戏平台用哪里的高防服务器比较好
  19. mysql dump 10.13 下载_mysqldump.exe 文件下载
  20. UVa Problem 10254 The Priest Mathematician (牧师数学家)

热门文章

  1. 【搞一点AUTOSAR】基于TC397的MACL_ADC配置(Davinci工具链)
  2. Excel合并表格之vba
  3. 第三部分:成交动力学之十大成交激素——9、紧迫感
  4. 域计算机软件安装统计,如何通过SCCM查找客户端计算机已安装的软件清单
  5. 中国象棋---棋盘/棋子
  6. 阿里云ACP如何线上考试
  7. 阿里云国际站代充值个人注册与分销商邀约区别
  8. SpringMVC复习——B站
  9. 解决:当笔记本连接WIFi,电脑可以打开QQ等,但是不能打开网页,显示DNS错误
  10. 苹果计算机如何显示错误,科普电脑打开苹果手机视频教程及Apple ID验证失败发生未知错误怎么解决...