代码之家  ›  专栏  ›  技术社区  ›  Egor Vasilyev

带复选框的树

  •  0
  • Egor Vasilyev  · 技术社区  · 6 年前

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

    https://joshsmithonwpf.wordpress.com/2008/08/01/article-about-checkboxes-in-a-wpf-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\u行。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\u行。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>
    

    列表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\u列表。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;
                    }
                });
            }
    
        }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   i_A_mok    6 年前

    尝试此示例:-)

    维护活动性。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\u 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;
    }
    }
    

    展开的\u list\u组。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>
    

    展开的\u list\u项。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>
    

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