Проблемы с зашифрованными данными при прокрутке моего списка. Может быть, вы можете увидеть мои проблемы в моем адаптере
Я сделал специальный адаптер на основе 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;
}
Это должно помочь вам. Ура!
Для всех тех, кто все еще борется с зашифрованными данными в виде списка, переключитесь на утилиту просмотра. У меня была такая же проблема, я попробовал следующее:
- Использование шаблона View-Holder.
- Проведение ссылок на индивидуальный вид на карте.
Я пришел к выводу, что для этого есть что-то, что влияет на высоту списка, если вы установите его в значение "wrap_content", необходимо вызвать getview() для измерения высоты дочерних элементов в списке. Это вызывает неловкое поведение для convertview.
Мое решение состояло в том, чтобы полностью заменить реализацию listview и переключиться на переработчик.