Android - ExpandableListView实现Filterable

时间:2012-04-06 16:32:43

标签: android expandablelistview

我正在开发一个Android应用程序,其中包含可扩展的列表视图和顶部的搜索栏。因此,如果我在编辑文本字段中输入任何内容,我希望它过滤可扩展列表。

例如:我在搜索栏中输入“ as ” - >该列表应仅显示以下条目:“ as sert”,“b as e”,“c as e”,“ as sembling“等等。

我在互联网上搜了几个小时,但我无法实现这个功能。 所以我真的希望你能帮助我(:

这是我的可扩展列表适配器:

package my.pack;

public class ExpandableListAdapter extends BaseExpandableListAdapter {

    @Override
    public boolean areAllItemsEnabled() {
        return true;
    }

    private Context context;
    private ArrayList<String> groups;
    private ArrayList<ArrayList<Product>> children;

    public ExpandableListAdapter(Context context, ArrayList<String> groups,
            ArrayList<ArrayList<Product>> children) {
        this.context = context;
        this.groups = groups;
        this.children = children;
    }

    public void addItem(Product product) {
        if (!groups.contains(product.getGroup())) {
            groups.add(product.getGroup());
        }
        int index = groups.indexOf(product.getGroup());
        if (children.size() < index + 1) {
            children.add(new ArrayList<Product>());
        }
        children.get(index).add(product);

    }

    public Object getChild(int groupPosition, int childPosition) {
        return children.get(groupPosition).get(childPosition);
    }

    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    // Return a child view. You can load your custom layout here.

    public View getChildView(int groupPosition, int childPosition,
            boolean isLastChild, View convertView, ViewGroup parent) {
        Product product = (Product) getChild(groupPosition, childPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.productinsertchild,
                    null);
        }
        TextView tv = (TextView) convertView.findViewById(R.id.tvChild);
        tv.setText("   " + product.getpName());

        return convertView;
    }

    public int getChildrenCount(int groupPosition) {
        return children.get(groupPosition).size();
    }

    public Object getGroup(int groupPosition) {
        return groups.get(groupPosition);
    }

    public int getGroupCount() {
        return groups.size();
    }

    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    // Return a group view. You can load your custom layout here.

    public View getGroupView(int groupPosition, boolean isExpanded,
            View convertView, ViewGroup parent) {
        String group = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) context
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.productinsertgroup,
                    null);
        }
        TextView tv = (TextView) convertView.findViewById(R.id.tvGroup);
        tv.setText(group);
        return convertView;
    }

    public boolean hasStableIds() {
        return true;
    }

    public boolean isChildSelectable(int arg0, int arg1) {
        return true;
    }

}

在这里我的活动: 请注意,ExpandableListView从在线mysql服务器获取数据。这就是我使用异步任务的原因。

package activities.shop;

public class ProductInsert extends BaseActivity {

    public static final String phpServerConnection = "url-to-php-file";
    public static final String phpgetGrocery = "url-to-php-file";

    static final int MY_DIALOG_ID = 0;
    protected static AppPreferences appPrefs;
    private getGroceryTask ggt = null;

    private ExpandableListAdapter adapter;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        ExpandableListView listView = (ExpandableListView) findViewById(R.id.listView);

        listView.setOnChildClickListener(new OnChildClickListener() {

            public boolean onChildClick(ExpandableListView arg0, View arg1,
                    int arg2, int arg3, long arg4) {
                Toast.makeText(getBaseContext(), "Child clicked",
                        Toast.LENGTH_LONG).show();
                return false;
            }
        });

        listView.setOnGroupClickListener(new OnGroupClickListener() {

            public boolean onGroupClick(ExpandableListView arg0, View arg1,
                    int arg2, long arg3) {
                return false;
            }
        });

        adapter = new ExpandableListAdapter(this, new ArrayList<String>(),
                new ArrayList<ArrayList<Product>>());

