带有复选框的Expandablelistview显示在对话框

时间:2016-05-08 14:09:59

标签: android checkbox expandablelistview dialogfragment

我正在Android中编写过滤器,并希望将BaseExpandableListAdapter与复选框一起使用。在我的情况下,如果组元素有任何子元素,也可以选择组元素。也可以选择所有子元素。优惠截图: enter image description here

当我打开对话框并选择必要的元素时,其选中的元素将放入文本edittext。我的问题在于,当我重新打开对话框并关闭/打开组元素时,我选择的复选框会发生变化。重新打开对话框时,我找不到解决方案如何记住选择。

我所有必要的代码都提供以下内容:

我的实体类:

public class Category implements Listable, Parcelable{
    private int id;
    private String title;
    private String c_date;
    private List<Category> sub_categories = new ArrayList<>();
    private boolean isChecked;
    private int parent;

protected Category(Parcel in) {
        id = in.readInt();
        title = in.readString();
        c_date = in.readString();
        sub_categories = in.createTypedArrayList(Category.CREATOR);
        isChecked = in.readByte() != 0;
        parent = in.readInt();
        m_date = in.readString();
    }

 public static final Creator<Category> CREATOR = new Creator<Category>() {
        @Override
        public Category createFromParcel(Parcel in) {
            return new Category(in);
        }

        @Override
        public Category[] newArray(int size) {
            return new Category[size];
        }
    };

@Override
    public void writeToParcel(Parcel parcel, int i) {
        parcel.writeInt(id);
        parcel.writeString(title);
        parcel.writeString(c_date);
        parcel.writeTypedList(sub_categories);
        parcel.writeByte((byte) (isChecked ? 1 : 0));
        parcel.writeInt(parent);
        parcel.writeString(m_date);
    }
//getters, setters
}    

我的适配器类:

public class CategoryAdapter extends BaseExpandableListAdapter {

private Context context;
private ArrayList<Category> categories;
private LayoutInflater inflater;

public CategoryAdapter(Context context,
                       ArrayList<Category> categoryList) {
    this.context = context;
    this.categories = categoryList;
    inflater = LayoutInflater.from(context);
}

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

public long getChildId(int groupPosition, int childPosition) {
    return (long)( groupPosition*1024+childPosition );  // Max 1024 children per group
}

private static class ViewHolder {
    private TextView title;
    private CheckBox cb;
}

public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    View v = convertView;
    ViewHolder viewHolder;
    boolean isChecked = categories.get(groupPosition).getSub_categories().get(childPosition).isChecked();
    if (v != null)
        viewHolder = (ViewHolder) v.getTag();
    else {
        v = inflater.inflate(R.layout.category_child_row, parent, false);
        viewHolder = new ViewHolder();
        viewHolder.title = (TextView)v.findViewById(R.id.title);
        viewHolder.cb = (CheckBox)v.findViewById(R.id.check);
        viewHolder.cb.setChecked(isChecked);
        viewHolder.cb.setOnCheckedChangeListener(new CheckchangeChildListener(groupPosition, childPosition));
        v.setTag(viewHolder);
    }

    final Category c = (Category) getChild( groupPosition, childPosition );
    viewHolder.title.setText(c.getTitle());
    return v;
}

class CheckchangeChildListener implements CompoundButton.OnCheckedChangeListener {
    private int position;
    private int childPosition;

    public CheckchangeChildListener(int position, int childPosition) {
        this.position= position;
        this.childPosition = childPosition;
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView,
                                 boolean isChecked) {
        // TODO Auto-generated method stub
        if (isChecked) {
            categories.get(position).getSub_categories().get(childPosition).setChecked(true);
        } else {
            categories.get(position).getSub_categories().get(childPosition).setChecked(false);
        }
    }
}

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

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

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

public long getGroupId(int groupPosition) {
    return (long)( groupPosition*1024 );  // To be consistent with getChildId
}

private static class ViewGroupHolder {
    private TextView title;
    private CheckBox cb;
    private ImageView image;
}

public View getGroupView(final int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    View v = convertView;
    ViewGroupHolder holder;
    boolean isChecked = categories.get(groupPosition).isChecked();
    if(v != null)
        holder = (ViewGroupHolder)v.getTag();
    else {
        v = inflater.inflate(R.layout.category_parent_row, parent, false);
        holder = new ViewGroupHolder();
        holder.title = (TextView)v.findViewById(R.id.title);
        holder.cb = (CheckBox)v.findViewById(R.id.check);
        holder.cb.setChecked(isChecked);
        holder.image = (ImageView)v.findViewById(R.id.arrow);
        holder.cb.setOnCheckedChangeListener(new CheckchangeGroupListener(groupPosition));
        v.setTag(holder);
    }

    final Category category = (Category)getGroup(groupPosition);
    holder.title.setText(category.getTitle());
    if(getChildrenCount(groupPosition) == 0){
        holder.cb.setVisibility(View.VISIBLE);
        holder.image.setVisibility(View.INVISIBLE);
    } else {
        holder.image.setVisibility(View.VISIBLE);
        holder.cb.setVisibility(View.INVISIBLE);
        holder.image.setImageResource(isExpanded ? R.drawable.ic_chevron_down : R.drawable.ic_chevron_right);
    }
    return v;
}

class CheckchangeGroupListener implements CompoundButton.OnCheckedChangeListener {
    private int position;

    public CheckchangeGroupListener(int position) {
        this.position= position;
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView,
                                 boolean isChecked) {
        // TODO Auto-generated method stub
        if (isChecked) {
            categories.get(position).setChecked(true);
        } else {
            categories.get(position).setChecked(false);
        }
    }
}


