在平时的开发中,我们使用的ListView基本都是单一布局,但是在一些特殊的应用中,ListView务必使用多样性的布局,如聊天窗口、新闻列表等。既然使用到ListView,那对其优化是必不可少的,下面我们一起来学习ListView多种布局的使用及优化。
首先我们看下模拟新闻列表的原型:
在这个原型中,ListView一共有三种布局,下面就一步一步来实现这个原型。
一、定义ListView的三种布局
1.布局一(第一个列表)
<?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="100dp"
android:padding="8dp"
android:orientation="horizontal" >
<ImageView
android:id="@+id/news1_iv_pic"
android:layout_width="0dp"
android:layout_height="match_parent"
android:scaleType="fitCenter"
android:layout_weight="2" />
<TextView
android:layout_marginLeft="8dp"
android:id="@+id/news1_tv_content"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="3" />
</LinearLayout>
2.布局二(第二个列表)
<?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="wrap_content"
android:orientation="vertical"
android:padding="8dp" >
<TextView
android:id="@+id/new2_tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginTop="8dp"
android:orientation="horizontal" >
<ImageView
android:id="@+id/new2_iv_pic1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:scaleType="fitCenter" />
<ImageView
android:id="@+id/new2_iv_pic2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:scaleType="fitCenter" />
<ImageView
android:id="@+id/new2_iv_pic3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_marginLeft="8dp"
android:layout_weight="1"
android:scaleType="fitCenter" />
</LinearLayout>
</LinearLayout>
3.布局三(第三个列表)
<?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="200dp"
android:orientation="vertical"
android:padding="8dp" >
<TextView
android:id="@+id/new3_tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/new3_iv_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:scaleType="fitCenter" />
</LinearLayout>
二、定义主布局
<pre name="code" class="html"><?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="200dp"
android:orientation="vertical"
android:padding="8dp" >
<TextView
android:id="@+id/new3_tv_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/new3_iv_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="8dp"
android:scaleType="fitCenter" />
</LinearLayout>
三、定义新闻实体类
public class Message {
//类型N的新闻对应第一N种布局
public static final int TYPE_ONE = 0;
public static final int TYPE_TWO = 1;
public static final int TYPE_THREE = 2;
private int mType;
private String mText;
public int getType() {
return mType;
}
public void setType(int type) {
mType = type;
}
public String getText() {
return mText;
}
public void setText(String text) {
mText = text;
}
}
四、创建适配器
public class MessageAdapter extends BaseAdapter {
private ArrayList<Message> mMessages;
private LayoutInflater mInflater;
public MessageAdapter(Context context) {
mMessages = Datas.getAllMessage();
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount() {
return mMessages.size();
}
@Override
public Message getItem(int position) {
return mMessages.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
/**
* 告诉系统ListView中有多少种布局
*/
@Override
public int getViewTypeCount() {
return 3;
}
/**
* 返回每个item对应的布局类型
*/
@Override
public int getItemViewType(int position) {
return getItem(position).getType();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
TypeOneViewHolder typeOneViewHolder = null;
TypeTwoViewHolder typeTwoViewHolder = null;
TypeThreeViewHolder typeThreeViewHolder = null;
//获取当前item的新闻实体
Message message = getItem(position);
//获取当前item的布局类型
int type = message.getType();
if (convertView == null) {
//根据当前item的布局类型选择对应的操作
switch (type) {
//布局一
case Message.TYPE_ONE:
convertView = mInflater.inflate(R.layout.item_listview_news1, null);
typeOneViewHolder = new TypeOneViewHolder();
typeOneViewHolder.typeOneContentTv = (TextView) convertView.findViewById(R.id.news1_tv_content);
typeOneViewHolder.typeOnePicIv = (ImageView) convertView.findViewById(R.id.news1_iv_pic);
typeOneViewHolder.typeOneContentTv.setText(message.getText());
typeOneViewHolder.typeOnePicIv.setImageResource(R.drawable.ic_launcher);
convertView.setTag(typeOneViewHolder);
break;
//布局二
case Message.TYPE_TWO:
convertView = mInflater.inflate(R.layout.item_listview_news2, null);
typeTwoViewHolder = new TypeTwoViewHolder();
typeTwoViewHolder.typeTwoContentTv = (TextView) convertView.findViewById(R.id.new2_tv_content);
typeTwoViewHolder.typeTwoPicIv1 = (ImageView) convertView.findViewById(R.id.new2_iv_pic1);
typeTwoViewHolder.typeTwoPicIv2 = (ImageView) convertView.findViewById(R.id.new2_iv_pic2);
typeTwoViewHolder.typeTwoPicIv3 = (ImageView) convertView.findViewById(R.id.new2_iv_pic3);
typeTwoViewHolder.typeTwoContentTv.setText(message.getText());
typeTwoViewHolder.typeTwoPicIv1.setImageResource(R.drawable.ic_launcher);
typeTwoViewHolder.typeTwoPicIv2.setImageResource(R.drawable.ic_launcher);
typeTwoViewHolder.typeTwoPicIv3.setImageResource(R.drawable.ic_launcher);
convertView.setTag(typeTwoViewHolder);
break;
//布局三
case Message.TYPE_THREE:
convertView = mInflater.inflate(R.layout.item_listview_news3, null);
typeThreeViewHolder = new TypeThreeViewHolder();
typeThreeViewHolder.typeThreeContentTv = (TextView) convertView.findViewById(R.id.new3_tv_content);
typeThreeViewHolder.typeThreePicIv = (ImageView) convertView.findViewById(R.id.new3_iv_pic);
typeThreeViewHolder.typeThreeContentTv.setText(message.getText());
typeThreeViewHolder.typeThreePicIv.setImageResource(R.drawable.ic_launcher);
convertView.setTag(typeThreeViewHolder);
break;
default:
break;
}
} else {
switch (type) {
case Message.TYPE_ONE:
typeOneViewHolder = (TypeOneViewHolder) convertView.getTag();
typeOneViewHolder.typeOneContentTv.setText(message.getText());
typeOneViewHolder.typeOnePicIv.setImageResource(R.drawable.ic_launcher);
break;
case Message.TYPE_TWO:
typeTwoViewHolder = (TypeTwoViewHolder) convertView.getTag();
typeTwoViewHolder.typeTwoContentTv.setText(message.getText());
typeTwoViewHolder.typeTwoPicIv1.setImageResource(R.drawable.ic_launcher);
typeTwoViewHolder.typeTwoPicIv2.setImageResource(R.drawable.ic_launcher);
typeTwoViewHolder.typeTwoPicIv3.setImageResource(R.drawable.ic_launcher);
break;
case Message.TYPE_THREE:
typeThreeViewHolder = (TypeThreeViewHolder) convertView.getTag();
typeThreeViewHolder.typeThreeContentTv.setText(message.getText());
typeThreeViewHolder.typeThreePicIv.setImageResource(R.drawable.ic_launcher);
break;
default:
break;
}
}
//可根据日志来查看布局复用的情况
LogUtil.d(position + " item : " + convertView);
return convertView;
}
/**
* 布局一控件缓存类
*/
class TypeOneViewHolder {
TextView typeOneContentTv;
ImageView typeOnePicIv;
}
/**
* 布局二控件缓存类
*/
class TypeTwoViewHolder {
TextView typeTwoContentTv;
ImageView typeTwoPicIv1;
ImageView typeTwoPicIv2;
ImageView typeTwoPicIv3;
}
/**
* 布局三控件缓存类
*/
class TypeThreeViewHolder {
TextView typeThreeContentTv;
ImageView typeThreePicIv;
}
}