android控件 listview网站,Android常用控件-ListView

143158783838

由于手机屏幕有限, 所以ListView的使用非常的普遍. ListView就是用户可以通过手指上下滑动的方式来展现更多的数据.

ListView的简单使用:

新建一个ListViewDemo的项目,修改activity-main.xml中的代码:

android:layout_width="match_parent"

android:layout_height="match_parent"

android:orientation="vertical">

android:id="@+id/list_view_demo"

android:layout_width="match_parent"

android:layout_height="match_parent">

为ListView指定一个id, 这样就会在页面出现一个ListView的基本布局.

下面是MainAcitivity中代码:

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.widget.ArrayAdapter;

import android.widget.ListView;

public class MainActivity extends AppCompatActivity {

private String[] data = {"爸爸","妈妈","姐姐","妹妹","二姑","三姑",

"四舅","五伯","哥哥","嫂嫂","爷爷","奶奶","姥姥","姥爷"};

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

//android.R.layout.simple_list_item_1 作为ListView子项布局的id,

// 这是一个android内置的布局文件, 里面只有一个textview

//可用于简单的显示一段文本.

ArrayAdapter adapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1,data);

ListView listView = (ListView)findViewById(R.id.list_view_demo);

listView.setAdapter(adapter);

}

}

ListView是用来展示大量数据的, 这里用了一个数组. 数组中的数据是无法直接传递给ListView的, 需要借助适配器来传递. 由于这里提供的数据都是字符串,因此将ArrayAdapter的泛型指定为String, 依次传递参数为, 上下文, 子项布局id, 数据.

ListView的setAdapter()方法表示将建好的设配器对象传递给listview, 这样页面和数据就进行了关联.

运行效果:

143158783838

定制ListView的界面

正式的项目开发中, 不可能使用这么简单的, 很多情况是需要根据客户的需求, 进行定制开发, 下面我们就对上面的ListView进行简单的扩展.

我们把这个列表扩展成一个简单的通讯录功能功能, 会显示头像, 昵称, 和电话.

我们首先定义一个实体类, 作为ListView适配器的适配类型. 新建类Family, 代码如下:

public class Family {

private String name;

private int imageID;

private int phoneNum;

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getImageID() {

return imageID;

}

public void setImageID(int imageID) {

this.imageID = imageID;

}

public int getPhoneNum() {

return phoneNum;

}

public void setPhoneNum(int phoneNum) {

this.phoneNum = phoneNum;

}

}

name:表示称呼

imageID: 表示头像id

phoneNum: 表示电话号码

我们需要为ListView的子项指定一个我们自定义的布局, 在layout的目录下新建family_item.xml, 代码如下:

android:layout_width="match_parent"

android:layout_height="match_parent">

android:id="@+id/family_image"

android:layout_width="wrap_content"

android:layout_height="wrap_content" />

android:id="@+id/family_name"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical"

android:layout_marginLeft="10dp"/>

android:id="@+id/family_phone_num"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_gravity="center_vertical"

android:layout_marginLeft="10dp"/>

在这个布局中, 定义了ImageView用于显示头像, TextView分别用来显示称谓和电话. 并且让TextView在垂直方向居中显示.

接下来我们需要创建自定义的适配器, 这个适配器继承ArrayAdapter, 并将泛型定义为Family类. 新建类FamilyAdapter, 代码如下:

public class FamilyAdapter extends ArrayAdapter{

private int resourceID;

public FamilyAdapter(Context context, int resource, List objects) {

super(context, resource, objects);

resourceID = resource;

}

@NonNull

@Override

public View getView(int position, View convertView, ViewGroup parent) {

Family family = getItem(position); // 获取当前项的Family实例

View view = LayoutInflater.from(getContext()).inflate(resourceID, parent, false);

ImageView familyImage = (ImageView) view.findViewById(R.id.family_image);

TextView familyName = (TextView) view.findViewById(R.id.family_name);

TextView familyPhone = (TextView) view.findViewById(R.id.family_phone_num);

familyImage.setImageResource(family.getImageID());

familyName.setText(family.getName());

familyPhone.setText(family.getPhoneNum());

return view;

}

}

FamilyAdapter重写了父类的一组构造函数, 用于将上下文, ListView子项布局的id和数据都传递进来. 另外又重写了一个getView()方法, 这个方法在每个子项被滚动到屏幕内的时候会被调用.

在getView()中, 首先通过getItem()方法得到当前项的Family实例, 然后使用LayoutInflater来为这个子项加载我们传入的布局.

这里LayoutInflater的inflate()方法接收3个参数, inflate()可以动态加载一个布局文件的id, 布局id, 第二个参数是给加载好的布局添加一个父布局.第三个参数指定成false, 表示只将我们在父布局中声明的layout属性生效, 但不为这个View添加父布局, 因为一旦view有了父布局之后, 它就不能再添加到ListView中了.

之后我们调用View的findViewById()方法分别获取到ImageView和TextView的实例. 并分别调用他们的setImageResource()和setText()方法来设置显示的图片和文字, 最后将布局完成.

