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

Expandable ListView with different types of views android

我正在尝试实现可扩展列表视图,它包含不同类型的视图,例如文本视图、编辑框和下拉列表,如下所示 child。

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

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

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

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

}
}

截图:

我浏览了不同的网站,但我找到了仅包含一种视图类型的可扩展列表视图的解决方案。

谢谢。

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

您可以在这里找到所有信息。希望对你有帮助。

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

我的建议是开发多个布局并根据它们的位置膨胀它们。这是一些伪代码:

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

希望对您有所帮助。

学习下面的adapter的getView()方法,你可以随心所欲地设计adapter,

    @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 class 并借助 viewHolder 的 id 我们可以检查,我们有哪个 convertview 并相应地决定在哪里重用它。