我正试图让我的列表视图使用搜索框来过滤列表视图中已安装的应用程序。我尝试过各种方法,比如重写toString()方法和重写getFilter()方法,但似乎都不起作用。
主要活动:
public class AllApplicationsActivity extends Activity {
private ListView mListAppInfo;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// set layout for the main screen
setContentView(R.layout.layout_main);
// load list application
mListAppInfo = (ListView)findViewById(R.id.lvApps);
EditText search = (EditText)findViewById(R.id.EditText01);
mListAppInfo.setTextFilterEnabled(true);
// create new adapter
final AppInfoAdapter adapter = new AppInfoAdapter(this, Utilities.getInstalledApplication(this), getPackageManager());
// set adapter to list view
mListAppInfo.setAdapter(adapter);
search.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before,
int count) {
Log.e("TAG", "ontextchanged");
adapter.getFilter().filter(s); //Filter from my adapter
adapter.notifyDataSetChanged(); //Update my view
}
});
// implement event when an item on list view is selected
mListAppInfo.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView parent, View view, int pos, long id) {
// get the list adapter
AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
// get selected item on the list
ApplicationInfo appInfo = (ApplicationInfo)appInfoAdapter.getItem(pos);
// launch the selected application
//Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
Utilities.getPermissions(parent.getContext(), getPackageManager(), appInfo.packageName);
//Toast.makeText(MainActivity.this, "You have clicked on package: " + appInfo.packageName, Toast.LENGTH_SHORT).show();
}
});
}
}
AppInfoAdapter
public class AppInfoAdapter extends ArrayAdapter<ApplicationInfo> {
private Context mContext;
PackageManager mPackManager;
public AppInfoAdapter(Context c, List<ApplicationInfo> list, PackageManager pm) {
super(c, 0, list);
mContext = c;
mPackManager = pm;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// get the selected entry
ApplicationInfo entry = (ApplicationInfo) getItem(position);
Log.e("TAG", entry.toString());
// reference to convertView
View v = convertView;
// inflate new layout if null
if(v == null) {
LayoutInflater inflater = LayoutInflater.from(mContext);
v = inflater.inflate(R.layout.layout_appinfo, null);
}
// load controls from layout resources
ImageView ivAppIcon = (ImageView)v.findViewById(R.id.ivIcon);
TextView tvAppName = (TextView)v.findViewById(R.id.tvName);
TextView tvPkgName = (TextView)v.findViewById(R.id.tvPack);
// set data to display
ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
tvAppName.setText(entry.loadLabel(mPackManager));
tvPkgName.setText(entry.packageName);
// return view
return v;
}
}
附加
public static List<ApplicationInfo> getInstalledApplication(Context context) {
PackageManager packageManager = context.getPackageManager();
List<ApplicationInfo> apps = packageManager.getInstalledApplications(0);
Collections.sort(apps, new ApplicationInfo.DisplayNameComparator(packageManager));
return apps;
}
使用TextWatcher应该可以。您可以尝试不调用setTextFilterEnabled,因为这将导致列表设置自己的过滤器,当列表具有焦点时,该过滤器将工作。
我的猜测是ApplicationInfo.toString()返回的不是您在列表中显示的内容。由于默认的ArrayAdapter筛选器在每个项上都与getString()匹配,因此您可能会针对一些意外的内容进行筛选。
您可以通过使用包装器对象并重写toString()来解决这个问题,或者构建自己的过滤器。
@Override
public Filter getFilter() {
return mFilter;
}
private final Filter mFilter = new Filter() {
@Override
protected FilterResults performFiltering(CharSequence charSequence) {
FilterResults results = new FilterResults();
if (charSequence == null) {
return results;
}
// snip
results.values = /* snip */
results.count = /* snip */
return results;
}
@Override
protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
if (filterResults != null) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
};
至少,提供自己的过滤器可能有助于调试。此外,我可以想象提供一个过滤器,对包名称和标签进行正则表达式搜索。