下面来修改MainActivity中的代码.

public class MainActivity extends AppCompatActivity {

private List familyList = new ArrayList<>();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

initFamilys();// 初始化家庭数据

FamilyAdapter adapter = new FamilyAdapter(MainActivity.this,R.layout.family_item,familyList);

ListView listView = (ListView)findViewById(R.id.list_view_demo);

listView.setAdapter(adapter);

}

private void initFamilys() {

for(int i= 0; i<2; i++){

Family family1 = new Family("爸爸", R.mipmap.family_1,

"13813813888");

familyList.add(family1);

Family family2 = new Family("妈妈", R.mipmap.family_2,

"13813813888");

familyList.add(family2);

Family family3 = new Family("姐姐", R.mipmap.family_1,

"13813813888");

familyList.add(family3);

Family family4 = new Family("三姑", R.mipmap.family_2,

"13813813888");

familyList.add(family4);

Family family5 = new Family("妹妹", R.mipmap.family_1,

"13813813888");

familyList.add(family5);

Family family6 = new Family("二姑", R.mipmap.family_1,

"13813813888");

familyList.add(family6);

Family family7 = new Family("三姑", R.mipmap.family_2,

"13813813888");

familyList.add(family7);

Family family8 = new Family("四舅",

R.mipmap.family_1, "13813813888");

familyList.add(family8);

Family family9 = new Family("三姑", R.mipmap.family_2,

"13813813888");

familyList.add(family9);

Family family10 = new Family("哥哥", R.mipmap.family_1,

"13813813888");

familyList.add(family10);

Family family11 = new Family("嫂嫂", R.mipmap.family_1,

"13813813888");

familyList.add(family11);

Family family12 = new Family("爷爷", R.mipmap.family_2,

"13813813888");

familyList.add(family12);

Family family13 = new Family("奶奶", R.mipmap.family_1,

"13813813888");

familyList.add(family13);

Family family14 = new Family("姥姥", R.mipmap.family_2,

"13813813888");

familyList.add(family14);

Family family15 = new Family("姥爷", R.mipmap.family_1,

"13813813888");

familyList.add(family15);

}

}

}

运行效果:

143158783838

相信你已经领悟到了诀窍, 只要修改family_item.xml中的内容, 就可以定制出各种复杂的界面了.

提升ListView的运行效率

之所以说ListView很难用, 是因为它有很多细节可以优化. 其中效率就是很重要的一点. 目前我们的运行效率极低, 是因为FamilyAdapter的getView()方法中, 每次都将布局重新加载一遍, 当ListView快速滚动的时候, 就会出现性能的瓶颈.

在getView()方法中还有一个converView参数, 这个参数用于将之前加载好的布局进行缓存, 以便之后可以重用. 所以修改代码如下:

Family family = getItem(position); // 获取当前项的Family实例

View view;

if(convertView == null){

view = LayoutInflater.from(getContext()).inflate(resourceID,

parent, false);

} else {

view = convertView;

}

convertView 为null的时候, 才去加载布局, 如果不为null, 则直接重用convertView. 这样就大大提高了ListView的运行效率. 加快滚动的时候也可以出现很好的性能.

当然这部分代码还是可以继续优化的, 虽然现在不会再去重复加载布局, 但是每次在getView()方法中还是会调用View的findViewById()方法来获取一次控件的实例.

我们可以借助一个ViewHolder来对这部分性能进行优化. 修改FamilyAdapter中的优化代码.

public View getView(int position, View convertView, ViewGroup parent) {

Family family = getItem(position); // 获取当前项的Family实例

View view;

ViewHolder viewHolder;

if(convertView == null){

view = LayoutInflater.from(getContext()).inflate(resourceID,

parent, false);

viewHolder = new ViewHolder();

viewHolder.familyImage = (ImageView) view.findViewById(R.id.family_image);

viewHolder.familyName = (TextView) view.findViewById(R.id.family_name);

viewHolder.familyPhone = (TextView) view.findViewById(R.id.family_phone_num);

view.setTag(viewHolder); //将ViewHolder储存在View中

} else {

view = convertView;

viewHolder = (ViewHolder) view.getTag();// 重新获取ViewHolder

}

viewHolder.familyImage.setImageResource(family.getImageID());

viewHolder.familyName.setText(family.getName());

viewHolder.familyPhone.setText(family.getPhoneNum());

return view;

}

class ViewHolder {

ImageView familyImage;

TextView familyName;

TextView familyPhone;

}

解读:

新增的ViewHolder用于对控件的实例进行缓存, 当convertView为null的时候, 创建一个ViewHolder对象, 并将控件实例都存在ViewHolder里, 然后调用view的setTag()方法, 将ViewHolder对象储存在view中.

当convertView不为null的时候, 则调用View的getTag()方法, 把ViewHolder重新取出. 这样所有的控件实例都缓存在了ViewHolder里面. 就没有必要每次通过findViewById()方法来获取控件实例了.

运行效果:

143158783838

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值