2013-08-25 5 views
1

Мое приложение требует отображения динамического вложенного списка. Мой внешний список - это серия заданий, и каждое задание содержит список элементов, необходимых для этого. Я использую пользовательские адаптеры для создания динамических вложенных списков. Что-то, как показано ниже:Динамические вложенные списки в android

LineItemCustomListViewAdaptor - загружает элементы данных для одного задания

JobCustomListViewAdaptor - загружает отдельные рабочие места по телефону LineItemCustomListViewAdaptor на каждую работу.

Моя GetView функция JobCustomListViewAdaptor подобна this-

public View getView(int position, View convertView, ViewGroup parent) { 

    LayoutInflater mInflater = (LayoutInflater) context 
      .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
    if (convertView == null) { 
     convertView = mInflater.inflate(R.layout.list_job, parent, false); 
     holder = new ViewHolder(); 
     holder.jobnum = (TextView)convertView.findViewById(R.id.JobNum); // jobID 
     holder.lineitems = (ListView)convertView.findViewById(R.id.list); // lineitems 

     convertView.setTag(holder); 
    } else 
     holder = (ViewHolder) convertView.getTag(); 

    holder.jobnum.setText(job.getJobID()); 
    listviewadapter = new LineItemCustomListViewAdapter(context,R.layout.list_row, job.getLineItem()); 
    holder.lineitems.setAdapter(listviewadapter); 

    return convertView; 
} 

Это работает отлично ДО точки отображения внешнего списка заданий и внутренний список тоже. Но каждая работа внутри только показывает первый элемент продукта, т. Е. Каждая строка внешнего списка показывает только первую строку внутреннего списка.

Может ли кто-нибудь указать, не хватает ли я чего-то или где я ошибаюсь. Любая помощь будет оценена!

Редактировать: Согласно комментарию Баренда, используйте ExpandableListAdapter, чтобы заставить это работать.

Поскольку ExpandableListView добавляет каждый элемент как новую строку в родительских/дочерних группах по мере необходимости, динамическая природа списков не имеет значения. Я сохранил родительский элемент и связанные с ним данные дочерних объектов в объектах ArrayList, которые обрабатываются в расширенном классе адаптера.

public class ExpandableAdapter extends BaseExpandableListAdapter { 

    private Context context; 
    private ArrayList<String> parent; 
    private ArrayList<ArrayList<LineItem>> children; 

    public ExpandableAdapter(Context context, ArrayList<String> parent, 
     ArrayList<ArrayList<LineItem>> children) { 
     this.context = context; 
     this.parent = parent; 
     this.children = children; 
    } 

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

     final LineItem lineitem = (LineItem)getChild(groupPosition, childPosition); 

     if (convertView == null) { 
      LayoutInflater mInflater = (LayoutInflater) context 
       .getSystemService(Activity.LAYOUT_INFLATER_SERVICE); 
       convertView = mInflater.inflate(R.layout.list_row, null); 
     } 

     TextView item; // item 
     TextView desc; // desc 

     item = (TextView)convertView.findViewById(R.id.Item); // item 
     desc = (TextView)convertView.findViewById(R.id.Desc); // desc 

     item.setText(lineitem.getItem()); 
     desc.setText(lineitem.getDesc()); 
     return convertView; 
    } 


    public View getGroupView(int groupPosition, boolean isExpanded, 
     View convertView, ViewGroup parent) { 
    Integer parentnum = Integer.valueOf(groupPosition); 

     String parentcond = (String) getGroup(groupPosition); 
     TextView jobnum; // jobID 
     TextView cond; 

     if (convertView == null) { 
      LayoutInflater infalInflater = (LayoutInflater) context 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
      convertView = infalInflater.inflate(R.layout.list_job, 
       null); 
     }  
     jobnum = (TextView)convertView.findViewById(R.id.JobNum); // jobID 
     cond = (TextView)convertView.findViewById(R.id.Condition); // cond 

     jobnum.setText(parentnum.toString()) 
     cond.setText(parentcond); 
     return convertView; 
    } 

    /// other methods 
} 
+0

Вложенные 'ListViews' вряд ли будут работать хорошо. «ExpandableListView» представляется более практичным решением. – CommonsWare

+0

Hi @CommonsWare - Barend в своем ответе ниже упоминает ExpandableListAdapter как возможный вариант. Я предполагаю, что это потому, что и мои внутренние, и внешние списки являются динамическими. Если бы вы могли взвесить, я бы тоже это оценил. – Sandman

ответ

8

Вы не должны пытаться вложить два вида списка - оба являются прокручиваемыми видами, а UX становится ужасным. Вместо этого вы должны использовать ExpandableListAdapter, который позволяет вам составить список родительских (групповых) и дочерних представлений. На каждую группу может быть несколько детей, поэтому на практике у вас есть вложенные списки, но на самом деле это один ListView.

+0

Привет @ Barend- Большое спасибо за ваш ответ! Как это происходит, мои внутренние и внешние списки здесь динамичны. Так можете ли вы дать мне какие-либо указания или передать какие-либо ссылки, где они могли бы иметь дело со сценарием, подобным этому? Это было бы очень полезно поставить меня на правильный путь. – Sandman

+0

@Sandman: «Как это бывает, и мои внутренние, и внешние списки динамичны здесь» - так? – CommonsWare

+0

@CommonsWare - я, вероятно, не искал правильные слова или поисковые фразы, но когда я искал что-то вроде этого, я сталкивался только с примерами, где они используют ExpandableListAdapter со статическими данными. Я ищу реализацию с использованием расширяемых списков для динамических данных. Я был бы признателен, если бы вы могли указать мне в правильном направлении. – Sandman

0

Вам лучше не встраивать ListView. Этот способ неэффективен.

Вы можете использовать ExpandableListView. Или вы можете использовать проект PreOrderTreeAdapter. Он соответствует вашему случаю и прост в использовании.

Смежные вопросы