Кастомный ExpandableListView

Интерфейс, диалоги, темы, стили, меню
Ответить
popoc
Сообщения: 12
Зарегистрирован: 16 апр 2016, 13:55

Кастомный ExpandableListView

Сообщение popoc » 09 май 2016, 10:48

День добрый.

Пытаюсь реализовать свой ExpandableListView.

Цель - сделать трехуровневый список для выбора стран и регионов.

Структура примерно такая:
-Европа
--Польша
--Германия
---Центральная
---Северная
-Азия
--Китай
--Япония

У стран и их частей (у центр Цермании, у самой Германии и тд) должны быть чекбоксы. Причем, при выборе целой страны, её регионы отмечаются автоматически.

Я написал два своих адаптера.
Получается два ExpandableListView вложенных друг в друга - один отвечает за список регионов, второй - за список стран и их частей.

В макетах стран и регионов находится RelativeLayout с одним TextView.

Адаптер для регионов:

Код: Выделить всё

public class RegionsAdapter extends BaseExpandableListAdapter {
 
    private List<Object> objects;
    private Activity activity;
    private LayoutInflater inflater;
 
    public RegionsAdapter(Activity activity, List<Object> objects) {
        this.objects = objects;
        this.activity = activity;
        this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
 
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return objects.get(groupPosition).getObjects().get(childPosition);
    }
 
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
 
    @Override
    public View getChildView(int groupPosition, int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {
 
        Object object = (Object) getChild(groupPosition, childPosition);
        CustomExpandableListView subObjects = (CustomExpandableListView) convertView;
 
        if (convertView == null) {
            subObjects = new CustomExpandableListView(activity);
        }
        CountriesAdapter adapter = new CountriesAdapter(activity, object);
        subObjects.setAdapter(adapter);
 
        return subObjects;
    }
 
    @Override
    public int getChildrenCount(int groupPosition) {
        return objects.get(groupPosition).getObjects().size();
    }
 
    @Override
    public Object getGroup(int groupPosition) {
        return objects.get(groupPosition);
    }
 
    @Override
    public int getGroupCount() {
        return objects.size();
    }
 
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
 
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
 
        Object object = (Object) getGroup(groupPosition);
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.layout_region_item, null);
        }
 
        TextView name = (TextView) convertView.findViewById(R.id.name);
        name.setText(object.getName());
 
        return convertView;
    }
 
    @Override
    public boolean hasStableIds() {
        return true;
    }
 
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}
Адаптер для стран и их частей:

Код: Выделить всё

public class CountriesAdapter extends BaseExpandableListAdapter {
 
    private Object object;
    private LayoutInflater inflater;
    private Activity activity;
 
    public CountriesAdapter(Activity activity, Object object) {
        this.activity = activity;
        this.object = object;
        this.inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }
 
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return object.getObjects().get(childPosition);
    }
 
    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }
 
    @Override
    public View getChildView(int groupPosition, int childPosition,
                             boolean isLastChild, View convertView, ViewGroup parent) {
 
        Object object = (Object) getChild(0, childPosition);
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.layout_country_item, null);
 
            Resources r = activity.getResources();
            float px40 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, r.getDisplayMetrics());
            convertView.setPadding(
                    convertView.getPaddingLeft() + (int) px40,
                    convertView.getPaddingTop(),
                    convertView.getPaddingRight(),
                    convertView.getPaddingBottom());
        }
 
        TextView name = (TextView) convertView.findViewById(R.id.name);
        name.setText(object.getName());
 
        return convertView;
    }
 
    @Override
    public int getChildrenCount(int groupPosition) {
 
        if (object.getObjects() == null) {
            return 0;
        }
        return object.getObjects().size();
    }
 
    @Override
    public Object getGroup(int groupPosition) {
        return object;
    }
 
    @Override
    public int getGroupCount() {
        return 1;
    }
 
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }
 
    @Override
    public View getGroupView(int groupPosition, boolean isExpanded,
                             View convertView, ViewGroup parent) {
 
        if (convertView == null) {
            convertView = inflater.inflate(R.layout.layout_country_item, null);
            Resources r = activity.getResources();
            float px20 = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 20, r.getDisplayMetrics());
            convertView.setPadding(
                    convertView.getPaddingLeft() + (int) px20,
                    convertView.getPaddingTop(),
                    convertView.getPaddingRight(),
                    convertView.getPaddingBottom());
        }
 
        TextView name = (TextView) convertView.findViewById(R.id.name);
        name.setText(object.getName());
 
        return convertView;
    }
 
    @Override
    public boolean hasStableIds() {
        return true;
    }
 
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}
И свой ExpandableListView:

Код: Выделить всё

public class CustomExpandableListView extends ExpandableListView {
 
    public CustomExpandableListView(Context context) {
        super(context);
    }
 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        widthMeasureSpec = MeasureSpec.makeMeasureSpec(960, MeasureSpec.AT_MOST);
        heightMeasureSpec = MeasureSpec.makeMeasureSpec(600, MeasureSpec.AT_MOST);
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }
}
Выглядит все это как-то так:
Изображение Изображение

Проблема в том, что если я заменю в макете стран TextView на CheckBox, и присвою этому CheckBox текст, то список стран перестанет раскрываться. Я не понимаю почему так происходит, может кто объяснить?

И ещё, не могу понять почему мой итоговый список не хочет разворачиваться на весь экран по вертикали - использует только где-то треть (на первом скрине видно, что нижние элементы исчезли).

Аватара пользователя
Foenix
Сообщения: 4201
Зарегистрирован: 20 окт 2012, 12:01

Re: Кастомный ExpandableListView

Сообщение Foenix » 09 май 2016, 22:11

ничего не вижу, но полагаю, что чекбокс ловит нажатия, а тебе надо перенаправить их на внешний лэйаут.
R.id.team

NullPointerException - что делать???
viewtopic.php?f=33&t=3899&p=28952#p28952
Где моя ошибка?
viewtopic.php?f=60&t=3198

Ответить