Проблемы с зашифрованными данными при прокрутке моего списка. Может быть, вы можете увидеть мои проблемы в моем адаптере

Я сделал специальный адаптер на основе Baseadapter, и при прокрутке данных в списке возникает проблема. Все данные взломаны. Я предполагаю, что мой адаптер продолжает создавать представления, но мне нужно, чтобы вы, один из экспертов, посмотрели на код моего адаптера и указали на проблему, если вы можете решить мою проблему. Я думаю, что у меня должны быть некоторые проблемы с методом getView().

public class ListViewAdapter extends BaseAdapter {
    public ArrayList<HashMap<String, String>> list;
    Activity activity;
    TextView txtFirst;
    TextView txtSecond;
    TextView txtThird;
    TextView txtFourth;
    TextView txtFifth;
    TextView txtSixth;
    TextView txtSeventh;
    TextView txtEighth;
    public ListViewAdapter(Activity activity,ArrayList<HashMap<String, String>> list){
        super();
        this.activity=activity;
        this.list=list;
    }
    @Override
    public int getCount() {
// TODO Auto-generated method stub
        return list.size();
    }
    @Override
    public Object getItem(int position) {
// TODO Auto-generated method stub
        return list.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=activity.getLayoutInflater();
        if(convertView == null){
            LayoutInflater inflater=activity.getLayoutInflater();
            convertView=inflater.inflate(R.layout.colmn_row, null);
            txtFirst=(TextView) convertView.findViewById(R.id.range);
            txtSecond=(TextView) convertView.findViewById(R.id.dropin);
            txtThird=(TextView) convertView.findViewById(R.id.dropmoa);
            txtFourth=(TextView) convertView.findViewById(R.id.windin);
            txtFifth=(TextView) convertView.findViewById(R.id.windmoa);
            txtSixth=(TextView) convertView.findViewById(R.id.velocity);
            txtSeventh=(TextView) convertView.findViewById(R.id.energy);
            txtEighth=(TextView) convertView.findViewById(R.id.time);
        }
        HashMap<String, String> map=list.get(position);
        txtFirst.setText(map.get(FIRST_COLUMN));
        txtSecond.setText(map.get(SECOND_COLUMN));
        txtThird.setText(map.get(THIRD_COLUMN));
        txtFourth.setText(map.get(FOURTH_COLUMN));
        txtFifth.setText(map.get(FIFTH_COLUMN));
        txtSixth.setText(map.get(SIXTH_COLUMN));
        txtSeventh.setText(map.get(SEVENTH_COLUMN));
        txtEighth.setText(map.get(EIGHTH_COLUMN));
        return convertView;
    }
}

3 ответа

Первый. Вы должны использовать шаблон ViewHolder. Это сделало бы код чистым и эффективным.

public class ListViewAdapter extends BaseAdapter {

    public ArrayList<HashMap<String, String>> list;
    Activity activity;

    public ListViewAdapter(Activity activity,ArrayList<HashMap<String, String>> list){
        super();
        this.activity=activity;
        this.list=list;
    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder;
        //Only of the convertView is null, Inflate it.
        if(convertView == null){
            LayoutInflater inflater=activity.getLayoutInflater();
            convertView=inflater.inflate(R.layout.colmn_row, parent, false);

            holder = new ViewHolder();
            holder.txtFirst=(TextView) convertView.findViewById(R.id.range);
            holder.txtSecond=(TextView) convertView.findViewById(R.id.dropin);
            holder.txtThird=(TextView) convertView.findViewById(R.id.dropmoa);
            holder.txtFourth=(TextView) convertView.findViewById(R.id.windin);
            holder.txtFifth=(TextView) convertView.findViewById(R.id.windmoa);
            holder.txtSixth=(TextView) convertView.findViewById(R.id.velocity);
            holder.txtSeventh=(TextView) convertView.findViewById(R.id.energy);
            holder.txtEighth=(TextView) convertView.findViewById(R.id.time);
        //Add the holder as a tag to the convertView
         convertView.setTag(holder);
        } else {
          holder = (ViewHolder) convertView.getTag();
        }
        HashMap<String, String> map=list.get(position);
        holder.txtFirst.setText(map.get(FIRST_COLUMN));
        holder.txtSecond.setText(map.get(SECOND_COLUMN));
        holder.txtThird.setText(map.get(THIRD_COLUMN));
        holder.txtFourth.setText(map.get(FOURTH_COLUMN));
        holder.txtFifth.setText(map.get(FIFTH_COLUMN));
        holder.txtSixth.setText(map.get(SIXTH_COLUMN));
        holder.txtSeventh.setText(map.get(SEVENTH_COLUMN));
        holder.txtEighth.setText(map.get(EIGHTH_COLUMN));

        return convertView;
    }

