今天写了一段代码,用于读取Android手机中的通话记录。
由于单纯的ListView不能满足自己的显示需求,因此我重新创建一个布局
以下是布局代码:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="80dp"
android:orientation="horizontal">
<RelativeLayout
android:layout_width="80dp"
android:layout_height="80dp"
android:layout_gravity="center_vertical">
<ImageView
android:id="@+id/iv_call_avatar"
android:layout_width="75dp"
android:layout_height="75dp"
android:layout_centerVertical="true"
android:padding="10dp"
android:src="@mipmap/ic_launcher" />
<ImageView
android:id="@+id/iv_call_indicator"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/iv_call_avatar"
android:layout_alignRight="@id/iv_call_avatar"
android:layout_marginRight="5dp"
android:layout_marginBottom="5dp"
android:src="@mipmap/ic_warning" />
</RelativeLayout>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/tv_call_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:gravity="bottom"
android:text="name"
android:textColor="#000"
android:textSize="26sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv_call_type"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="top"
android:layout_marginTop="4dp"
android:paddingRight="5dp"
android:src="@mipmap/ic_outgoing_call" />
<TextView
android:id="@+id/tv_call_phone"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="13810001000" />
<TextView
android:id="@+id/tv_call_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:text="京城" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/tv_call_time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="TIME"
android:layout_gravity="center_vertical"
android:textSize="40sp" />
</LinearLayout>
效果图:
要使用这个布局就需要自定义一个适配器CallAdapter继承BaseAdapter
重写方法父类方法:
public class CallLogAdapter extends BaseAdapter {
@Override
public int getCount() {
return 0;
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return null;
}
}
需要重点编写的方法是getView()。
将从数据控中的信息装到ListView中就需要在此方法中写
由于此方法底层自带ListView优化,故而当屏幕上只能显示N条信息时,至多会创建N+1个Item对象,故而会出现布局重用
在对每个view赋值时,如果写的是
if (call.getType()==3){
viewHolder.tvName.setTextColor(Color.RED);
}
类似这种情况,那么在布局复用时,其之前设置的文本颜色为红色,没有被清除,故而在上下滑动后会出现不需要红色的字体也变成了红色。
效果图:
1.理想情况
2.滑动后
显然这种结果并不是我想要的。
原因分析:
上面的赋值写法只考虑到了call.getType()==3的这种情况,对于其他情况并没有考虑进去,故而当call.getType()!=3时,底层并不知道怎么处理,故而我们需要将所有的可能都考虑进去
解决办法:
将上面的代码改成:
if (call.getType()==3){
viewHolder.tvName.setTextColor(Color.RED);
}else {
viewHolder.tvName.setTextColor(Color.BLACK);
}
这样子考虑到了当call.getType() == 3和call.getType() != 3所有的情况。
总结:在自定义adapter时,由于ListView的item数量过多,系统底层会对其进行优化(如果不优化的话,有一个item便建一个对象,会消耗系统资源),所以需要考虑item复用的问题,故而在赋值操作时,需要将所有可能出现的情况考虑进去。