        // Set this blank adapter to the list view
        listView.setAdapter(adapter);

        ggt = new getGroceryTask(this);
        ((getGroceryTask) ggt).execute();

    }

    @Override
    public int getContentViewId() {

        return R.layout.productinsert;
    }

    @Override
    protected Dialog onCreateDialog(int id) {

        ProgressDialog progressDialog = null;

        switch (id) {
        case MY_DIALOG_ID:
            progressDialog = new ProgressDialog(this);
            progressDialog.setMessage("Aktualisieren...");

            break;
        default:
            progressDialog = null;
        }

        return progressDialog;
    }

    final static class getGroceryTask extends
            SuperAsyncTask<String, String, Void> {

        ProductInsert activity;
        InputStream is = null;
        String result = "";

        public getGroceryTask(BaseActivity activity) {

            super(activity, MY_DIALOG_ID); // change your dialog ID here...
            this.activity = (ProductInsert) activity; // and your dialog will be
                                                        // managed
                                                        // automatically!
        }

        @Override
        protected Void doInBackground(String... params) {

            appPrefs = new AppPreferences(activity);

            ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
            nameValuePairs.add(new BasicNameValuePair("uEmail", appPrefs
                    .getUserEmail()));

            try {
                HttpClient httpclient = new DefaultHttpClient();
                HttpPost httppost = new HttpPost(phpgetGrocery);
                httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
                HttpResponse response = httpclient.execute(httppost);
                HttpEntity entity = response.getEntity();
                is = entity.getContent();

            } catch (Exception e) {
                Log.e("log_tag", "Error in http connection " + e.toString());
            }

            // convert response to string
            try {
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(is, "UTF-8"), 8);
                StringBuilder sb = new StringBuilder();
                String line = null;
                while ((line = reader.readLine()) != null) {
                    sb.append(line + "\n");
                }
                is.close();
                result = sb.toString();

            } catch (Exception e) {
                Log.e("log_tag", "Error converting result " + e.toString());
            }

            return null;
        }

        private Product get(int pid, String pName, String pKat) {
            return new Product(pid, pName, pKat);
        }

        @Override
        public void onAfterExecute() {

            try {

                JSONArray jArray = new JSONArray(result);
                for (int i = 0; i < jArray.length(); i++) {

                    JSONObject json_data = jArray.getJSONObject(i);

                    activity.adapter.addItem(get(json_data.getInt("pid"),
                            json_data.getString("pName"),
                            json_data.getString("pKat")));

                }

                activity.adapter.notifyDataSetChanged();

            } catch (JSONException e) {
                Log.e("log_tag", "Error parsing datauuuuuu " + e.toString());

            }
        }

    }

}

2 个答案:

答案 0 :(得分:0)

您可以考虑从CursorTreeAdapter而不是BaseExpandableListAdapter进行扩展 - 这样您就可以覆盖getFilterQueryProvider(并提供您自己的FilterQueryProvider)来查找您正在寻找的功能。当然,这意味着您必须将MySQL数据库中的结果转换为游标,但如果您这样做,则过滤过程会变得更加容易。

否则,您必须覆盖getFilter()并在ListAdapter中提供您自己的Filter - 这并没有太大的不同 - 它有一些更复杂的问题,但您不必添加光标转换层。

在任何情况下,将您自己的textChangedListener添加到过滤器编辑文本以调用过滤器。

答案 1 :(得分:0)

可扩展列表视图的问题在于,如果您有许多与组父项关联的子项,则需要时间....

您可以使用可扩展列表视图中预先填充的项目使用AutoCompleteTextView,以便您可以获得平滑的搜索功能,并允许根据用户选择而不是上述功能刷新列表...您可能会影响使用上述功能的最终用户体验....但是如果你对你的实现如此执着..你可以使用相同的AutoCompleteTextView和onKeyDown功能或textvalidation功能......

查看小工具http://developer.android.com/reference/android/widget/AutoCompleteTextView.html