2017-01-23 2 views
0

Я создал адаптер для ListView в Android, который ведет себя действительно странно. Listview передается список объектов, который сортируется по некоторому правилу (сравнение чисел, wow ...). Теперь, когда список показан в представлении, отображаются повторяющиеся записи, они не сортируются, записи отсутствуют, а при прокрутке списка меняются даже записи! Что происходит?Почему мой список выглядит странно в андроиде?

Вот код адаптера, я могу разместить больше кода, если это необходимо:

public class StatViewAdapter extends BaseAdapter { 

    Activity activity; 
    ArrayList<Entry> entries; 

    TextView txtName; 
    TextView txtOK; 
    TextView txtNOK; 
    TextView txtHist; 
    TextView txtPrandom; 
    TextView txtPhist; 
    TextView txtPtotal; 

    //public StatViewAdapter(Activity activity, ArrayList<HashMap<String, String>> list){ 
    public StatViewAdapter(Activity activity, ArrayList<Entry> entries){ 

     super(); 
     this.activity=activity; 
     this.entries = entries; 

     Collections.sort(this.entries, new Comparator<Entry>() { 
      @Override 
      public int compare(Entry o1, Entry o2) { 
       if (o1.getPriority() > o2.getPriority()) { 
        return 1; 
       } 
       if (o1.getPriority() < o2.getPriority()) { 
        return -1; 
       } 
       return 0; 

      } 
     }); 

     for (int i=0;i<this.entries.size();i++) { 
      String name = this.entries.get(i).name(); 
      int p = this.entries.get(i).getPriority(); 
      System.out.println(String.format("%s: %d", name, p)); 
     } 


    } 

    @Override 
    public int getCount() { 
     // TODO Auto-generated method stub 
     //return list.size(); 
     return this.entries.size(); 
    } 

    @Override 
    public Object getItem(int position) { 
     // TODO Auto-generated method stub 
     return this.entries.get(position); 
    } 

    @Override 
    public long getItemId(int position) { 
     // TODO Auto-generated method stub 
     return 0; 
    } 



    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     // TODO Auto-generated method stub 

     LayoutInflater inflater=this.activity.getLayoutInflater(); 

     if(convertView == null){ 

      convertView=inflater.inflate(R.layout.list_view, null); 

      txtName=(TextView) convertView.findViewById(R.id.listname); 
      txtOK=(TextView) convertView.findViewById(R.id.listok); 
      txtNOK=(TextView) convertView.findViewById(R.id.listnok); 
      txtHist=(TextView) convertView.findViewById(R.id.listhist); 
      txtPrandom =(TextView) convertView.findViewById(R.id.listprandom); 
      txtPhist=(TextView) convertView.findViewById(R.id.listphist); 
      txtPtotal=(TextView) convertView.findViewById(R.id.listptot); 
     } 

     Entry entry = this.entries.get(position); 
     txtName.setText(entry.name()); 
     txtOK.setText(Integer.toString(entry.number_ok)); 
     txtNOK.setText(Integer.toString(entry.number_nok)); 
     txtHist.setText(entry.history); 
     txtPrandom.setText(Integer.toString(entry.randomIndex)); 
     txtPhist.setText(Integer.toString(entry.histIndex)); 
     txtPtotal.setText(Integer.toString(entry.getPriority())); 

     return convertView; 
    } 

} 
+1

Очевидно, потому что вы храните ссылки на мнения пункта непосредственно в Adapter – Selvin

+0

что? Вы можете объяснить? Это не очевидно для меня ... – Alex

+0

Проанализируйте, что произойдет, если convertView не является нулевым, но не совпадает с последним представлением, полученным от getView. – Selvin

ответ

2

Целью public View getView(int position, View convertView, ViewGroup parent) является связать данные объекта на данном position на вид. Представление может быть переработанным (convertView) или вам нужно создать его в методе. Проблема в том, что вы не должны хранить ссылки на эти виды (txtName, txtOk) в Adapter.

public class StatViewAdapter extends BaseAdapter { 

    Activity activity; 
    ArrayList<Entry> entries; 

    //TextView txtName; 
    //TextView txtOK; 
    // ... 

    public StatViewAdapter(Activity activity, ArrayList<Entry> entries){ 
    // ... 

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

     LayoutInflater inflater=this.activity.getLayoutInflater(); 

     if(convertView == null){ 
      convertView=inflater.inflate(R.layout.list_view, null); 
     } 

     TextView txtName=(TextView) convertView.findViewById(R.id.listname); 
     TextView txtOK=(TextView) convertView.findViewById(R.id.listok); 
     // ... 

     Entry entry = this.entries.get(position); 
     txtName.setText(entry.name()); 
     txtOK.setText(Integer.toString(entry.number_ok)); 
     // .... 

     return convertView; 
    } 

Это работает, но это еще не хороший способ сделать это, вы можете использовать RecyclerView или реализовать ViewHolder шаблон.

Идея шаблона ViewHolder заключается в том, что вам не нужно звонить findViewById каждый раз, когда вы привязываете представление, потому что оно является дорогостоящим, и это может сделать прокрутку лагги.

Вы можете использовать RecyclerView, потому что это более новый и более гибкий вид, что делает ту же самую работу в ListView и имеет ViewHolder шаблона встроенные.

+0

Нет, не работает. Я вижу тот же результат. Возможно, мне нужно очистить проект. Один момент ... – Alex

+0

Хорошо, похоже, это сработало. Но почему это не очень хорошо. Что такое «RecyclerView»? Я не хочу перерабатывать представление, просто чтобы представить данные в списке ...? – Alex

+0

Я отредактировал ответ, почему это не очень хорошая причина, также если это помогло, пожалуйста, подумайте о принятии ответа :) – lelloman

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