《Android群英传》阅读笔记——第四章:ListView使用技巧
昨天把自定义View看完了,真是受益颇多啊,今天又来看ListView了,我们都知道现在已经出了RecyclerView不可谓不强大,但是我们在一般情况下,用ListView就够了,除非有一些特殊的需求,所以ListView的地位还是挺稳的,这就促使我们必须必的将它掌握,虽然在这之前我用ListView用的也挺多的,但是就是差一个总结了,现在正好借着群英传阅读笔记的这个机会来将我所理解的记下来,当然还是以书为主哈,下面我们来看书吧!
一、ListView常用优化技巧
- 使用ViewHolder模式提高效率
ViewHolder模式是提高ListView效率的一个很重要的方法,他充分利用了ListView的视图缓存机制,避免每次调用getView()的时候去通过findViewById()实例化控件,有人测试结果效率可以提高50%,我们只需要在自定义的Adapter里面定义一个内部类ViewHolder即可,代码如下:
private class ViewHolder {
private ImageView img;
private TextView title;
}
剩下的,我们只要在getView()方法中通过视图缓存机制来重用以缓存即可,完整的ListView的Adapter如下:
package com.llx.lenovo.listviewdemo;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
/*
* 项目名: ListViewDemo
* 包名: com.llx.lenovo.listviewdemo
* 文件名: MyAdapter
* 创建者: LLX
* 创建时间: 2017/2/27 17:08
* 描述: ListView适配器
*/
public class MyAdapter extends BaseAdapter {
private Context mContext;
private List<String> mListData;
private LayoutInflater mLayoutInflater;
private ViewHolder mViewHolder;
public MyAdapter(Context mContext, List<String> mListData) {
this.mContext = mContext;
this.mListData = mListData;
//获取系统服务
mLayoutInflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
//返回长度
@Override
public int getCount() {
return mListData.size();
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View view, ViewGroup viewGroup) {
//判断是否有缓存
if (view == null) {
//实例化ViewHolder
mViewHolder = new ViewHolder();
//加载item布局
view = mLayoutInflater.inflate(R.layout.item, viewGroup, false);
//绑定id
mViewHolder.img = (ImageView) view.findViewById(R.id.item_imag);
mViewHolder.title = (TextView) view.findViewById(R.id.item_text);
//将实例化后的ViewHolder存储到view中
view.setTag(mViewHolder);
} else {
//若有缓存则通过view.getTag的方法获取到ViewHolder
mViewHolder = (ViewHolder) view.getTag();
}
//设置布局中控件要显示的布局
mViewHolder.title.setText(mListData.get(position));
return view;
}
private class ViewHolder {
private ImageView img;
private TextView title;
}
}
好的,现在我们的adapter已经设置好了,下一步就是将为该adapter添加数据,并和ListView绑定到一块儿了,修改MainActivity.java如下:
package com.llx.lenovo.listviewdemo;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView mListView;
private MyAdapter myAdapter;
private List<String> mListData;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//数据初始化
initData();
//控件初始化
initView();
}
//数据初始化
private void initData() {
//实例话List
mListData = new ArrayList<>();
//循环向List中添加数据
for (int i = 0; i < 10; i++) {
mListData.add("第" + i + "张");
}
}
//控件初始化
private void initView() {
//实例化adapter
myAdapter = new MyAdapter(this, mListData);
//绑定id
mListView = (ListView) findViewById(R.id.mlistView);
//设置adapter
mListView.setAdapter(myAdapter);
}
}
这样我们一个简单的ListView就完成了,运行效果如下;
1、设置item间分隔线
ListView每个item之间,可以通过分隔线进行区分,系统也提供了divider和dividerHeight两个属性来帮助我们实现这一功能。通过这两个属性,也可以控制每个item之间的分隔线和它的高度,分隔线不仅仅可以设置一个颜色,也可以设置成一个图片资源,用法如下:
android:divider="@color/colorPrimary"
android:dividerHeight="5dp"
设置好后,效果如下:
假如我们不想要分隔线,则将divider属性改为如下:
android:divider="@null"
是否生效了呢,看下图:
2、隐藏ListView的滚动条
这个就看需求了,虽然感觉取消和不取消并没有大的影响,但是,毕竟有这个方法,那么我们就写出来吧,很简单,就一个属性,如下:
android:scrollbars="none"
3、取消ListView的Item点击效果
用过ListView的同学肯定熟悉,当点击其中的Item时会出现一个灰色的点击效果,如下:
若是我们不想要这个灰色的点击效果该怎么办呢?其实也和去除滚动条的一样,添加一个属性就好了,如下:
android:listSelector="@android:color/transparent"
当然里面的值不是固定的哈,可以用”#00000000”代替,这个颜色就是透明的了,这样我们就把点击的颜色去掉了。若是要反馈其他的颜色,直接设置就好了,只是这里有个坑,等以后再说,毕竟现在是看书嘛。
4、设置ListView需要显示在第几项:
listview.setSelection(15);//显示第15个item
5、瞬间的平滑到第几项:
listview.smoothScrollBy(1,15);
listview.smoothScrollByOffset(15);
listview.smoothScrollToPosition(15);
6、动态修改ListView:
这个就很常用了,listView的数据并不是固定的,我们会根据我们的需求对listView的数据进行修改,最常用的无非就是,添加和删除了,我们先在我们的布局中增加一个Button,如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.llx.lenovo.listviewdemo.MainActivity">
<ListView
android:id="@+id/mlistView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:divider="@null"
android:dividerHeight="5dp"
android:listSelector="@android:color/transparent"
android:scrollbars="none" />
<Button
android:id="@+id/bt_add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="添加数据" />
</RelativeLayout>
修改MainActivity.java代码如下:
....
//Button
private Button bt_add;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
....
//控件初始化
initView();
bt_add.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//添加数据