siriusdely siriusdely - 3 years ago 162
Android Question

List Item (a view) order changes unexpextedly while (fast) scrolling in a ListView

I am new to android, and ended up (have to) ask a question here,

Let's make it simple, I simply want to make my own TextView-like
(MyView extends View),

this is my code:

public class MyView extends View {
private Paint mPaint;
private String mText;
private Bitmap mBitmap1;
private Bitmap mBitmap2;
public MyView(Context context) {
super(context);
initView();
}

public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
initView();
}

private final void initView() {
mPaint = new Paint();
}

public void setText(String text) {
mText = text;
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int measuredWidth = measureWidth(widthMeasureSpec);
if (mBitmap1 == null) initBitmap1(measuredWidth);
int measuredHeight = measureHeight(heightMeasureSpec);
setMeasuredDimension(measuredWidth, measuredHeight);
}

private void initBitmap1(int measuredWidth) {
mBitmap1 = Bitmap.createBitmap(measuredWidth, Fonts.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(mBitmap1 );
canvas.drawText(mText, 0, 0, mPaint);
}

private void initBitmap2() {
mBitmap2 = Bitmap.createBitmap(30, Fonts.getHeight(), Bitmap.Config.ARGB_4444);
Canvas canvas = new Canvas(mBitmap2);
canvas.drawText(mText, 0, 0, mPaint);
}

private int measureWidth(int widthMeasureSpec) {
int measuredWidth = 0;
int specWidthMode = MeasureSpec.getMode(widthMeasureSpec);
int specWidthSize = MeasureSpec.getSize(widthMeasureSpec);

if (specWidthMode == MeasureSpec.EXACTLY) {
measuredWidth = specWidthSize;
} else {
measuredWidth = getWidth();
if (specWidthMode == MeasureSpec.AT_MOST) {
measuredWidth = Math.min(measuredWidth, specWidthSize);
}
}
return measuredWidth;
}

private int measureHeight(int heightMeasureSpec) {
int measuredHeight = 0;
int specHeightMode = MeasureSpec.getMode(heightMeasureSpec);
int specHeightSize = MeasureSpec.getSize(heightMeasureSpec);

if (specHeightMode == MeasureSpec.EXACTLY) {
measuredHeight = specHeightSize;
} else {
measuredHeight = 80;
if (specHeightMode == MeasureSpec.AT_MOST) {
measuredHeight = Math.min(measuredHeight, specHeightSize);
}
}
return measuredHeight;
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawBitmap(mBitmap1, getLeft(), 0, mPaint);
initBitmap2();
canvas.drawBitmap(mBitmap2, getLeft(), 30, mPaint);
}


}

in my code, i populate some numbers of MyView (let's say 20) in a
ListActivity

my question is why mBitmap1's order changes randomly while i scroll
(up-down) fastly (if i scroll slowly, this problem not occur)..?

mBitmap2 stays where those should be..

Answer Source

you must use a view holder class in order overcome this problem. something like this:

public View getView(final int i, View view, final ViewGroup viewGroup) {
    View vi = view;
    final ViewHolder holder;
    if (view == null) {
        holder = new ViewHolder();
        vi = inflater.inflate(R.layout.listview_row_cart, null);
        holder.yourbutton = (Button) vi.findViewById(R.id.btn);
        vi.setTag(holder);
    } else {
        holder = (ViewHolder) view.getTag();
    }
        holder.yourbutton.setText("Start");
 }
 class ViewHolder {
       Button yourbutton
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download