在应用程序开发中,ListView是最常用的控件之一。它可以用来显示大量的数据,比如联系人列表、音乐播放列表等等。当你需要在这些数据中查找、排列、筛选时,排序功能就变得非常重要了。在这篇文章中,我们将介绍如何在ListView中实现排序功能,包括如何创建一个自定义的ListAdapter,并使用它来对ListView进行排序。
Part 1:ListView简介
在开始介绍排序之前,我们先来简单介绍一下ListView。ListView是一个可以垂直滚动的列表控件,在它的Item中可以显示任意的View。回顾一下Android的基本组件,我们知道列表控件主要包含三个元素:Adapter、Item和LayoutManager。其中,Adaptor是ListView显示数据的重要组成部分,Item 用来显示列表项,LayoutManager 则负责布局控制。
ListView的工作原理很简单,当数据集合改变时,Adaptor 会自动调用自己的notifyDataSetChanged()方法来更新 ListView 中的数据项。当某个 Item 超过了 ListView 显示范围之后,它就被回收并放入“复用池”中。接着,再从“复用池”中获取一个 Item 去显示下一个数据项。这种方式不仅提高了列表的性能,而且减少了内存的开销,这点非常重要。
Part 2:如何实现排序功能
在实现ListView排序功能时,需要完成以下步骤:
1. 创建一个自定义 Adaptor,并在其构造函数中将数据集合传递进来。
2. 在 getView() 方法中根据不同的排序条件做出不同的处理,最后返回一个 View 对象。
3. 在 Activity 中使用自定义 Adaptor,并在排序按钮的点击事件回调函数中调用自定义 Adaptor 的排序方法,然后 ListView 会自动更新列表项。
下面我们就针对这三个步骤一一进行讲解。
2.1 创建 Adapter
在我们自己的 Adaptor 中,我们需要实现 getView() 和 getCount() 两个方法,其中 getView()方法是用来渲染每个 Item 。在 getView() 方法中,在判断要显示的数据集合基础上,我们根据不同的排序条件来渲染视图。
```
public class CustomAdapter extends BaseAdapter {
List
LayoutInflater mInflater;
int sortingType = 0;
public CustomAdapter(Context context, List
mDatas.addAll(datas);
mInflater = LayoutInflater.from(context);
}
public void sort(int type) {
sortingType = type;
if (type == 0) {
Collections.sort(mDatas);
} else if (type == 1) {
Collections.sort(mDatas, Collections.reverseOrder());
}
notifyDataSetChanged();
}
@Override
public int getCount() {
return mDatas.size();
}
@Override
public Object getItem(int i) {
return mDatas.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder holder;
if (view == null) {
view = mInflater.inflate(R.layout.list_item, viewGroup, false);
holder = new ViewHolder();
holder.textView = view.findViewById(R.id.text);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
String item = mDatas.get(i);
holder.textView.setText(item);
if (sortingType == 0) {
view.setBackgroundResource(R.drawable.red_selector);
} else if (sortingType == 1) {
view.setBackgroundResource(R.drawable.green_selector);
}
return view;
}
class ViewHolder {
TextView textView;
}
}
```
在代码中,我们首先定义了一个 List
关于 ViewHolder 模式,如果不了解也无妨,我们可以理解为此模式是为了避免频繁创建控件的情况下重复消耗内存。在每次渲染新的 Item 时,我们先通过 view.findViewById() 来找到 Item 中的textView,并且将该对象与当前的view绑定在一起,避免了反复调用findViewById() 方法的情况。显然,这种做法将大大提高程序的效率。
2.2 调用 Adapter 的排序方法
实现自定义 Adapter 后,我们就需要在Activity 的布局文件中添加一个ListView,再在 Activity 中重写 onCreate() 方法,并实例化 ListView 以及自定义 Adaptor。使用 Adaptor 排序非常简单,只需要在按钮的点击事件中调用 Adaptor 的 sort() 方法即可。
```
public class MainActivity extends AppCompatActivity {
ListView listView;
List
CustomAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.list_view);
dataList.add("Apple");
dataList.add("Orange");
dataList.add("Banana");
dataList.add("Watermelon");
dataList.add("Peach");
adapter = new CustomAdapter(this, dataList);
listView.setAdapter(adapter);
findViewById(R.id.sort_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
adapter.sort(0);
}
});
}
}
```
可以看出,在Activity 类中,我们先定义一个数据集合 dataList 用来存储需要显示的数据。接着,我们在 onCreate() 方法中实例化自定义 Adapter 并传入 context 和 dataList,最后将 Adapter 和 ListView 实例进行绑定。为了完成排序功能的实现,我们在按钮的点击事件中调用 Adapter 的 sort() 方法,这个方法根据传入的排序方式进行排序,然后通过 notifyDatasetChanged() 方法向Adapter 提交数据集合已经发生了变化。
至此,我们已经成功实现了对ListView进行升序排序功能。
接下来我们再补充一下如何实现降序排序功能,跟升序类似。刚才已经讲过,当sortingType 为0表示升序,为1表示降序。因此我们只要再添加一个排序按钮,并且在点击事件中将 sortingType 设为1即可,代码如下:
```
findViewById(R.id.sort_by_desc_button).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
adapter.sort(1);
}
});
```
这样,我们的升序和降序排序功能就都已经实现了。
总结
本文主要介绍了如何在ListView中实现排序功能。通过自定义 Adapter,并在其中实现Adaptor 的 getView() 和 getCount() 方法,根据不同的排序条件来渲染视图。最后,我们通过在Activity中调用 Adaptor 的方法,结合界面事件来实现排序功能。相比于ListView自带的排序方式,自定义Adapter 的方法不仅更加灵活,同时代码的可重用性也更高。通常情况下,我们都会使用自定义Adapter 来实现复杂的列表,这样做不仅使程序结构更加清晰、易维护,还能增强用户体验。