我有一个listview,可以加载设备上所有已安装的应用程序。我想过滤listview的结果,以便用户可以通过键入其名称而不是滚动列表视图来查找应用程序。但我不知道如何实现这个,因为我使用的是自定义适配器。感谢您提前提出任何建议。
ListView Activity使用异步任务加载所有应用
class loadList extends AsyncTask<String, String, String> {
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
loadinglayout.setVisibility(View.VISIBLE);
lockbutton.setEnabled(false);
}
@Override
protected String doInBackground(String... params) {
// TODO Auto-generated method stub
parent = getActivity().getBaseContext();
final PackageManager packageManager = parent.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resInfos = packageManager.queryIntentActivities(
intent, 0);
HashSet<String> packageNames = new HashSet<String>(0);
appInfos = new ArrayList<ApplicationInfo>(0);
for (ResolveInfo resolveInfo : resInfos) {
if ((resolveInfo.activityInfo.packageName.toString())
.equals("com.mypackage")) {
continue;
} else {
packageNames.add(resolveInfo.activityInfo.packageName);
}
}
for (String packageName : packageNames) {
try {
appInfos.add(packageManager.getApplicationInfo(packageName,
PackageManager.GET_META_DATA));
} catch (NameNotFoundException e) {
// Do Nothing
}
}
Collections.sort(appInfos,
new ApplicationInfo.DisplayNameComparator(packageManager));
return null;
}
@Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
adapter = new ApkAdapter(getActivity().getApplicationContext(),
R.layout.apklist_item, appInfos);
loadinglayout.setVisibility(View.GONE);
lView.setAdapter(adapter);
lockbutton.setEnabled(true);
}
}
我的适配器
public class ApkAdapter extends ArrayAdapter<ApplicationInfo> {
private List<ApplicationInfo> appsList = null;
private Context context;
private PackageManager packageManager;
DataBaseHandler handler;
String[] LockedApps;
Typeface fontFamily = Typeface.createFromAsset(getContext().getAssets(),
"fontawesome-webfont.ttf");
public ApkAdapter(Context context, int textViewResourceId,
List<ApplicationInfo> appsList) {
super(context, textViewResourceId, appsList);
this.context = context;
this.appsList = appsList;
packageManager = context.getPackageManager();
handler = new DataBaseHandler(getContext());
try {
handler.open();
LockedApps = handler.getPackages();
handler.close();
} catch (Exception E) {
LockedApps = null;
System.out.println("in constructor exception");
}
}
@Override
public int getCount() {
return ((null != appsList) ? appsList.size() : 0);
}
@Override
public ApplicationInfo getItem(int position) {
return ((null != appsList) ? appsList.get(position) : null);
}
@Override
public long getItemId(int position) {
return position;
}
public boolean isEnabled(int position) {
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
if (null == view) {
LayoutInflater layoutInflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = layoutInflater.inflate(R.layout.apklist_item, null);
}
final ApplicationInfo data = appsList.get(position);
if (position % 2 == 0) {
view.setBackgroundColor(Color.parseColor("#fafafa"));
} else {
view.setBackgroundColor(Color.parseColor("#eeeeee"));
}
if (null != data) {
final TextView appName = (TextView) view
.findViewById(R.id.app_name);
TextView packageName = (TextView) view
.findViewById(R.id.app_package);
final TextView lockstatus = (TextView) view
.findViewById(R.id.lock_status);
ImageView iconview = (ImageView) view.findViewById(R.id.app_icon);
appName.setTypeface(fontFamily);
appName.setTextColor(Color.BLACK);
appName.setText(data.loadLabel(packageManager));
packageName.setText(data.packageName);
lockstatus.setTypeface(fontFamily);
try {
if (Arrays.asList(LockedApps).contains(
data.packageName.toString())) {
lockstatus.setText("\uf205");
} else if (LockedApps == null) {
lockstatus.setText("\uf204");
} else {
lockstatus.setText("\uf204");
}
} catch (Exception E) {
lockstatus.setText("\uf204");
}
lockstatus.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) { // TODO Auto-generated method stub
if (lockstatus.getText().toString().equals("\uf204")) {
handler.open();
handler.insertPackage(data.packageName.toString());
LockedApps = handler.getPackages();
handler.close();
Toast.makeText(
getContext(),
appName.getText().toString()
+ " has been locked",
Toast.LENGTH_SHORT).show();
lockstatus.setText("\uf205");
} else if (lockstatus.getText().toString().equals("\uf205")) {
handler.open();
handler.deletePackage("'" + data.packageName.toString()
+ "'");
LockedApps = handler.getPackages();
handler.close();
Toast.makeText(
getContext(),
appName.getText().toString()
+ " has been unlocked",
Toast.LENGTH_SHORT).show();
lockstatus.setText("\uf204");
}
}
});
iconview.setImageDrawable(data.loadIcon(packageManager));
}
return view;
}
};
答案 0 :(得分:0)
这可以实现。你必须根据你的搜索键盘过滤掉数据并调用相同的片段或活动。它将重建视图。
答案 1 :(得分:0)
ArrayAdapter
已经支持过滤。但是,它内置逻辑会在toString()
对象上调用ApplicationInfo
并在其上执行startsWith(String search_criteria)
。如果这适合你,那么你所要做的就是打电话:
adapter.getFilter().filter(search_string);
过滤器将处理更新适配器和ListView
。通常,您将实现一个SearchView,它将处理用户输入的String并调用适配器上的getFilter()
。但是,这不是一项要求
如果ArrayAdapter
过滤逻辑对您不起作用,那么您可以实现BaseAdapter
而不是ArrayAdapter
类,并从头开始编写自己的过滤器和适配器。或者您可以使用third party library,它允许您轻松实现逻辑,而无需从头开始编写整个适配器。
附注,您无需在null
和getCount
方法中进行getItem
检查。如果您看到null
出现,则表示您做错了。
答案 2 :(得分:0)
你需要创建一个扩展filter.try的类,我已经将它用于我的一个项目。我认为它与你的代码相匹配。在适配器文件中的View GetView()下添加appfilter类。
private class AppFilter extends Filter {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
// TODO Auto-generated method stub
constraint = constraint.toString().toLowerCase();
FilterResults result = new FilterResults();
if (constraint != null && constraint.toString().length() > 0) {
List<ApplicationInfo> filteredItems = new ArrayList<ApplicationInfo>();
for (int i = 0, l = appsList.size(); i < l; i++) {
ApplicationInfo data = appsList.get(i);
String name = data.loadLabel(packageManager).toString();
if (name.toLowerCase().contains(constraint)) {
filteredItems.add(data);
}
}
result.count = filteredItems.size();
result.values = filteredItems;
} else {
synchronized (this) {
result.values = appsList;
result.count = appsList.size();
}
}
return result;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint,
FilterResults results) {
// TODO Auto-generated method stub
appsList = (ArrayList<ApplicationInfo>) results.values;
notifyDataSetChanged();
clear();
for (int i = 0; i < appsList.size(); i++)
add(appsList.get(i));
notifyDataSetInvalidated();
}
}
您还需要初始化并覆盖过滤器类的构造函数
private AppFilter filter;
@Override
public Filter getFilter() {
if (filter == null) {
filter = new AppFilter();
}
return filter;
}
并在主列表文件中
searchtext.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
// TODO Auto-generated method stub
adapter.getFilter().filter(s.toString());
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
答案 3 :(得分:0)
我遇到过这个图书馆。 https://github.com/bhavyahmehta/ListviewFilter 我认为它会解决你的目的。