滚动时ListView搞砸了

时间:2014-08-13 09:27:10

标签: android listview baseadapter

我有一个项目列表。其中一些需要购买,一些不需要。对于那些需要购买的人,会显示价格。我正在使用BaseAdapter来填充列表视图。乍一看,正确的项目显示价格,但滚动价格也显示其他课程。每次滚动时,列表视图都会更改。

    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
            }
        }
    }
}

2 个答案:

答案 0 :(得分:2)

重复使用ListView视图中的滚动时。设置视图值时(在setLessonView方法中)确保获得每个视图(使用findViewById)并为它们提供所有值。如果没有,如果该视图以前曾被用于持有价格课程并且您没有隐藏此价格视图(或设置某种值),您将看到旧值。

在您的代码中:

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);
            }
}

}

答案 1 :(得分:1)

问题似乎是您没有使用setLessonView()方法重置价格。

滚动时,getView()将重复使用视图,而convertView将不为空,因此else的{​​{1}}分支将被执行。这会调用getView(),当setLessonView()返回false时,您不会清除lessonsDetailsMap.containsKey(sku)purchaseIcon,因此会保留旧的purchasePricepurchaseIcon从视图中重复使用。

要解决此问题,请在评论purchasePrice之后的else setLessonView()分支中添加

// no purchased items

您也可以使用View.GONE,具体取决于您的布局以及是否要删除而不是隐藏。