自定义ListView

本文详细介绍了如何在Android中自定义ListView,通过创建CustomAdapter实现显示用户列表,包括头像、用户名和描述。文章重点讲解了Adapter的四个关键方法,并通过ViewHolder优化性能。示例中展示了VIP用户在名字前显示标识的实现方式。
摘要由CSDN通过智能技术生成

技术总结

——AJSZJ01131221-自定义ListView

12月21日

 

ListView是Android的UI系统中的重要组件之一,也是Android MVC模型的典型体现。

ListView的滑动、点击方式非常适合小屏幕移动设备的交互方式,自然也成为Android系统交互开发的关键组件。对ListView的掌握意味着对Android平台的内容展现由简单向复杂的提升。

这篇文章我们重点讨论对ListView的自定义。

实例效果为:显示一个用户列表,包用户头像、用户名、用户描述。用户名为Frank的用户为VIP,在其名称之前显示VIP标识。

效果图:效果图

提到ListView就一定要讨论Adapter。Adapter是适配器模式在ListView上实现的关键,是数据和视图之间的适配器。自定义ListView的每个项目,实际上就是自定义Adapter。

Android的SDK为我们提供了很多Adapter,其继承关系如下图:

 

 

 


我们在这里要继承BaseAdapter,以获得最大的自定义空间。

CustomAdapter的代码如下:

 

package com.ajszj.demolistview;

 

import java.util.List;

 

import android.content.Context;

import android.graphics.Color;

import android.graphics.drawable.Drawable;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.BaseAdapter;

import android.widget.ImageView;

import android.widget.TextView;

 

publicclass CustomAdapter extends BaseAdapter {

 

         private LayoutInflater mInflater=null;

         private List<User> mData =null;

         private Context mContext =null;

         private ViewHolder mHolder;

 

         public CustomAdapter(Contextcontext, List<User> userList)throws Exception {

                   mContext = context;

                   mInflater = LayoutInflater.from(context);

                   if (userList ==null){

                            throw newException("no user");

                   } else {

                            mData = userList;

                   }

         }

 

         private class ViewHolder {

                   ImageView uPortrait;

                   TextView uName;

                   TextView uDspt;

         }

 

         @Override

         public int getCount(){

                   return mData.size();

         }

 

         @Override

         public ObjectgetItem(intposition) {

                   return mData.get(position);

         }

 

         @Override

         public long getItemId(intposition) {

                   return ((User) getItem(position)).getId();

         }

 

         @Override

         public ViewgetView(intposition, View convertView, ViewGroup parent) {

 

                   if (convertView ==null){

 

                            convertView = mInflater.inflate(R.layout.custom_list_item,null);

 

                            mHolder =newViewHolder();

                            mHolder.uPortrait = (ImageView)convertView

                                               .findViewById(R.id.item_portrait);

                            mHolder.uName = (TextView)convertView.findViewById(R.id.item_name);

                            mHolder.uDspt = (TextView)convertView.findViewById(R.id.item_dspt);

 

                            convertView.setTag(mHolder);

                   } else {

                            mHolder = (ViewHolder)convertView.getTag();

                   }

 

                   User user = (User) getItem(position);

 

                   mHolder.uPortrait.setImageResource(user.getmPortraitId());

                   mHolder.uName.setText(user.getmName());

                   mHolder.uDspt.setText(user.getmDspt());

 

                   if (user.getmName().equals("Frank")){

                            Drawable drawable = mContext.getResources().getDrawable(

                                               R.drawable.vip_icon_small);

                            drawable.setBounds(0,0, drawable.getMinimumWidth(), drawable.getMinimumHeight());

                            mHolder.uName.setTextColor(Color.RED);

                            mHolder.uName.setCompoundDrawablePadding(5);

                            mHolder.uName.setCompoundDrawables(drawable,null,null, null);

                   } else {

                            mHolder.uName.setTextColor(Color.parseColor("#666666"));

                            mHolder.uName.setCompoundDrawablePadding(0);

                            mHolder.uName.setCompoundDrawables(null,null,null, null);

                   }

 

                   return convertView;

         }

}

在CustomAdapter类中,我们复写了BaseAdapter的四个方法:getCount()、getItem()、getItemId()、getView(),并定义了一个私有内部类ViewHolder。下面逐个解释:

1.   getCount()

这个方法返回ListView的大小,以便计算ListView的高度以及其他用途。

需要返回的是item的数量,由数据决定。

2.   getItem(int postion)

这个方法返回对应position的item,为单个数据对象,返回值类型是Object,即可以返回任意对象。这也要求在使用getItem()的时候要注意类型的转换。