public boolean hasStableIds() {
    return true;
}

public boolean isChildSelectable(int groupPosition, int childPosition) {
    return true;
}

public void onGroupCollapsed (int groupPosition) {}
public void onGroupExpanded(int groupPosition) {}

public ArrayList<Category> getSelectedCats(){
    ArrayList<Category> checkedCategories = new ArrayList<>();
    for(Category c: categories){
        if(c.isChecked()) checkedCategories.add(c);
        if(!c.getSub_categories().isEmpty()){
            for(Category category: c.getSub_categories()) {
                if (category.isChecked()) checkedCategories.add(category);
            }
        }
    }
    return checkedCategories;
}

}

我的自定义EditText:

public class CategoryEditText<T extends Listable> extends EditText {
    List<T> mItems;
    String[] mListableItems;
    CharSequence mHint;
    OnItemSelectedListener<T> onItemSelectedListener;
    DialogFragment newFragment;

    public CategoryEditText(Context context) {
        super(context);
        mHint = getHint();
    }

    public CategoryEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        mHint = getHint();
    }

    public CategoryEditText(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mHint = getHint();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public CategoryEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        mHint = getHint();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        setFocusable(false);
        setClickable(true);
    }

    public void setItems(List<T> items) {
        this.mItems = items;
        newFragment = CategoryDialogFragment.newInstance((ArrayList<Category>)mItems, this);
        this.mListableItems = new String[items.size()];

        int i = 0;

        for (T item : mItems) {
            mListableItems[i++] = item.getLabel();
        }

        configureOnClickListener();
    }

    private void configureOnClickListener() {
        setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {

                Context context = getContext();
                FragmentManager fm = ((Activity) context).getFragmentManager();
                newFragment.show(fm, "dialog");
            }
        });
    }

    public void setOnItemSelectedListener(OnItemSelectedListener<T> onItemSelectedListener) {
        this.onItemSelectedListener = onItemSelectedListener;
    }

    public interface OnItemSelectedListener<T> {
        void onItemSelectedListener(T item, int selectedIndex);
    }
}

我的自定义dialogfragment显示列表:

public class CategoryDialogFragment extends DialogFragment {

    ArrayList<Category> categories;
    static EditText editText;

    public static CategoryDialogFragment newInstance(ArrayList<Category> categories, EditText customEditText) {
        CategoryDialogFragment frag = new CategoryDialogFragment();
        Bundle args = new Bundle();
        args.putParcelableArrayList("categories", categories);
        frag.setArguments(args);
        editText = customEditText;
        return frag;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        categories = getArguments().getParcelableArrayList("categories");
        View v = LayoutInflater.from(getActivity()).inflate(R.layout.select_category_layout, null);
        ExpandableListView expandableListView = (ExpandableListView) v.findViewById(R.id.list);
        final CategoryAdapter categoryAdapter = new CategoryAdapter(getActivity(), categories);
        expandableListView.setAdapter(categoryAdapter);

        MaterialDialog dialog = new MaterialDialog.Builder(getActivity())
                .title(R.string.shop_category)
                .customView(v, false)
                .positiveText(R.string.select)
                .negativeText(android.R.string.cancel)
                .onPositive(new MaterialDialog.SingleButtonCallback() {
                    @Override
                    public void onClick(@NonNull MaterialDialog materialDialog, @NonNull DialogAction dialogAction) {
                        ArrayList<Category> cats = categoryAdapter.getSelectedCats();
                        String selectedText = "";
                        for(int i=0; i<cats.size(); i++){
                            selectedText += cats.get(i).getTitle();
                            if(i+1 < cats.size()){
                                selectedText += " | ";
                            }
                        }
                        editText.setText(selectedText);
                        materialDialog.dismiss();
                    }
                })
                .build();

        return dialog;
    }
}

我试着在网上阅读,但我没有找到解决问题的方法。

1 个答案:

答案 0 :(得分:0)

问题在于您的getView()方法。我建议阅读如何正确编写列表适配器类。

private static class ViewHolder {
    private TextView title;
    private ChecBbox cb;
}

public View getChildView(final int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    View v = convertView;
    ViewHolder holder;
    boolean isChecked = categories.get(groupPosition).getSub_categories().get(childPosition).isChecked();
    if( convertView != null )
        viewHolder = (ViewHolder) v.getTag();
    else {
        v = inflater.inflate(R.layout.category_child_row, parent, false);
        viewHolder = new ViewHolder();
        holder.title = (TextView)v.findViewById(R.id.title);
        holder.cb = (CheckBox)v.findViewById(R.id.check);
        holder.cb.setChecked(isChecked);
        cb.setOnCheckedChangeListener(new CheckchangeChildListener(groupPosition, childPosition));
        v.setTag(viewHolder);
    }

    final Category c = (Category) getChild( groupPosition, childPosition );
    title.setText(c.getTitle());

    return v;
}

检查已更改的侦听器:

class CheckchangeGroupListener implements CompoundButton.OnCheckedChangeListener {
private int groupPosition, childPosition;

public CheckchangeGroupListener(int groupPosition, int childPosition) {
    this.groupPosition= groupPosition;
    this.childPosition = childPosition;
}

@Override
public void onCheckedChanged(CompoundButton buttonView,
                             boolean isChecked) {
    // TODO Auto-generated method stub
    if (isChecked) {
        categories.get(groupPosition).getSub_categories().get(childPosition).setChecked(true);
    } else {
        categories.get(groupPosition).getSub_categories().get(childPosition).setChecked(false);
    }
}