    private class ViewHolder {
        TextView txtFirst;
        TextView txtSecond;
        TextView txtThird;
        TextView txtFourth;
        TextView txtFifth;
        TextView txtSixth;
        TextView txtSeventh;
        TextView txtEighth;
    }
}

Разница в том, что каждое представление в списке имеет свои собственные ссылки на txtviews в своем теге. И только в первый раз, когда представление надувается, на них ссылаются. Это уменьшит количество findViewById звонки и улучшить производительность.

У вас есть несколько проблем. Твой подход ужасен. Во-первых, вы должны по крайней мере использовать методы шаблонов ViewHolder. Шаблон ViewHolder - это шаблон, который можно использовать для увеличения скорости, с которой ListViws отображает данные. Причина этого улучшения заключается в том, что количество раз, когда вызывается метод findViewById, резко сокращается, существующие представления не нужно собирать мусором, а новые представления не нужно раздувать. Давайте попробуем изменить ваш код.

public class ListViewAdapter extends BaseAdapter {

   private ArrayList<HashMap<String, String>> mList; // did this really have to be public?
   private Activity mActivity; // I changed to a more proper variable name

   public ListviewAdapter(Activity activity, ArrayList<HashMap<String, String>> list) {
      // super(); yes I commented out this line
      this.mActivity = activity;
      this.mList = list;
   } 

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

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

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

   @Override
   public View getView(int position, View convertView, ViewGroup parent) {
      View view = convertView;
      ViewHolder holder;
      if (Utils.checkIfNull(view)) {
         LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
         view = inflater.inflate(R.layout.colmn_row, parent, false); //don't set to null here, better to set to false. Refer to google's official docs
         holder = new ViewHolder();

         holder.txtFirst=(TextView) convertView.findViewById(R.id.range);
         holder.txtSecond=(TextView) convertView.findViewById(R.id.dropin);
         holder.txtThird=(TextView) convertView.findViewById(R.id.dropmoa);
         holder.txtFourth=(TextView) convertView.findViewById(R.id.windin);
         holder.txtFifth=(TextView) convertView.findViewById(R.id.windmoa);
         holder.txtSixth=(TextView) convertView.findViewById(R.id.velocity);
         holder.txtSeventh=(TextView) convertView.findViewById(R.id.energy);
         holder.txtEighth=(TextView) convertView.findViewById(R.id.time);

         view.setTag(holder);

      } else {
         holder = (ViewHolder) view.getTag();
      }

      HashMap<String, String> map=list.get(position);
      holder.txtFirst.setText(map.get(FIRST_COLUMN));
      holder.txtSecond.setText(map.get(SECOND_COLUMN));
      holder.txtThird.setText(map.get(THIRD_COLUMN));
      holder.txtFourth.setText(map.get(FOURTH_COLUMN));
      holder.txtFifth.setText(map.get(FIFTH_COLUMN));
      holder.txtSixth.setText(map.get(SIXTH_COLUMN));
      holder.txtSeventh.setText(map.get(SEVENTH_COLUMN));
      holder.txtEighth.setText(map.get(EIGHTH_COLUMN));

      return view;
   }

   private static class ViewHolder {
      private TextView txtFirst, txtSecond, txtThird, txtFourth, txtFifth, txtSixth, txtSeventh, txtEighth;

   }
}

В качестве примечания, если вам нужен метод checkIfNull, то здесь

/**
 * Method is used to check null value for any object
 * 
 * @param objectToCheck
 * @return boolean
 */
public static <T> boolean checkIfNull(T objectToCheck) {
    return objectToCheck == null ? true : false;
}

Это должно помочь вам. Ура!

Для всех тех, кто все еще борется с зашифрованными данными в виде списка, переключитесь на утилиту просмотра. У меня была такая же проблема, я попробовал следующее:

  1. Использование шаблона View-Holder.
  2. Проведение ссылок на индивидуальный вид на карте.

Я пришел к выводу, что для этого есть что-то, что влияет на высоту списка, если вы установите его в значение "wrap_content", необходимо вызвать getview() для измерения высоты дочерних элементов в списке. Это вызывает неловкое поведение для convertview.

Мое решение состояло в том, чтобы полностью заменить реализацию listview и переключиться на переработчик.

Другие вопросы по тегам