Listview с двумя разными макетами - PullRequest
0 голосов
/ 27 мая 2011

Приложение вылетает после нескольких секунд прокрутки в просмотре списка.

 String[] names = new String[] {"Cook","2/Person/15/5","Cashier","2/Person/15/5"};
 @Override
 public View getView(int position, View convertView, ViewGroup parent) {


        ViewHolder holder;
        View rowView = convertView;
        LayoutInflater inflater =(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        String[] info = names.get(position).split("/");

        if (rowView == null) {

                if (info.length != 1) {
                    rowView = inflater.inflate(R.layout.employee, null, true);
                    holder = new ViewHolder();
                    holder.name = (TextView) rowView.findViewById(R.id.name);
                    holder.money= (TextView) rowView.findViewById(R.id.money);
                    holder.rating = (RatingBar) rowView.findViewById(R.id.rating);
                    rowView.setTag(holder);
                }else{
                    rowView = inflater.inflate(R.layout.lable, null, true);
                    holder = new ViewHolder();
                    holder.lable = (TextView) rowView.findViewById(R.id.name);

                    rowView.setTag(holder);
                }


            }

        holder = (ViewHolder) rowView.getTag();


        if (holder.lable==null) {
            holder.name.setText(info[1]);
            holder.money.setText(info[2]);
            holder.rating.setRating(Float.valueOf("1"));
        }else{
            holder.lable.setText(names.get(position));
        }

        //}



        return rowView;
    }

Ответы [ 3 ]

3 голосов
/ 27 сентября 2011

Так как вы используете шаблон Viewholder и перезапускаете представления, вы в итоге получаете беспорядок. Это связано с тем, что в вашем списке есть два разных вида представлений, и когда вы получите convertview, это будет одно из этих представлений.

Представьте набор данных A с компоновкой / представлением a и такой же для B b

(- B- означает, что пока не отображается на экране) Таким образом, если ваш начальный список Aa, Bb, Bb, Aa, -B-, -B- и вы прокручиваете, чтобы внести данные B в список ... Тогда вы получите конвертированное представление с макетом или макет ИЛИ b, таким образом, не имея возможности Надежно использовать convertview.

Я занимаюсь поиском способа поддержки различных представлений в ListView и в то же время использую шаблон convertView / viewHolder. До сих пор я нашел этот вариант интересным: https://github.com/commonsguy/cwac-merge#readme

То, что вы хотите сделать, это переопределить getItemViewType (position). Вот пример. Конечно, у вас есть dataTypes вместо MoreResultsLoader и YPContact.

@Override
public int getItemViewType(int position) {

    if (resultsList.get(position) instanceof MoreResultsLoader) {
        return VIEW_TYPE_MORE_RESULTS_LOADER;
    }
    if (resultsList.get(position) instanceof YPContact) {
        YPContact ypCon = (YPContact) resultsList.get(position);
        if(checkForGold(ypCon))
            return VIEW_TYPE_YPCONTACT_GOLD;
        else
            return VIEW_TYPE_YPCONTACT_REG;
    }
  }

Затем в getView вам нужно будет проверить, с каким типом представления вы имеете дело, и наполнить / заполнить правильным классом ViewHolder.

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

    View ourView = convertView;
    int itemViewType = getItemViewType(position);
    switch (itemViewType) {
    case VIEW_TYPE_MORE_RESULTS_LOADER:
        MoreResultsViewHolder moreResVH = null;
        if (ourView == null) {

            ourView = layoutInflator.inflate(R.layout.load_more_items,
                    null, true);
            moreResVH = new MoreResultsViewHolder(ourView);
            ourView.setTag(moreResVH);

        } else {
            moreResVH = (MoreResultsViewHolder) ourView.getTag();
        }
        if (moreResVH != null) {
            moreResVH.populate((MoreResultsLoader) resultsList
                    .get(position), context);
        }
        return ourView;
    case VIEW_TYPE_YPCONTACT_GOLD:
        ContactViewHolderGold contactVHGold = null;
        if (ourView == null) {

            ourView = layoutInflator.inflate(
                    R.layout.yp_search_result_list_item_gold, null, true);
            contactVHGold = new ContactViewHolderGold(ourView);
            ourView.setTag(contactVHGold);

        } else {
            contactVHGold = (ContactViewHolderGold) ourView.getTag();
        }
        if (contactVHGold != null) {
            final YPContact ypContact = (YPContact) resultsList
                    .get(position);
            contactVHGold.populate(ypContact, mCurrentLocation,
                    ypSearchResultsActivity);
            // moreResVH.populate(
            // (MoreResultsLoader)resultsList.get(position),context);
        }
        return ourView;
0 голосов
/ 27 мая 2011

Посмотрите на первый элемент "Cook":

String[] names = new String[] {"Cook","2/Person/15/5","Cashier","2/Person/15/5"};

Вы делаете:

String[] info = names.get(position).split("/");

А потом:

holder.name.setText(info[1]);
holder.money.setText(info[2]);

Я нечтобы увидеть ArrayIndexOutOfBoundsException, нужно заглянуть в logcat

0 голосов
/ 27 мая 2011

Android имеет инструмент отладки logcat в перспективе ddms, где вы найдете журналы. Вы сможете точно определить номер строки, в которой происходит сбой кода.

convertView в основном используется, когда все элементы списка одинаковы. Как это помогает в переработке взглядов. Здесь мы не уверены, является ли переработанное представление R.layout.employee или R.layout.lable. Это может быть причиной проблемы.

Снова это предположение. Logcat поможет вам сузить проблему.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...