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