【问题标题】:Tree with checkBox带复选框的树
【发布时间】:2018-04-11 10:54:32
【问题描述】:

美好的一天! 有必要创建一个列表树,大致如图所示:

https://joshsmithonwpf.wordpress.com/2008/08/01/article-about-checkboxes-in-a-wpf-treeview/

原谅我,网站本身不允许我插入图片

树由复选框组成,当您单击父级时,复选框会显示/从子元素中删除。除了复选框之外,树的每个元素都有自己的参数(字节数组)。

实际上,需要在按下复选框后(通过单击,比如说,一个按钮)读取复选框的状态,并取值(相同的字节数组),名称,名称选项卡并将其写入另一个数组/列表等。

主要问题是如何创建一个 TreeView,其中子元素的状态取决于父元素,以及如何为它们分配值。

我看到了很多例子,但我没有找到。只是遇到损坏的链接。

我只能自己实现复选框列表,但子元素不会对更改父元素的状态做出反应。

代码如下所示。

ExpandableListAdapter.java

    public class ExpandableListAdapter extends BaseExpandableListAdapter {

    private Context context;
    private List<String> listDataHeader;
    private HashMap<String, List<String>> listDataChild;

    public ExpandableListAdapter(Context context, List<String> listHeaderData, HashMap<String, List<String>> listChildData){
        this.context = context;
        this.listDataHeader = listHeaderData;
        this.listDataChild = listChildData;
    }

    @Override
    public int getGroupCount() {
        return this.listDataHeader.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        return this.listDataChild.get(this.listDataHeader.get(groupPosition)).size();
    }

    @Override
    public Object getGroup(int groupPosition) {
        return this.listDataHeader.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return this.listDataChild.get(this.listDataHeader.get(groupPosition)).get(childPosition);
    }

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

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

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {

        String headerTitle = (String) getGroup(groupPosition);
        if (convertView == null) {
            LayoutInflater infalInflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.layout.group_row, null);
        }

        TextView lblListHeader = (TextView) convertView
                .findViewById(R.id.lblListHeader);
        lblListHeader.setTypeface(null, Typeface.BOLD);
        lblListHeader.setText(headerTitle);

        return convertView;
    }


    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

        final String childText = (String) getChild(groupPosition, childPosition);

        if(convertView == null){
            LayoutInflater inflater = (LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.child_row, null);
        }
        TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);

        txtListChild.setText(childText);

        return convertView;
    }

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

child_row.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="55dip"
    android:layout_marginTop="5dp"
    android:layout_marginLeft="5dp"
    android:layout_marginRight="5dp"
    android:orientation="horizontal">

    <TextView
        android:id="@+id/lblListItem"
        android:layout_width="308dp"
        android:layout_height="match_parent"
        android:paddingBottom="5dp"
        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft"
        android:paddingTop="5dp"
        android:text="asd"
        android:textSize="20dip" />

    <CheckBox
        android:id="@+id/lblListChildCheckbox"
        android:layout_width="72dp"
        android:layout_height="match_parent"
        android:focusable="false"
        android:textSize="17dp" />



</LinearLayout>

group_row.xml

  <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:layout_marginLeft="5dp"
        android:layout_marginRight="5dp"
        android:orientation="horizontal"
        android:padding="8dp">

        <TextView
            android:id="@+id/lblListHeader"
            android:layout_width="306dp"
            android:layout_height="match_parent"
            android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
            android:textSize="20dp" />

        <CheckBox
            android:id="@+id/lblListHeaderCheckbox"
            android:layout_width="50dp"
            android:layout_height="match_parent"
            android:focusable="false"
            android:text=""
            android:textSize="17dp" />

    </LinearLayout>

listings.xml

   <?xml version="1.0" encoding="utf-8"?>

    <LinearLayout xmlns:andoid="http://schemas.android.com/apk/res/android"
        andoid:layout_width="match_parent"
        andoid:layout_height="match_parent"
        andoid:orientation="vertical">

        <Button
            andoid:id="@+id/add_template"
            style="@style/Widget.AppCompat.Button.Colored"
            andoid:layout_width="match_parent"
            andoid:layout_height="wrap_content"
            andoid:layout_gravity="center"
            andoid:layout_marginTop="10dp"
            andoid:text="Добавить шаблон" />

        <ExpandableListView
            andoid:id="@+id/listing"
            andoid:layout_width="match_parent"
            andoid:layout_height="wrap_content"></ExpandableListView>

    </LinearLayout>

