图片列表视图过滤器
如何在图像列表视图中进行过滤,请加入
引言
在智能手机中,很容易找到一个在列表视图中具有过滤功能的应用程序。 过滤功能将帮助用户轻松找到他想要查看的记录。 但是我们该怎么做呢?
我将提供一个简单的示例来帮助您清除它。
- 显示足球运动员的列表。 每个玩家都将拥有
- 玩家缩略图。
- 玩家姓名。
- 一个编辑文本框,用户可以在其中输入玩家姓名开头的字符。 根据输入的文本,列表将按玩家姓名过滤并显示。
- 例如:如果用户想要查看 Ronaldo,他可以输入 R,然后是 o,...
希望您喜欢它:)
使用代码
准备显示列表视图数据
请参考以下代码来显示列表玩家数据。
public class MainActivity extends Activity {
public ArrayList<FootballPlayer> listDatas = new ArrayList<MainActivity.FootballPlayer>();
public FootballPlayerAdapter adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create dummy data
String[] userNames = new String[] { "Ronaldo", "Zidance", "Cong Vinh",
"Huynh Duc", "Gerrard", "Nagatomo", "Messi", "Minh Phuong",
"neymar" };
int[] playerDrawableResourceIds = new int[] { R.drawable.ronaldo,
R.drawable.zindance, R.drawable.congvinh, R.drawable.huynhduc,
R.drawable.gerrard, R.drawable.nagatomo, R.drawable.messi,
R.drawable.minhphuong, R.drawable.neymar };
// Prepare dummy data
for (int i = 0; i < playerDrawableResourceIds.length; i++) {
FootballPlayer footballPlayer = new FootballPlayer();
footballPlayer.name = userNames[i];
footballPlayer.imageResourceId = playerDrawableResourceIds[i];
listDatas.add(footballPlayer);
}
ListView lv = (ListView) findViewById(R.id.lv);
adapter = new FootballPlayerAdapter();
lv.setAdapter(adapter);
}
private class FootballPlayerAdapter extends BaseAdapter {
@Override
public int getCount() {
return listDatas.size();
}
@Override
public FootballPlayer getItem(int position) {
return listDatas.get(position);
}
@Override
public long getItemId(int position) {
return 0;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
PlayerViewHolder holder;
if (convertView == null) {
convertView = (ViewGroup) LayoutInflater.from(
getApplicationContext()).inflate(
R.layout.football_player_item, null);
holder = new PlayerViewHolder();
holder.name = (TextView) convertView
.findViewById(R.id.player_name);
holder.thumb = (ImageView) convertView
.findViewById(R.id.player_thumbnail);
convertView.setTag(holder);
} else {
holder = (PlayerViewHolder) convertView.getTag();
}
holder.name.setText(getItem(position).name);
holder.thumb.setImageResource(getItem(position).imageResourceId);
return convertView;
}
}
private static class PlayerViewHolder {
public ImageView thumb;
public TextView name;
}
public class FootballPlayer {
/** Keep the id of resource file which is player's thumbnail. */
public int imageResourceId;
/** Player name. */
public String name;
}
}
每个玩家项目的布局football_player_item.xml。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="35dp"
android:orientation="horizontal" >
<ImageView
android:id="@+id/player_thumbnail"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="5dp" />
<TextView
android:id="@+id/player_name"
android:textColor="@android:color/black"
android:layout_width="match_parent"
android:layout_height="35dp"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:ellipsize="end"
android:gravity="center_vertical"
android:maxLines="1"
android:orientation="vertical"
android:singleLine="true"
android:textSize="16sp" />
</LinearLayout>
上面的代码有一些虚拟数据,实际上您必须创建它并保存到可绘制资源文件夹。 对于我来说,没有比从网络下载更容易的方法了:D
int[] playerDrawableResourceIds = new int[] { R.drawable.ronaldo,
R.drawable.zindance, R.drawable.congvinh, R.drawable.huynhduc,
R.drawable.gerrard, R.drawable.nagatomo, R.drawable.messi,
R.drawable.minhphuong, R.drawable.neymar };
这是结果
添加编辑文本以按玩家姓名过滤列表数据
- 当输入文本到编辑文本时,它将自动过滤当前的列表数据。
- 如果编辑文本为空,则显示完整列表
要过滤列表,除了 ArrayList<FootballPlayer> listDatas
用作适配器数据之外,创建一个备份数据列表 ArrayList<FootballPlayer> listBackupDatas
。
// Prepare dummy data
for (int i = 0; i < playerDrawableResourceIds.length; i++) {
FootballPlayer footballPlayer = new FootballPlayer();
footballPlayer.name = userNames[i];
footballPlayer.imageResourceId = playerDrawableResourceIds[i];
listDatas.add(footballPlayer);
listBackupDatas.add(footballPlayer);
}
将编辑文本添加到主布局,输入过滤文本将在其中。
EditText filterText = (EditText) findViewById(R.id.filter_text);
filterText .addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int arg1, int arg2,
int arg3) {
adapter.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence arg0, int arg1,
int arg2, int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
}
});
上面的代码意味着,我们将控制filter
编辑文本何时更改。 如果发生更改,我们将在player adapter
中调用filter
函数。
adapter.getFilter().filter(s.toString());
PlayerFilter
类将按如下方式实现
private class PlayerFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
// We implement here the filter logic
ArrayList<FootballPlayer> filters = new ArrayList<FootballPlayer>();
if (constraint == null || constraint.length() == 0) {
// No filter implemented we return all the list
for (FootballPlayer player : listBackupDatas) {
filters.add(player);
}
results.values = filters;
results.count = filters.size();
} else {
// We perform filtering operation
for (FootballPlayer row : listBackupDatas) {
if (((FootballPlayer) row).name.toUpperCase().startsWith(
constraint.toString().toUpperCase())) {
filters.add(row);
}
}
results.values = filters;
results.count = filters.size();
}
return results;
}
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
if (results.count == 0) {
listDatas.clear();
adapter.notifyDataSetChanged();
} else {
listDatas.clear();
ArrayList<FootballPlayer> resultList = (ArrayList<FootballPlayer>) results.values;
for (FootballPlayer row : resultList) {
listDatas.add(row);
}
adapter.notifyDataSetChanged();
}
}
}
performFiltering
当filterText
的onTextChanged
的回调时,将调用此方法。
filterText
的输入文本是参数constraint
。- 基于
constraint
文本,将返回合适的数据。
通过此示例,它将在listBackupDatas
中找到姓名以constraint
开头的玩家,并添加到数组列表中。
该方法的返回数据是一个 FilterResults
对象。 它包含
-
values
:包含name
以constraint
文本开头的玩家的arraylist。 -
count
:上述arraylist的数量。
publishResults
调用此方法以将过滤器结果通知给UI线程。 使用此示例
- 如果从
performFiltering
返回的数据,则列表视图listDatas
的数据将被清除,并且adapter.notifyDataSetChanged()
。 在这种情况下,列表当然将为空。 - 否则,基于从
performFiltering
方法返回的FilterResults
,将FilterResults
.values
的所有玩家添加到adapter.listDatas
,然后调用adapter.notifyDataSetChanged()
以刷新列表视图。
最终结果如下
关注点
根据我的经验,如果对于每个过滤器列表,我们创建两个列表数据,一个用于显示,另一个用于备份,那就更好了。 这将有助于轻松控制。 在此示例中,它们是
public ArrayList<FootballPlayer> listDatas = new ArrayList<MainActivity.FootballPlayer>();
public ArrayList<FootballPlayer> listBackupDatas = new ArrayList<MainActivity.FootballPlayer>();
listDatas
将用作适配器的主要数据。 它的数据将在过滤时更改。-
listBackupDatas
用作备份数据。
有关更多信息,您可以使用此技巧中的编辑文本,以获得带有搜索图标的编辑文本。:)
历史
- 2013 - 08 - 11:第一个版本。