2015-11-24 2 views
3

Я в основном пытаюсь отобразить несколько просмотров через один и тот же адаптер ListView. Тем не менее, адаптер заканчивает создание нескольких дубликатов и сбоев иногда также с помощью NullPointer. Я предполагаю, что я внедрил адаптер, все неправильно. Вот мой полный код:Android ListView Adapter Crash issue/Duplicates

Элемент может быть либо фото или текст.

Adapter:

public class FeedAdapter extends BaseAdapter { 

     static private Activity activity; 
     private static LayoutInflater inflater = null; 
     ArrayList<ActivityTable> actList = new ArrayList<ActivityTable>(); 
     Holder holder; 

    public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) { 
      activity = a; 
      this.actList = actList; 
     } 

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

      Holder holder; 

      final ActivityTable act = actList.get(position); 
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 

    if (convertView == null) { 

       if (act.getType().equals("text")) { 

        convertView = inflater.inflate(R.layout.feed_single_text, null); 
        holder = new Holder(); 

        //More code that Set the caption to the holder 
        convertView.setTag(holder); 

       } 

       if (act.getType().equals("photo")) { 

        convertView = inflater.inflate(R.layout.feed_single_picture, parent, false); 
        holder = new Holder(); 
        holder.media = (ImageView) convertView.findViewById(R.id.postphoto); 
        //More code that Set the photo to the holder 
        convertView.setTag(holder); 
       } 

      } else { 

       holder = (Holder) convertView.getTag(); 

      } 

     return convertView; 
    } 


    public static class Holder { 
      ImageView media; 
      TextView caption; 
    } 
} 

Могу ли я надувания несколько представлений в одном адаптере не так? Может ли кто-нибудь указать на ошибку?

+0

Вы можете разместить код, заданный для каждой строки? я имею в виду код выше «return convertView» и ниже 'else {...} ' –

+0

Почему вы все еще используете' ListView', когда есть лучшая альтернатива? Поддерживаете ли вы устаревший код? –

+0

@AvinashR Какая лучшая альтернатива? – Dinuka

ответ

0

Да, вы получите дубликат, потому что Convertview повторное использование. Когда будет создан конверт, который будет просматривать, если вы прокручиваете.

Поэтому лучше использовать единый макет и с изображением и текстом. На основе типа скрыть любой.

+0

с использованием setVisibility для каждого элемента так же плохо, как с использованием двух разных видов. Удачи, используя один вид в будущем, если вам нужно добавить 5 текстовых полей, и вам нужно скрыть 5 текстовых полей. Я не могу поверить, что это правильный ответ. @ earthing the best practice использует мой ответ как логику для adpater, чтобы идентифицировать разные между двумя видами, а затем использовать view Holder, я вижу, что вы используете в своем коде Holder. вы должны уметь это понимать. –

0

XML файл

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:orientation="vertical" > 

<ImageView 
    android:id="@+id/ImgFeed" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 

<TextView 
    android:id="@+id/txtCaption" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" /> 

</LinearLayout> 

попробовать это вы используете ImageView InstEd из TextView

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

     Holder holder; 

     final ActivityTable act = actList.get(position); 
     inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
     if (convertView == null) { 
     convertView = inflater.inflate(R.layout.feed_layout, null); 
     holder = new Holder(); 
     holder.caption = (TextView) convertView.findViewById(R.id.txtCaption); 
     holder.media = (ImageView) convertView.findViewById(R.id.ImgFeed); 
      if (act.getType().equals("text")) { 
       holder.media.setVisibility(View.GONE) 
      } 

      else if (act.getType().equals("photo")) { 
       holder.caption.setVisibility(View.GONE)    
      } 
      convertView.setTag(holder); 

     } else { 

      holder = (Holder) convertView.getTag(); 

     } 

    return convertView; 
} 
+0

Можете ли вы прояснить свое решение? Я не вижу разницы? – Dinuka

+0

holdor.caption - это текстовое представление, и вы используете его как изображение в getview. –

+0

. Nope все еще не решит проблему. Я вижу много дубликатов. – Dinuka

1

У вас есть 2 diffrent макет для каждой строки, так что я думаю, вы должны добавить

@Override 
public int getViewTypeCount() { 
    return 2; 
} 

к вашему адаптеру listview
В вашем коде попытайтесь ваш LayoutInflater внутри конструктора адаптера

public FeedAdapter(Activity a, ArrayList<ActivityTable> actList) { 
    ... 
    inflater = (LayoutInflater) activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
} 

А также вы должны оптимизировать производительность ListView

Here is my experience

+0

Все еще давал мне дубликаты просмотров, приятель. Я прибегну к использованию RecyclerView, тогда – Dinuka

1

Это хорошо, чтобы иметь эти 3 на месте.

@Override 
public int getCount() { 
    return actList().size(); 
} 

@Override 
public Object getItem(int position) { 
    return actList().get(position); 
} 

@Override 
public long getItemId(int position) { 
    return position; 
} 

Вот важная часть, первых вы должны сказать адаптер, сколько тип, и тогда вы должны сказать адаптер, как определить тип.

Здесь я говорю типа View Type = 2

@Override 
public int getViewTypeCount() { 
    return 2; 
} 

и здесь я говорю адаптер Как поставить номер типа в массив Я использую SetType = 0 || установить тип = 1 личные предпочтения здесь: Я хотел бы использовать INT вместо строки

@Override 
public int getItemViewType(int position) { 
    return act.get(position).getType(); 
} 

а затем на GetView

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

    View v = convertView; 
    int listViewItemType = getItemViewType(position); 
    if (v == null) { 
     ..whatevever you doing to make v not null 
    } 

    if (listViewItemType == 0) { 
     //Do something  
    }else if(listViewItemType == 1){ 
     // Do something different 
    } 
    return v; 
} 
Смежные вопросы