Choise_list.java

public class Choise_List extends Activity {

    private Button add_template;

    class Lists{
        String page;
        String name;
        String type;
        byte[] val;
    }

    Context context;

    ExpandableListAdapter listAdapter;
    ExpandableListView expListView;
    HashMap<String, List<String>> listDataChild;
    List<String> pages;

    ArrayList< Map<String, String> > childDataItem = new ArrayList<>();

    List<Lists> structure_list = new ArrayList<>();

    public void createListsList(ArrayList<byte[]> ch_check) throws UnsupportedEncodingException {
        for (int i = 0; i < ch_check.size(); i++){
            if(Arrays.equals( ch_check.get(i), "PAGE".getBytes( Charset.forName("UTF-8") ) ) ){
                Lists lists = new Lists();
                int state = i;
                lists.page = new String( ch_check.get(++state), "UTF-8" );
                lists.name = new String( ch_check.get(++state), "UTF-8" );
                lists.type = new String( ch_check.get(++state), "UTF-8" );
                lists.val = ch_check.get(++state);

                i = state;
                structure_list.add(lists);
            }
        }
    }

    private void prepareListData(){

        HashSet<String> used = new HashSet<>();

        int count = 0;

        pages = new ArrayList<>();
        listDataChild = new HashMap<String, List<String>>();

        for(int i = 0; i < structure_list.size(); i++){
            if(used.contains(structure_list.get(i).page)){
                continue;
            } else {
                used.add(structure_list.get(i).page);
            }

            String new_page_name = "";
            ArrayList<Integer> positions = new ArrayList<>();

            positions.add(i);
            for(int j = i + 1; j < structure_list.size(); j++){

                if(structure_list.get(i).page.equals(structure_list.get(j).page)){
                    positions.add(j);
                }
            }

            childDataItem = new ArrayList<Map<String, String>>();

            List<String> child = new ArrayList<String>();

            for(Integer p : positions){
                new_page_name = structure_list.get(p).page;
                child.add(structure_list.get(p).name);
            }
            pages.add(new_page_name);
            listDataChild.put(pages.get(count), child);
            count++;
        }

    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.listings);


        expListView = (ExpandableListView) findViewById(R.id.listing);

        ArrayList<byte[]> ch_check = new ArrayList<>();

        if(savedInstanceState == null){
            MyObject myObj = (MyObject) getIntent().getParcelableExtra(MyObject.class.getCanonicalName());

            if(myObj == null){
                ch_check = null;
            } else{
                ch_check = myObj.choise;
            }
        }

        if(ch_check != null){

            try {
                createListsList(ch_check);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }

            prepareListData();

            expListView.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE);
            listAdapter = new ExpandableListAdapter(this, pages, listDataChild);
            expListView.setAdapter(listAdapter);

            expListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
                @Override
                public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) {

                    return false;
                }
            });

            expListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
                @Override
                public void onGroupExpand(int groupPosition) {
                    Toast.makeText(getApplicationContext(), pages.get(groupPosition) + " Expanded", Toast.LENGTH_SHORT).show();
                }
            });

            expListView.setOnGroupCollapseListener(new ExpandableListView.OnGroupCollapseListener() {

                @Override
                public void onGroupCollapse(int groupPosition) {
                    Toast.makeText(getApplicationContext(),pages.get(groupPosition) + " Collapsed", Toast.LENGTH_SHORT).show();
                }
            });

            expListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {

                @Override
                public boolean onChildClick(ExpandableListView parent, View v,
                                            int groupPosition, int childPosition, long id) {
                    // TODO Auto-generated method stub
                    Toast.makeText( getApplicationContext(),pages.get(groupPosition) + " : " + listDataChild.get(pages.get(groupPosition)).get( childPosition), Toast.LENGTH_SHORT).show();
                    CheckBox checkBox = (CheckBox) findViewById(R.id.lblListChildCheckbox);
                    checkBox.setChecked(true);
                    checkBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            checkBox.setChecked(isChecked);
                        }
                    });
                    return false;
                }
            });
        }

    }

