0

我试图让我的列表视图与搜索框一起使用,以过滤掉列表视图中已安装的应用程序。我尝试了各种方法,例如覆盖 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();
            }
        });


    }
}

应用信息适配器

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;

}
4

1 回答 1

1

Using a TextWatcher as you've done it should work. You might try not calling setTextFilterEnabled, since that will cause the list to set up it's own filter that will work when the list has focus.

My guess is that ApplicationInfo.toString() is returning something other than what you are displaying in the list. Since the default ArrayAdapter filter matches against getString() on each item, you might be filtering against something unexpected.

You could solve this by using a wrapper object and overriding toString(), or build your own filter.

  @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();
      }
    }
  };

At the very least, providing your own filter might help with debugging. Also, I could imagine providing a filter that does a regex search on the package name and label.

于 2012-07-27T10:26:20.073 回答