【问题标题】:ListView filtering with ArrayAdapter使用 ArrayAdapter 进行 ListView 过滤
【发布时间】:2012-07-25 23:12:59
【问题描述】:

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

}

【问题讨论】:

标签: android arrays listview filter


【解决方案1】:

按照您的做法使用 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();
      }
    }
  };

至少,提供您自己的过滤器可能有助于调试。另外,我可以想象提供一个过滤器,对包名称和标签进行正则表达式搜索。

【讨论】:

  • setTextFilterEnabled 即使被注释掉也不起作用。我可能会再次尝试getfilter,但我不能期待太多:(
  • ApplicationInfo.toString() 返回什么?如果它没有返回包装标签,您可能会根据您的想法进行过滤。
  • 其实是一个列表。在主帖中编辑
  • adapter.toString() 返回 07-27 11:01:13.106: E/TAG(395): com.example.androidtablayout.AppInfoAdapter@44f621d8
  • 重要的是 ApplicationInfo.toString 返回类似“ApplicationInfo{
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 2011-09-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多