ListView的demo在网上有很多,自己去找。。。
1、基本用法
<!-- main.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.sky.listviewdemo.MainActivity">
<Button
android:id="@+id/btnNormal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="@string/normal" />
<Button
android:id="@+id/btnCustom"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="@string/custom" />
</LinearLayout>
// MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btnNormal;
private Button btnCustom;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnNormal = (Button)findViewById(R.id.btnNormal);
btnCustom = (Button)findViewById(R.id.btnCustom);
btnNormal.setOnClickListener(this);
btnCustom.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()){
case R.id.btnNormal:
normalListView();
break;
case R.id.btnCustom:
customListView();
break;
default:
}
}
private void normalListView() {
Intent intent = new Intent(MainActivity.this, NormalListViewActivity.class);
startActivity(intent);
}
private void customListView() {
Intent intent = new Intent(MainActivity.this, CustomListViewActivity.class);
startActivity(intent);
}
}
<!-- normal_list_view.xml -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.sky.listviewdemo.NormalListViewActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="@string/normal_list"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"/>
<ListView
android:id="@+id/normalListView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
// NormalListViewActivity
public class NormalListViewActivity extends AppCompatActivity {
private ListView listView;
private String[] listData = {
"111","222","333","444","555",
"666","777","888","999","000",
"qqq","www","eee","rrr","ttt",
"yyy","uuu","iii","ooo","ppp"
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.normal_list_view);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(NormalListViewActivity.this,
android.R.layout.simple_list_item_1, listData);
ListView listView = (ListView)findViewById(R.id.normalListView);
listView.setAdapter(adapter);
}
}
从NormalListViewActivity中可以看出,显示listView只需要调用ListView的setAdapter()方法。
setAdapter()方法接收一个参数:adapter适配器
所以需要构建适配器就行了。
这里用了ArrayAdapter作为构建的适配器,它可以通过泛型来指定适配的数据类型。
android.R.layout.simple_list_item_1是作为ListView子项布局的id,它是android内置的布局文件,里面只有一个TextView,用于显示一段文本。
所以,当我们使用自定义布局文件和自定义adapter时,就能够达到定制ListView的效果。
2、定制ListView
<!-- activity_custom_list_view -->
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="com.sky.listviewdemo.CustomListViewActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="24sp"
android:text="@string/custom_list"/>
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#000"/>
<ListView
android:id="@+id/customListView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
// CustomListViewActivity
public class CustomListViewActivity extends AppCompatActivity {
// 装载列表资源
private int[] listData = {
R.drawable.pic_1, R.drawable.pic_2, R.drawable.pic_3,
R.drawable.pic_4, R.drawable.pic_5, R.drawable.pic_6,
R.drawable.pic_7, R.drawable.pic_8, R.drawable.pic_9,
};
// 将资源放到list中
private List<YYPic> listItem = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_custom_list_view);
// 装载数据
addItemData();
// 构建adapter
PicAdapter adapter = new PicAdapter(CustomListViewActivity.this,
R.layout.custom_list_item, listItem);
// 显示列表
ListView listView = (ListView)findViewById(R.id.customListView);
listView.setAdapter(adapter);
}
private void addItemData() {
for(int i=0; i<listData.length; i++){
YYPic pic = new YYPic(listData[i]);
listItem.add(pic);
}
}
}
// 新建类,作为构建adapter的适配类型(就像ArrayAdaper<String>中的String类型)
public class YYPic {
// id作为图片资源的id项
private int picId;
public YYPic(int id){
this.picId = id;
}
public int getPicId() {
return picId;
}
}
// 列表显示的布局内容
<?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">
<ImageView
android:id="@+id/pic_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
// 自定义adapter,这个adapter继承ArrayAdapter,并将泛型指定为YYPic类
public class PicAdapter extends ArrayAdapter<YYPic> {
private int resourceId;
public PicAdapter(Context context, int textViewResourceId, List<YYPic> objects) {
super(context, textViewResourceId, objects);
resourceId = textViewResourceId;
}
@NonNull
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// 获取当前项的YYPic 实例
YYPic pic = getItem(position);
// 动态加载布局
View view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
// 显示图片
ImageView imageView = (ImageView)view.findViewById(R.id.pic_item);
imageView.setImageResource(pic.getPicId());
return view;
}
}
优化1:
getView()方法,在每个子选项被滚动到屏幕内的时候被调用。
因此每次滚动屏幕的时候,都会加载布局文件。当快速滑动屏幕时,就会对性能产生影响。
解决方法:
它的第二个参数convertView,主要用于将之前加载好的布局进行缓存,以便以后进行重用。这里就可以对convertView进行判断,如果为空则去加载布局,不为空则直接使用
// getView优化
public View getView(int position, View convertView, ViewGroup parent) {
// 获取当前项的YYPic 实例
YYPic pic = getItem(position);
View view = null;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
} else {
view = convertView;
}
// 显示图片
ImageView imageView = (ImageView)view.findViewById(R.id.pic_item);
imageView.setImageResource(pic.getPicId());
return view;
}
优化2:
每次调用getView()方法时,都会调用View的findViewById()方法来获取一次控件的实例。可以借助ViewHolder来对这部分进行优化。主要的目的是讲控件的实例都缓存到ViewHolder里。
// getView优化
public View getView(int position, View convertView, ViewGroup parent) {
YYPic pic = getItem(position);
View view = null;
ViewHolder viewHolder=null;
if (convertView == null) {
view = LayoutInflater.from(getContext()).inflate(resourceId, parent, false);
viewHolder = new ViewHolder();
viewHolder.picImageView = (ImageView)view.findViewById(R.id.pic_item);
view.setTag(viewHolder);// 将viewHolder存储在view中
} else {
view = convertView;
viewHolder = (ViewHolder)view.getTag();// 重新获取viewHolder
}
viewHolder.picImageView.setImageResource(pic.getPicId());
return view;
}
class ViewHolder{
ImageView picImageView;
}
对列表响应点击事件,只需要使用setOnItemClickListener()方法为ListView注册一个监听器即可。
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
Toast.makeText(CustomListViewActivity.this, "item:"+i, Toast.LENGTH_SHORT).show();
}
});