publicvoidsetSelectedPosition(int pos) { selectedPos = pos; // inform the view of this change notifyDataSetChanged(); }
@Override public View getView(int position, View convertView, ViewGroup parent) { Viewv= convertView; ViewHolder holder; // to reference the child views for later actions
if (v == null) { LayoutInflatervi= (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.mainrow, null);
// associate the holder with the view for later lookup v.setTag(holder); } else { // view already exists, get the holder instance from the view holder = (ViewHolder)v.getTag(); }
// change the row color based on selected state if (selectedPos == position) { v.setBackgroundResource(R.drawable.stocks_selected_gradient); holder.nameText.setTextColor(Color.WHITE); holder.priceText.setTextColor(Color.WHITE); holder.changeText.setTextColor(Color.WHITE); } else { v.setBackgroundResource(R.drawable.stocks_gradient); holder.nameText.setTextAppearance(getApplicationContext(), R.style.BlueText); holder.priceText.setTextAppearance(getApplicationContext(), R.style.BlueText); holder.changeText.setTextAppearance(getApplicationContext(), R.style.BlueText); }
Quoteq= items.get(position); if (q != null) { if (holder.nameText != null) { holder.nameText.setText(q.getSymbol()); } if (holder.priceText != null) { holder.priceText.setText(q.getLastTradePriceOnly()); } if (holder.changeText != null) { try { floatfloatedChange= Float.valueOf(q.getChange()); if (floatedChange < 0) { if (selectedPos != position) holder.changeText.setTextAppearance(getApplicationContext(), R.style.RedText); // red } else { if (selectedPos != position) holder.changeText.setTextAppearance(getApplicationContext(), R.style.GreenText); // green } } catch (NumberFormatException e) { System.out.println("not a number"); } catch (NullPointerException e) { System.out.println("null number"); } holder.changeText.setText(q.getChange() + " (" + q.getPercentChange() + ")"); } } return v; } }
Переведено автоматически
Ответ 1
ViewHolder - это, по сути, статический экземпляр класса, который вы связываете с представлением при его создании, кэшируя дочерние представления, которые вы просматриваете во время выполнения. Если представление уже существует, извлеките экземпляр holder и используйте его поля вместо вызова findViewById.
В вашем случае:
@Override public View getView(int position, View convertView, ViewGroup parent) { Viewv= convertView; ViewHolder holder; // to reference the child views for later actions
if (v == null) { LayoutInflatervi= (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.mainrow, null); // cache view fields into the holder holder = newViewHolder(); holder.nameText = (TextView) v.findViewById(R.id.nameText); holder.priceText = (TextView) v.findViewById(R.id.priceText); holder.changeText = (TextView) v.findViewById(R.id.changeText); // associate the holder with the view for later lookup v.setTag(holder); } else { // view already exists, get the holder instance from the view holder = (ViewHolder) v.getTag(); } // no local variables with findViewById here
// use holder.nameText where you were // using the local variable nameText before
return v; }
// somewhere else in your class definition staticclassViewHolder { TextView nameText; TextView priceText; TextView changeText; }
предостережение: я не пытался это скомпилировать, так что отнеситесь к этому с недоверием.
Ответ 2
Я только что столкнулся с аналогичной проблемой здесь, но немного сложнее, рассмотрим очень похожий пример.
if (v == null) { LayoutInflatervi= (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); v = vi.inflate(R.layout.mainrow, null); holder = newViewHolder(); holder.nameText = (TextView) v.findViewById(R.id.nameText); holder.priceText = (TextView) v.findViewById(R.id.priceText); holder.myCheckbox = (Checkbox) v.findViewById(R.id.changeText); v.setTag(holder); } else { holder = (ViewHolder) v.getTag(); /*ATTENTION - this line below was added, because i started to face some problems with view reuse of other rows, when user changed the state, the behavior of other row was triggered*/ holder.myCheckbox.setOnCheckedChangeListener(null); } /*without the new line above, the line below trigger the old event and some strange behavior happens.*/ holder.myCheckbox.setChecked(myList.get(position).isChecked()); holder.myCheckbox.setOnCheckedChangeListener(()->{ //some behavior });
return v; }
// somewhere else in your class definition staticclassViewHolder { TextView nameText; TextView priceText; Checkbox myCheckbox; }
Итак, помните, что при использовании шаблона ViewHolder полезно очистить прослушиватели компонентов, прежде чем изменять их состояние.