具有不同类型的视图android的可扩展ListView

时间:2015-09-02 10:25:57

标签: android expandablelistview

我正在尝试实现Expandable listview,它包含不同类型的视图,例如textview,editboxes和dropdown,如下所示。

Personal Info (Header)
   Name (editbox)
   Gender (spinner)
   Age (editbox)

Address (Header)
   Province (dropdown)
   street (Editbox)
   textview

这是我的适配器代码。 (仅适用于编辑框类型的孩子)

public class ExpandableListAdapter extends BaseExpandableListAdapter implements
    TextWatcher {

private Context _context;
private List<String> _listDataHeader; // header titles
// child data in format of header title, child title
private HashMap<String, List<String>> _listDataChild;
private ArrayList<EditText> editTextList = new ArrayList<EditText>();

String name, purpose;

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

@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this._listDataChild.get(this._listDataHeader.get(groupPosition))
            .get(childPosititon);
}

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

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

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

    String header = _listDataHeader.get(groupPosition);
    System.out.println("Header: " + header);

    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.listitem, null);
    }

    TextView txtListChild = (TextView) convertView
            .findViewById(R.id.lblListItem);
    txtListChild.setText(childText);

    EditText editetext = (EditText) convertView
            .findViewById(R.id.lblListItemEditext);
    editetext.addTextChangedListener(this);
    editTextList.add(editetext);

    return convertView;
}

@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 int getGroupCount() {
    return this._listDataHeader.size();
}

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

@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.listgroup, null);
    }

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

    return convertView;
}

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

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

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
        int after) {
    // TODO Auto-generated method stub

}

@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
    // TODO Auto-generated method stub

}

@Override
public void afterTextChanged(Editable s) {
    // TODO Auto-generated method stub

}
}

截图:

enter image description here

我经历过不同的网站,但我发现只有一种类型的可扩展列表视图的解决方案。

感谢。

3 个答案:

答案 0 :(得分:1)

研究下面的适配器的getView()方法,你可以根据需要设计适配器,

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


    final String childText = (String) getChild(groupPosition, childPosition);
    String header = _listDataHeader.get(groupPosition);
    LayoutInflater infalInflater = (LayoutInflater) this._context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    //If your groups are fixed then we can differentiate using groupPosition otherwise
    // we will have to compare the groupHeader title(which is a bit low performance)

    //Lets say we have three group headers as Personal Info, Contact Detail and Family Info
    // so we know their positions as 0,1 & 2

    switch (groupPosition){
        case 0 :
            //Now lets say we have fixed childViews as First Name, Middle Name, Last Name, Gende and Religion
            //with positions 0,1,2,3,4,5
            switch (childPosition){
                case 0 :
                    convertView = infalInflater.inflate(R.layout.listitem_first_name, null);
                    TextView txtListChild = (TextView) convertView.findViewById(R.id.lblListItem);
                    txtListChild.setText(childText);
                    EditText editetext = (EditText) convertView.findViewById(R.id.lblListItemEditext);
                    editetext.addTextChangedListener(this);
                    editTextList.add(editetext);
                    break;

                case 1 :
                    convertView = infalInflater.inflate(R.layout.listitem_last_name, null);
                    TextView txtListChild2 = (TextView) convertView.findViewById(R.id.lblListItemTextView);
                    txtListChild2.setText(childText);
                    break;

                case 2 :
                    convertView = infalInflater.inflate(R.layout.listitem_gender, null);
                    Spinner genderSpinner = (Spinner) convertView.findViewById(R.id.lblListItemSpinner_);
                    genderSpinner.setSelection(0);              //check for gender and select accordingly
                    break;
            }
            break;

        case 1 :
            // with reference to above case 0 code this
            break;

        case 2 :
            // with reference to above case 0 code this
            break;
    }
    return convertView;
}

这个问题是我没有回收视图,这可能会在滚动时导致性能问题,所以你尝试在适配器内使用viewHolder类,并且在viewHolder的id的帮助下我们可以检查,我们有哪些convertview,并相应地决定重用它的位置。

答案 1 :(得分:0)

您可以通过将不同的适配器(具有不同的视图)组合到一个适配器中来实现此目的。您需要使用 Commons Guy的合并适配器

您可以在此处找到所有信息。希望它有所帮助。

https://github.com/commonsguy/cwac-merge

答案 2 :(得分:0)

我的建议是开发多个布局并根据它们的位置对它们进行充气。这是一些伪代码:

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

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

    String header = _listDataHeader.get(groupPosition);
    System.out.println("Header: " + header);

    if (convertView == null) {
        if(child refers to dropdown layout){
            LayoutInflater infalInflater = (LayoutInflater) this._context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.dropdown_layout, null);

            do code for dropdown
     }
        if(child refers to spinner layout{
            LayoutInflater infalInflater = (LayoutInflater) this._context
            .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = infalInflater.inflate(R.spinner_layout, null);

            do code for spinner
        }
        ... test your other layouts
    }

    return convertView;
}

希望它有所帮助。