Android界面上有很多的输入框,文字,图片,按钮等,这些都是Android提供的一些简单的控件来显示这些信息
用于显示文字信息,可在XML文件中设置其样式,相关属性如图
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="hello"
android:textSize="20dp"
android:id="@+id/tv_1"/>
表示编辑框,是TextView控件类的子类,下图是除TextView外其他的属性
<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="姓名"
android:textSize="50dp"
android:layout_margin="20dp"/>
<EditText
android:layout_below="@id/tv_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入姓名:"
android:layout_margin="20dp"/>
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点击事件,使用方法二匿名内部类
@Override
public void onClick(View view) {
mbtn1.setText("按钮1被点击");
}
});
使用当前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">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn1"
android:text="按钮1"/>
<Button
android:layout_below="@id/btn1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btn2"
android:onClick="click"
android:text="按钮2"/>
<Button
android: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;
@Override
protected 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点击事件,使用方法二匿名内部类
@Override
public void onClick(View view) {
mbtn1.setText("按钮1被点击");
}
});
}
public void click(View view)//按钮2点击事件,使用方法一,在xml中指定了onClick属性
{
mbtn2.setText("按钮2被点击");
}
@Override
public void onClick(View v)//按钮3点击事件,使用方法三,实现OnClickListener接口
{
switch (v.getId())
{
case R.id.btn3:
mbtn3.setText("按钮3被点击");
}
}
}
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">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/s"/>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/w"/>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:background="@drawable/q"/>
LinearLayout>
注意点:
android:background="@drawable/w"
设置的背景,默认拉伸显示
android:src="@drawable/w"
设置的是前景,默认原图显示
RadioButton表示单选按钮,是Button的一个子类,每一个单选按钮都有选中和未选中两种状态,都是通过android:checked
属性指定的
在Android程序中,该控件经常与RadioGroup配合使用,实现单选按钮的功能,RadioGroup是单选组合框,RadioGroup继承自LinearLayout,可以使用android:orientation
属性控制RadioButton的排列方向
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"/>
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"/>
RadioGroup>
参考代码
//MainActivity
public class MainActivity extends AppCompatActivity{
private RadioGroup mrg1;
private TextView mtv1;
@Override
protected 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() {
@Override
public void onCheckedChanged(RadioGroup radioGroup, int i) {//i就是状态为选中的那个单选按钮的id
if(i == R.id.rb_1)
{
mtv1.setText("你的性别是:男");
}
else
{
mtv1.setText("你的性别是:女");
}
}
});
}
}
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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="选择你的性别:"
android:textSize="15sp"/>
<CheckBox
android:id="@+id/cb_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="羽毛球"/>
<CheckBox
android:id="@+id/cb_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="篮球"/>
<CheckBox
android:id="@+id/cb_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="乒乓球"/>
<TextView
android:id="@+id/tv_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="你的兴趣爱好是"
android:textSize="20sp"/>
<TextView
android: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;//存放输出内容
@Override
protected 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();
}
@Override
public 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);
}
}
}
}
Toast类是android提供的轻量级信息提醒机制,用于向用户提示即时消息,显示在应用程序的最上层,显示一段时间后自动消失不会打断当前操作,也不会获得焦点
Toast.makeText(Context,Text,time).show();//需要调用show()方法才会显示
目标:实现一个注册演示界面,通过日志返回注册信息
下面是示例创建的样式,我实际没有使用这些样式,都是一个一个打上去的,这个样式不知道为什么覆盖了其他的默认属性值
themes.xml
<resources xmlns:tools="http://schemas.android.com/tools">
<style name="Theme.仿连连看" parent="Theme.MaterialComponents.DayNight.Bridge">
- "titleTextColor"
>@android:color/white
- "colorPrimary"
>@color/purple_500
- "colorPrimaryVariant">@color/purple_700
- "colorOnPrimary">@color/white
- "colorSecondary">@color/teal_200
- "colorSecondaryVariant">@color/teal_700
- "colorOnSecondary">@color/white
- "android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant
style>
<style name="hline">
- "android:layout_width"
>match_parent
- "android:layout_height"
>1dp
- "android:background">@android:color/white
style>
<style name="vline">
- "android:layout_width"
>1dp
- "android:layout_height"
>match_parent
- "android:background">@android:color/white
style>
<style name="tvOne">
- "android:layout_width"
>0dp
- "android:layout_height"
>match_parent
- "android:layout_weight">1
- "android:drawablePadding">8dp
- "android:gravity">center_horizontal
- "android:paddingTop">40dp
- "android:textColor">@android:color/white
- "android:textSize">15sp
style>
<style name="tvTwo">
- "android:layout_width"
>wrap_content
- "android:layout_height"
>wrap_content
- "android:layout_marginLeft">20dp
- "android:textColor">@android:color/white
- "android:textSize">15sp
style>
<style name="teOne">
- "android:layout_width"
>match_parent
- "android:layout_height"
>wrap_content
- "android:layout_marginTop">30dp
- "android:background">@null
- "android:textColor">@android:color/black
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">
<TextView
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="注册"
android:textSize="35sp"
android:layout_gravity="center_horizontal"/>
<LinearLayout
android:layout_marginTop="30dp"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<EditText
android:id="@+id/name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="输入账号名:"/>
<EditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="输入邮箱:"/>
<EditText
android:id="@+id/pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="输入密码"
android:password="true"/>
LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="性别:"
android:textSize="20sp"
android:layout_marginRight="20dp"
android:layout_marginLeft="10dp"/>
<RadioGroup
android:id="@+id/sex"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<RadioButton
android:id="@+id/man"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="男"
android:layout_marginRight="20dp"/>
<RadioButton
android:id="@+id/woman"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="女"/>
RadioGroup>
LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请选择兴趣爱好:"
android:textSize="20sp"/>
<CheckBox
android:id="@+id/sing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="唱歌"/>
<CheckBox
android:id="@+id/dance"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="跳舞"/>
<CheckBox
android:id="@+id/read"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="读书"/>
LinearLayout>
<CheckBox
android:id="@+id/fage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我已确认信息无误"
android:textColor="#00BCD4"
android:layout_marginTop="20dp"/>
<Button
android:id="@+id/login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="注册"
android:layout_margin="30dp"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="--其他登陆方式--"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp"
android:layout_marginLeft="40dp"
android:layout_marginRight="40dp">
<LinearLayout
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/w"
android:layout_gravity="center_horizontal"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="QQ"
android:layout_gravity="center_horizontal"/>
LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/s"
android:layout_gravity="center_horizontal"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="微信"
android:layout_gravity="center_horizontal"/>
LinearLayout>
<LinearLayout
android:layout_weight="1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<ImageView
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/q"
android:layout_gravity="center_horizontal"/>
<TextView
android: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;
@Override
protected 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() {//单选控件设置监听事件
@Override
public 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();
}
@Override
public 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;
}
}
@Override
public 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;
}
}
}
日常生活中,淘宝,微信等应用程序,通常会在页面中展示很多的条目,并且每一个条目的风格一致,这种数据方式就是通过ListView或RecyclerView控件实现的
ListView是一个比较常用的控件,以列表的形式展示数据内容,能够根据列表的高度自适应屏幕显示,ListView的属性如下图
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:listSelector="#fefefe" >
ListView>
###3.2.2 常用数据适配器
为ListView添加数据的时候会用到数据适配器,数据适配器是数据与视图之间沟通的桥梁,类似一个转换器,将复杂的数据转换成用户可以接受的方式进行呈现,下面是几个常用的数据适配器
BaseAdapter是一个基本适配器,实际上是一个抽象类,通常在自定义数据适配器的时候会继承自这个类,该类的抽象方法如下
SimpleAdapter继承自BaseAdapter,实现了四个抽象方法,并进行封装,使用SimpleAdapter进行数据适配的时候只需要在构造函数传入对应的参数即可
public SimpleAdapter(Context context,List<? extends Map<String,?>>data,int resource,String[] from,int[] to);
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);
设置数据适配器到ListView控件举例
ListView mListView = (ListView)findViewById(R.id.lv);
BaseAdapter madapter = new BaseAdapter();
mListView.setAdapter(madapter);
####activity_main.xml----创建ListView控件
<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">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="购物商城"
android:gravity="center_horizontal"
android:background="#DA8282"/>
<ListView
android:id="@+id/lv_1"
android:layout_width="match_parent"
android:layout_height="wrap_content">
ListView>
LinearLayout>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<ImageView
android:id="@+id/iv"
android:layout_width="120dp"
android:layout_height="90dp"
android:layout_centerVertical="true" />
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_toRightOf="@+id/iv"
android:layout_centerVertical="true">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="桌子"
android:textSize="20sp"
android:textColor="#000000" />
<TextView
android: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" />
<TextView
android: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>
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};//图片集合
@Override
protected 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//实现抽象类,不然不能使用
{
@Override
public int getCount() {//获取条目的总数
return titles.length;
}
@Override
public Object getItem(int i) {//返回条目的数据对象
return titles[i];
}
@Override
public long getItemId(int i) {//返回条目的id
return i;
}
@Override
public 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控件上加载的item过多,并且快速滑动屏幕的时候就会产生卡顿,出现的原因如下
优化:
在item出屏幕的时候,item会先以缓存的形式暂时保存,getView()方法中的第二个参数就是旧的对象,就可以修改getView()方法利用原来的旧对象来刷新新的信息,就可以有效减少频繁的创建销毁对象,具体修改的代码如下
MyBaseAdapter类下的getView()方法
public View getView(int i, View view, ViewGroup viewGroup) {//获取条目的视图,第二个参数代表滑出的item
ViewHolder 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;
}
此控件用于在有限的空间内显示大量数据,与ListView类似,该控件以列表的形式展示数据,数据通过数据适配器加载,但是这个控件比ListView更加强大
通常在Android开发过程中,都不直接使用View控件,而是使用它的子类,最简单的自定义控件就是创建一个继承View类或其他子类的类,并重写该类的构造方法,示例代码如下
class Customview extends View{
public Customview(Context context)
{
super(context);
}
public Customview(Context context, AttributeSet attrs)
{
super(context, attrs);
}
}
如果想要创建一个该类的对象,则需要使用到第一个构造函数,如果需要在布局文件中引用该自定义类,则需要使用到该类的第二个构造方法
我们可以在自定义控件中通过重写指定方法来添加额外的样式和功能,自定义控件常用的三个方法具体介绍如下
该方法用于测量尺寸,在该方法中可以设置控件本身或者是其子控件的宽高
onMeasure(int widthMeasureSpec,int heightMeasureSpec);
第一个参数表示获取父容器指定该控件的宽度,第二个则是高度
这两个参数不仅包含属性值,还包括父容器的测量模式,测量模式分为三种
注意点:虽然这两个参数是父容器为该控件指定的宽高,但是该控件还需要通过设置setMeasureDimension(int,int)来设置宽高
该方法用于绘制图像
onDraw(Canvas canvas);
canans表示画布,经常与Paint类配合使用,通过Paint类可以在Canans中绘制图像
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);
}
@Override
protected 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
<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.CircleView
android:layout_width="100dp"
android:layout_height="100dp" />
RelativeLayout>
注意点:一个java源文件只能设置一个public类,这里的CircleView自定义控件类必须单独放在一个源文件中,如果不加public属性放在主函数类对应的java源文件中也是不行的,当在布局文件中创建一个子对象控件的时候是检测不到的