ListView

          ListView是android开发使用最频繁的UI控件之一,在很多应用需要将内容以列表的形式显示出来,如下图所示的一个效果图上可以一发现,每一行显示的内容形式都是一致的,一个图片内容和2个文本内容,它是如何实现的呢,接下来开始用代码解析这张图片的实现过程。



1.首先介绍每一行内容的布局文件list_item.xml

图片和文本内容采用用水平布局,文本内容之间采用垂直布局,代码如下:

        因为图片的大小不一致,所有采用了固定大小,同时防止图片拉伸压缩变形,给图片设置了scaleType属性将其值设定为fitCenter,意思是按比例扩大/缩小到View的宽度,居中显示。在图中,第二行文本显示内容有限制,超过的部分用...代替,这是设置了TextView的ellipsize属性,看定义文字的省略方式,超过部分开始省略、中间省略、最后省略等,同时设置文本内容单行显示。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="44dp"
              android:orientation="horizontal">
    <ImageView
        android:id="@+id/fruit_img"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginTop="2dp"
        android:scaleType="fitCenter"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <TextView
            android:id="@+id/tv_content"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:gravity="fill_vertical"
            android:singleLine="true"
            android:textSize="18sp"/>
        <TextView
            android:id="@+id/tvDetail"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10dp"
            android:ellipsize="middle"
            android:gravity="fill_vertical"
            android:singleLine="true"/>
    </LinearLayout>
</LinearLayout>
2.显示内容的对象类讲解

        从图片显示内容中每个List项都包含一张图片、一个水果的名字和一些相关的说明,所以我定义了一个类,用作显示的内容。该对象的成员有name(名字)、imageId(图片Id)、detail(详细介绍)。具体代码入下:

......
public class Fruit
{
    private String name;
    private int imageId;
    private String detail;
    public Fruit(String name, int imageId, String detail)
    {
        super();        
        this.name = name;        
        this.imageId = imageId;        
        this.detail = detail;    
    }
    public String getName(){return name;}
    public String getDetail(){return detail;}
    public int getImageId(){return imageId;}
}
3.ListView的适配器

ListView的内容显示方式是要需要设置ListView的适配器(Adapter)

该Adapter继承了ArrayAdapter

代码中申明了一个有3个参数的构造方法,一个上下文、一个布局文件、和数据集

    // 适配器构造方法
    public MyAdapter(Context context, int layout, List<Fruit> obj)
    {
        super(context, layout, obj);
        this.resourceId = layout;
    }
在适配器类中申明了一个内部类ViewHolder,该类中有三个成员变量,1个ImageView类型的变量和2个TextView类型的变量,该内部类是用于辅助内容显示的,提高ListView效率的作用

    static class ViewHolder
    {
        ImageView fruitImage;
        TextView tvContent;
        TextView tvDetail;
    }
最后重写了父类的getView方法。

@Override
    public View getView(int position, View convertView, ViewGroup parent)
    {
        Fruit fruit = getItem(position);
        ViewHolder viewHolder;
        if (convertView == null)
        {
            viewHolder = new ViewHolder();
            convertView = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
            viewHolder.fruitImage = (ImageView) convertView.findViewById(R.id.fruit_img);
            viewHolder.tvContent = (TextView) convertView.findViewById(R.id.tv_content);
            viewHolder.tvDetail = (TextView) convertView.findViewById(R.id.tvDetail);
            convertView.setTag(viewHolder);
        } else
        {
            viewHolder = (ViewHolder) convertView.getTag();
        }
        viewHolder.fruitImage.setImageResource(fruit.getImageId());
        viewHolder.tvContent.setText(fruit.getName());
        viewHolder.tvDetail.setText(fruit.getDetail());
        return convertView;
    }
        首先查看convertView是否被加入缓存。如果没有则从布局文件中加载,并设置一个标签,当convertView加入进缓存,直接读取该标签,并将其赋值给局部变量viewHolder,最后设置显示内容,最后返回convertView

4.Activity的实现

首先申明了List变量,用做ListView的数据集,同时定义了一些需要显示内容中的图片ID和文本信息。

    int[] imgIds = {R.mipmap.one, R.mipmap.two, R.mipmap.three, R.mipmap.four, R.mipmap.five, R.mipmap.ic_launcher};
    String[] names = {"苹果", "梨子", "火龙果", "猕猴桃", "橙子", "水果机器人"};
    String[] details = {"这是一个苹果,一个苹果,一个苹果,一个苹果,这是一个苹果,一个苹果,一个苹果,一个苹果,这是一个苹果,一个苹果,一个苹果,一个苹果,这是一个苹果,一个苹果,一个苹果,一个苹果",
            "这是一个梨子,一个梨子,一个梨子,一个梨子,这是一个梨子,一个梨子,一个梨子,一个梨子,这是一个梨子,一个梨子,一个梨子,一个梨子,这是一个梨子,一个梨子,一个梨子,一个梨子",
            "我是一个火龙果,我是一个火龙果,我是一个火龙果,我是一个火龙果,我是一个火龙果,我是一个火龙果,我是一个火龙果,我是一个火龙果我是一个火龙果,我是一个火龙果,这是一个苹果,一个苹果,一个苹果,一个苹果",
            "我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃我是一个猕猴桃我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃,我是一个猕猴桃",
            "我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子,我是一个橙子",
            "我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人,我是一个水果机器人"};

在onCreate中首先对数据集做了初始化。

private void initFruit()
{
    for (int i = 0; i < 18; i++)
    {
        int index = random(6);
        Fruit fruit = new Fruit(names[index], imgIds[index], details[index]);
        listFruit.add(fruit);
    }
}
其中用了一个随机获取的方法随机调用申明的数据信息内容,代码如下:

private int random(int i)
{
    Random random = new Random();
    int target = random.nextInt(i);
    return target;
}

然后初始化ListView的适配器并对其赋值

最后为ListView进行复制

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);
        initFruit();
        MyAdapter adapter = new MyAdapter(MyActivity.this, R.layout.list_item, listFruit);
        ListView listView = (ListView) this.findViewById(R.id.lv_fruit);
        listView.setAdapter(adapter);
        listView.setOnItemClickListener(this);
    }

最后附上源代码下载地址:http://download.csdn.net/detail/dadadadaffd/9713544



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值