Reputation: 531
I have a list of items. Some of them need to be purchased and some don't. For those that need to be purchased a price is displayed. I am using a BaseAdapter to populate the list view. At first glance prices are shown for the right items, but at scroll prices are shown also for other lessons. With each scroll, the list view changes.
public View getView(int position, View convertView, ViewGroup parent)
{
Lesson lesson = (Lesson) getItem(position);
if (convertView == null)
{
convertView = new LessonView(lesson);
}
else
{
((LessonView) convertView).setLessonView(lesson);
}
return convertView;
}
public class LessonView extends LinearLayout
{
private TextView lessonTitle, cardsNr, percentageValue, percentageCompleted, purchasePrice;
private ImageView progressImage, purchaseIcon;
private DrawUIHelper drawUIHelper;
private RelativeLayout lessonRow;
public LessonView(Lesson lesson)
{
super(mContext);
drawUIHelper = DrawUIHelper.getInstance(mContext);
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getWidth(), (int) (((WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay().getHeight() * 0.14));
addView(LayoutInflater.from(mContext).inflate(R.layout.lesson_item, null), params);
setLessonView(lesson);
}
/**
* @param lesson
*/
private void setLessonView(Lesson lesson)
{
lessonTitle = (TextView) findViewById(R.id.lessonTitleTextView);
lessonTitle.setText(lesson.getTitle());
TypeFaceSetter.getInstance(mContext).setFontType(lessonTitle);
cardsNr = (TextView) findViewById(R.id.cardsNrTextView);
cardsNr.setText(String.valueOf(lesson.getCardCount()));
progressImage = (ImageView) findViewById(R.id.learnProgressImageView);
lessonRow = (RelativeLayout) findViewById(R.id.lessonItem);
lessonTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, lessonRow.getLayoutParams().width / 20);
percentageValue = (TextView) findViewById(R.id.percentageTextView);
TypeFaceSetter.getInstance(mContext).setFontType(percentageValue);
percentageValue.setTextSize(TypedValue.COMPLEX_UNIT_PX, lessonRow.getLayoutParams().width / 15);
percentageValue.setText(String.valueOf(Math.round(lesson.getLearningProgress() * 100)) + "%");
percentageCompleted = (TextView) findViewById(R.id.percentageCompleted);
TypeFaceSetter.getInstance(mContext).setFontType(percentageCompleted);
percentageCompleted.setTextSize(TypedValue.COMPLEX_UNIT_PX, lessonRow.getLayoutParams().width / 50);
progressImage.setImageBitmap(drawUIHelper.drawLearnCircle(lessonRow.getLayoutParams().height + 40, lessonRow.getLayoutParams().height + 40, lesson.getLearningProgress() * 100));
int lessonId = getResources().getIdentifier("lesson_" + String.valueOf(lesson.getId()), "string", mContext.getPackageName());
if (lessonId != 0) {
String sku = mContext.getString(lessonId);
if (lessonsDetailsMap.containsKey(sku)) {
purchaseIcon = (ImageView) findViewById(R.id.purchaseIcon);
purchaseIcon.setVisibility(View.VISIBLE);
purchasePrice = (TextView) findViewById(R.id.purchasePrice);
purchasePrice.setVisibility(View.VISIBLE);
purchasePrice.setText(lessonsDetailsMap.get(sku));
} else {
// no purchased items
}
}
}
}
Upvotes: 0
Views: 593
Reputation: 2634
When scrolling in ListView views are reused. When setting a view values (in your setLessonView method) be sure you are getting every view (with findViewById) and giving them all a value. If not, if the view have been previously used to hold a Lesson with price and you do not hide this price view (or set some kind of value) you will see the old value.
In your code:
purchaseIcon = (ImageView) findViewById(R.id.purchaseIcon);
purchasePrice = (TextView) findViewById(R.id.purchasePrice);
if (lessonId != 0) {
String sku = mContext.getString(lessonId);
if (lessonsDetailsMap.containsKey(sku)) {
purchaseIcon.setVisibility(View.VISIBLE);
purchasePrice.setVisibility(View.VISIBLE);
purchasePrice.setText(lessonsDetailsMap.get(sku));
} else {
// no purchased items
purchaseIcon.setVisibility(View.INVISIBLE);
purchasePrice.setVisibility(View.INVISIBLE);
}
}
}
Upvotes: 2
Reputation: 5789
The problem appears to be that you are not resetting your prices in your setLessonView()
method.
When you scroll, getView()
will reuse views and convertView
will not be null, so the else
branch of getView()
will be executed. This calls setLessonView()
, and when lessonsDetailsMap.containsKey(sku)
returns false, you don't clear the purchaseIcon
and purchasePrice
, so it will retain the old purchaseIcon
and purchasePrice
from the view it is reusing.
To fix this, in your else
branch of setLessonView()
after the comment // no purchased items
, you need to add
purchaseIcon.setVisibility(View.INVISIBLE);
purchasePrice.setVisibility(View.INVISIBLE);
You could alternatively use View.GONE, depending on your layout and whether you want it removed rather than hidden.
Upvotes: 1