3.   getItemId(int position)

这个方法返回对应position的item的id值,要注意区分position和id:

ListView中的每个item都会有一个item和一个position值,position为该item在ListView中的位置索引;id为该item包含的数据对象的id属性,两个值都是从0开始。最重要区别为,id根据数据不同而不同,即id是数据的属性;position根据数据在ListView中的位置不同而不同。数据的id属性一般在设定之后不会改变。

getItemId()即是让开发者根据position返回对应此position的数据的id属性。

4.   getView(int position, ViewconvertView, ViewGroup parent)

这是最重要的方法,Adapter就是使用这个方法将内容和显示方式进行对接,达到将数据显示到ListView中的目的。

这个方法的返回值类型是View,即是当前position的item对应的显示到ListView中的内容,getView方法要做的,就是用数据填充这个item的内容。

下面对getView方法和ViewHolder类进行解析:

getView的第二个参数convertView是Android虚拟机传入的缓存View,这是为了提升效率进行的缓存处理。在使用ListView的时候要充分利用Android提供的缓存机制,减少视图对象的创建进而减少资源消耗。

在使用convertView时,需要定义对应布局的ViewHolder类,来进行对视图中的控件的标记。

定义ViewHolder类的方式就是定义属性以对应布局中的控件,本例中:


重写getView()方法的步骤为:

l  判断convertView是否为空。如果为空,则使用LayoutInflater对item布局进行加载,同时新建ViewHolder对象并初始化。最后调用convertView的setTag()方法将ViewHolder对象和convertView进行关联。

如果不为空,则从convertView中获得暂存的ViewHolder对象。

l  得到和convertView关联的ViewHolder对象之后,开始对ViewHolder对象进行内容填充,即是对ViewHolder的属性进行赋值操作。

l  要注意对ViewHolder对象的操作,实际上就是对ListView中最终显示的View的操作。所以,如果需要对ListView中的View进行动态样式改变和编辑,需要在此处进行。如本例中的Vip标识显示,即是在此处进行定义。

l  最后是函数的返回值,返回值应该是convertView,它已经和ViewHolder进行了关联,所以以上对ViewHolder对象的赋值操作,都反映在当前的convertView对象中。

现在,已经完成了对BaseAdapter的自定义,测试代码如下:

Activity代码:

package com.ajszj.demolistview;

 

import java.util.ArrayList;

import java.util.List;

import java.util.Random;

 

import android.app.Activity;

import android.os.Bundle;

import android.widget.ListView;

 

publicclass MainActivity extends Activity {

 

     private ListView mListView =null;

 

     private int[] portraits = { R.drawable.img01,R.drawable.img02,

              R.drawable.img03, R.drawable.img04,R.drawable.img05 };

 

     private String[] names = { "Frank","Tom", "John", "Jobs", "Stark" };

 

     private String[] dspts = { "long,long day", "nothing to say",

              "merry Xmas", "home","i need a feast" };

 

     private List<User> list =null;

 

     @Override

     protected void onCreate(BundlesavedInstanceState) {

         super.onCreate(savedInstanceState);

         setContentView(R.layout.activity_main);

 

         mListView = (ListView) findViewById(R.id.list);

 

         Random random = new Random();

         list = new ArrayList<User>();

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

              list.add(new User(random.nextLong(),portraits[random.nextInt(5)],

                       names[random.nextInt(5)],dspts[random.nextInt(5)]));

         }

 

         try {

              CustomAdapter adapter =newCustomAdapter(this, list);

              mListView.setAdapter(adapter);

         } catch (Exception e) {

              e.printStackTrace();

         }

 

     }

}

item布局代码:

<?xml version="1.0"encoding="utf-8"?>

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"

    android:layout_height="wrap_content"

    android:orientation="horizontal"

    android:padding="5dp" >

 

    <ImageView

        android:id="@+id/item_portrait"

        android:layout_width="60dp"

        android:layout_height="60dp"

        android:src="@drawable/ic_launcher"/>

 

    <LinearLayout

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:layout_gravity="top"

        android:layout_marginLeft="5dp"

        android:orientation="vertical">

 

        <TextView

            android:id="@+id/item_name"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="Frank"

            android:textColor="#000000"

            android:textSize="18sp"

            android:singleLine="true"

            android:textStyle="bold" />

 

        <TextView

            android:id="@+id/item_dspt"

            android:layout_width="wrap_content"

            android:layout_height="wrap_content"

            android:text="description"

            android:singleLine="true"

            android:textColor="#666666"

            android:textSize="14sp"/>

    </LinearLayout>

 

</LinearLayout>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值