Question

The following is a very simplified layout for a list view item that works as expected running on multiple different android 4.x devices but not on android 2.3 (device and emulator).

Expected: The progressbar should cover the entire background of this item, both horizontally and vertically. Expected

On Android 2.3: The progressbar, when progress set > 0, is always shown as full and the height is not covering the entire item, just the top. Not working

Layout xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/shadowBackgroundHolder"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@drawable/selected_shadow_top_and_bottom" >

    <ProgressBar
        android:id="@+id/progressBar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_margin="0dp"
        android:padding="0dp"
        android:progressDrawable="@drawable/progress_timer" />

    <TextView
        android:id="@+id/currentTime"
        android:layout_width="wrap_content"
        android:layout_height="50dp" />

    <TextView
        android:id="@+id/timer_name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />

</FrameLayout>

I've tried different things etc, including the progressbar max values, programmatically and in xml. I've tried using a relative layout (and implicit z-ordering) instead of a frame layout, same problems. The 0dp padding and margin doesn't matter either.

Interestingly the same problems are present when using wrap_content for the width, albeit a shorter progressbar is shown, but still always filled when progress set to something greater than 0. The 50dp height for one of the TextViews is just in this example to clearly show the problem in the screenshot, it doesn't matter.

Could anyone else confirm this or even better have any ideas why the behavior is different? Better yet, a workaround or solution?

I can get the progressbar to work on 2.x devices using a different layout altogether not involving making it cover the entire height. That is in the current version of the app, but the next version is taking advantage of the entire item height for the progress instead. Opting for that solution for 2.x devices is not an optimal solution.

Update: Example of using RelativeLayout instead, I can get it to cover the full height, but still progress is always full. Using the following additional attributes on the progressbar element:

android:layout_alignBottom="@id/content"
android:layout_alignLeft="@id/content"
android:layout_alignTop="@id/content"

On Android 2.3 devices, full height indeed but progress is still always full if progress > 0: example problem 2

Was it helpful?

Solution 3

If using the version in the "update" section above and I cheat and add this after updating progress it "works" on Android 2.x as well:

if (!Application.hasHoneycomb()) {
    LayoutParams layoutParams = progressBar.getLayoutParams();
    layoutParams.width = ((View) progressBar.getParent()).getWidth() * progressBar.getProgress() / progressBar.getMax();
    progressBar.setLayoutParams(layoutParams);
}

So progress is still always full, just changing the size (width) of the entire progress bar. That's probably not very efficient though... It's a workaround but far from a real solution.

OTHER TIPS

ok, I'm sorry about my earlier comment, I reviewed my code base and found out that the bug was related to ProgressBar implementation itself.

So I ventured on created a view that extends TextView but has ProgressBar apperance. Feel free to copy it and improve on it as you need.

import android.widget.TextView;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;

public class ProgressTextView extends TextView {
private float mProgress = 0;
private int progressColor;
private int backgroundColor;
private Paint strokePaint;
private static final String tag = ProgressTextView.class.getSimpleName();

public ProgressTextView(Context context) {
    super(context);
}
public ProgressTextView(Context context, AttributeSet attrs) {
    super(context, attrs);
}
public ProgressTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);

}

@Override
public void draw(Canvas canvas) {
        canvas.save();
        setBackgroundColor(progressColor);
        canvas.clipRect(new Rect(0, 0, (int)(getWidth() * mProgress ), getHeight()));
        super.draw(canvas);
        canvas.restore();
        setBackgroundColor(backgroundColor);
        canvas.clipRect(new Rect((int)(getWidth() * mProgress), 0, getWidth(), getHeight()));
        super.draw(canvas);
        Rect rect = canvas.getClipBounds();
        if(strokePaint != null) {
            canvas.drawRect(rect, strokePaint);
        }
        canvas.restore();


}

public void setProgressColor(int color){
    progressColor = color;
}
public void setProgress(int progress) {
    if (progress > 100) {
        return;
    }
    if (mProgress == 0) {
        backgroundColor =Color.GRAY;
    }
    strokePaint = new Paint();
    strokePaint.setColor(progressColor);
    strokePaint.setStrokeWidth(5);
    strokePaint.setStyle(Style.STROKE);
    mProgress    = progress/ (float) 100;
    Log.i(tag, "update progress: " + mProgress);

    invalidate();
}
 }

I had a similar problem. This progress bar is working for me now:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MoDa" >

<TextView
    android:id="@+id/title"
    style="?textTitle"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:text="@string/app_name" />

<ProgressBar
    android:id="@+id/progressbar"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="fill_parent"
    android:layout_height="8dp"
    android:max="100"
    android:visibility="gone" />

<FrameLayout
    android:id="@+id/frame"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_gravity="top|center_horizontal"
    android:orientation="horizontal" >

(more layout follows) Progress bar is full width below the TextView

hope this helps

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top