【问题讨论】:

    标签: android checkbox treeview


    【解决方案1】:

    试试这个示例 :-)

    MainActivity.java:

    public class MainActivity extends AppCompatActivity {
    
    Button clearChecks;
    ExpandableListView mExpandableListView;
    ExpandableListViewAdapter mExpandableListAdapter;
    int mLastExpandedPosition = -1;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        mExpandableListView = (ExpandableListView)findViewById(R.id.expandedListView);
        clearChecks = (Button)findViewById(R.id.btnClearChecks);
    
        List<String> listTitle = genGroupList();
        mExpandableListAdapter = new ExpandableListViewAdapter(this, listTitle, genChildList(listTitle));
        mExpandableListView.setAdapter(mExpandableListAdapter);
    
        mExpandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() {
            @Override
            public void onGroupExpand(int groupPosition) {
                if(mLastExpandedPosition != -1 && (mLastExpandedPosition != groupPosition)){
                    mExpandableListView.collapseGroup(mLastExpandedPosition);
                }
                mLastExpandedPosition = groupPosition;
            }
        });
    
        clearChecks.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                mExpandableListAdapter.clearChecks();
            }
        });
    }
    
    private List<String> genGroupList(){
        List<String> listGroup = new ArrayList<>();
        for(int i=1; i<10; i++){
            listGroup.add("Group: " + i);
        }
        return listGroup;
    }
    
    private Map<String, List<ChildItemSample>> genChildList(List<String> header){
        Map<String, List<ChildItemSample>> listChild = new HashMap<>();
        for(int i=0; i<header.size(); i++){
            List<ChildItemSample> testDataList = new ArrayList<>();
            int a = (int)(Math.random() * 8);
            for(int j=0; j<a; j++){
                ChildItemSample testItem = new ChildItemSample("Child " + (j + 1));
                testDataList.add(testItem);
            }
            listChild.put(header.get(i), testDataList);
        }
        return  listChild;
    }
    
    }
    

    activity_main.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
        <Button
            android:id="@+id/btnClearChecks"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="Clear Checks" />
        <ExpandableListView
            android:id="@+id/expandedListView"
            android:layout_width="match_parent"
            android:layout_height="match_parent">
        </ExpandableListView>
    </LinearLayout>
    

    ChildItemSample.java:

    public class ChildItemSample {
    private boolean checked;
    private String name;
    public boolean isChecked() {
        return checked;
    }
    public void setChecked(boolean checked) {
        this.checked = checked;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public ChildItemSample(){
        checked = false;
        name = "";
    }
    public ChildItemSample(String name){
        checked = false;
        this.name = name;
    }
    }
    

    ExpandableListViewAdapter.java:

    public class ExpandableListViewAdapter extends BaseExpandableListAdapter {
    
    private Context context;
    private List<String> listGroup;
    private Map<String, List<ChildItemSample>> listChild;
    private int checkedBoxesCount;
    private boolean[] checkedGroup;
    
    public ExpandableListViewAdapter(Context context, List<String> listGroup, Map<String,
            List<ChildItemSample>> listChild) {
        this.context = context;
        this.listGroup = listGroup;
        this.listChild = listChild;
        checkedBoxesCount = 0;
        checkedGroup = new boolean[listGroup.size()];
    }
    
    @Override
    public int getGroupCount() {
        return listGroup.size();
    }
    
    @Override
    public int getChildrenCount(int groupPosition) {
        return listChild.get(listGroup.get(groupPosition)).size();
    }
    
    @Override
    public String getGroup(int groupPosition) {
        return listGroup.get(groupPosition);
    }
    
    @Override
    public ChildItemSample getChild(int groupPosition, int childPosition) {
        return listChild.get(listGroup.get(groupPosition)).get(childPosition);
    }
    
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
    
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
    
    @Override
    public boolean hasStableIds() {
        return false;
    }
    
    @Override
    public View getGroupView(int groupPosition, boolean b, View view, ViewGroup viewGroup) {
        String itemGroup = getGroup(groupPosition);
        GroupViewHolder groupViewHolder;
        if(view == null){
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.expanded_list_group, null);
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.tvGroup = view.findViewById(R.id.tv_group);
            groupViewHolder.cbGroup = view.findViewById(R.id.cb_group);
            groupViewHolder.cbGroup.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    int pos = (int)view.getTag();
                    checkedGroup[pos] = !checkedGroup[pos];
                    for(ChildItemSample item : listChild.get(listGroup.get(pos))){
                        item.setChecked(checkedGroup[pos]);
                    }
                    notifyDataSetChanged();
                }
            });
            view.setTag(groupViewHolder);
        }else {
            groupViewHolder = (GroupViewHolder)view.getTag();
        }
        groupViewHolder.tvGroup.setText(String.format("%s (%d)", itemGroup, getChildrenCount(groupPosition)));
        groupViewHolder.cbGroup.setChecked(checkedGroup[groupPosition]);
        groupViewHolder.cbGroup.setTag(groupPosition);
        return view;
    }
    
    @Override
    public View getChildView(final int groupPosition, final int childPosition, boolean b, View view, ViewGroup viewGroup) {
        ChildItemSample expandedListText = getChild(groupPosition,childPosition);
        ChildViewHolder childViewHolder;
        if(view == null){
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate(R.layout.expanded_list_item, null);
            childViewHolder = new ChildViewHolder();
            childViewHolder.tvChild = view.findViewById(R.id.tv_child);
            childViewHolder.cbChild = view.findViewById(R.id.cb_child);
            childViewHolder.cbChild.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    CheckBox cb = (CheckBox) view;
                    ChildItemSample selectedItem = listChild.get(listGroup.get(groupPosition)).get(childPosition);
                    selectedItem.setChecked(cb.isChecked());
                    if(cb.isChecked()){
                        checkedBoxesCount++;
                        Toast.makeText(context,"Checked value is: " +
                                        listChild.get(listGroup.get(groupPosition)).get(childPosition),
                                Toast.LENGTH_SHORT).show();
                    }else {
                        checkedBoxesCount--;
                        if(checkedBoxesCount == 0){
                            Toast.makeText(context,"nothing checked",Toast.LENGTH_SHORT).show();
                        }else {
                            Toast.makeText(context,"unchecked",Toast.LENGTH_SHORT).show();
                        }
                    }
                    notifyDataSetChanged();
                }
            });
            view.setTag(childViewHolder);
        }else {
            childViewHolder = (ChildViewHolder)view.getTag();
        }
        childViewHolder.cbChild.setChecked(expandedListText.isChecked());
        childViewHolder.tvChild.setText(expandedListText.getName());
        return view;
    }
    
    public void clearChecks() {
        for(int i=0; i<checkedGroup.length; i++) checkedGroup[i] = false;
        for(List<ChildItemSample> value : listChild.values()) {
            for (ChildItemSample sample : value) {
                sample.setChecked(false);
            }
        }
        checkedBoxesCount = 0;
        notifyDataSetChanged();
    }
    
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
    
    private class GroupViewHolder {
        CheckBox cbGroup;
        TextView tvGroup;
    }
    
    private class ChildViewHolder {
        CheckBox cbChild;
        TextView tvChild;
    }
    }
    

    expanded_list_group.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:descendantFocusability="blocksDescendants" >
    <CheckBox
        android:id="@+id/cb_group"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="40dp"
        android:layout_gravity="center_vertical"/>
    <TextView
        android:id="@+id/tv_group"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="30sp" />
    </LinearLayout>
    

    expanded_list_item.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <CheckBox
        android:id="@+id/cb_child"
        android:layout_marginLeft="60dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/tv_child"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="20sp" />
    </LinearLayout>
    

    注意:child 的选中状态存储在子类中,而 group 的选中状态存储在适配器内部的数组中。希望对您有所帮助!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-17
      • 1970-01-01
      • 2011-06-20
      • 2016-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多