带有复选框的树 [英] Tree with checkBox

查看:69
本文介绍了带有复选框的树的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Good day! It was necessary to create a list-tree, approximately, as represented in the picture:

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

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

Forgive me for this, the site itself does not allow me to insert the picture

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

The tree consists of a check of the boxes, when you click on the parent, the checkboxes are displayed / removed from the child elements. In addition to the checkboxes, each element of the tree has its own parameter (byte array).

实际上,有必要在按了[]之后读取复选框的状态。复选框(例如单击一个按钮),然后取值(相同的字节数组),名称,选项卡的名称并将其写入另一个数组/列表等。

Actually, it is necessary to read the state of the checkboxes after pressing the checkboxes (by clicking, say, a button), and taking the values ​​(the same array of bytes), the name, the name of the tab and writing it to another array / list, etc.

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

The main question is how to create a TreeView where the state of the child elements depends on the parent and how to assign them, among other things, also the values.

我看到了很多例子,但没有找到。只是碰到了断开的链接。

I saw many examples, but I did not find it. Just come across the broken links.

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

I could implement only the checkbox list on my own, but the child elements do not react to changing the state of the parent.

代码如下所示。

ExpandableListAdapter.java

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

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

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

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

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;
                }
            });
        }

    }


推荐答案

尝试此示例:-)

MainActiivity.java:

MainActiivity.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:

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:

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:

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:

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:

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>

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

Note: The checked state of child is stored inside child class while group's checked state is stored in an array inside adapter. Hope that helps!

这篇关于带有复选框的树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