Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android: Custom Horizontal Progress Bar Animation

I'm trying to create a progress bar where the bar itself animates in a vertical spin as it progresses horizontally. I'm successfully using my progress drawable as the drawable via:

<ProgressBar
        android:id="@+id/progressBar"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        style="@android:style/Widget.ProgressBar.Horizontal"
        android:progressDrawable="@drawable/custom_progress"
        android:layout_marginRight="5dp" />

Here is my drawable:

enter image description here

But I want it to have a subtle roll effect as its progressing. So it would look like the vertical lines are moving backwards sorta. You follow? Any help is much appreciated. Thanks.

EDIT: I tried created an animation-list as my progress drawable but I'm still not able to see the animation. Can an animation-list be inside of a clip for the progress item?

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@android:id/background" android:drawable="@drawable/gutter"></item>

<item android:id="@android:id/progress">

<clip>
    <animation-list android:oneshot="false">
        <item android:drawable="@drawable/progress_bar_animate" android:duration="100" />
        <item android:drawable="@drawable/progress_bar_animate2" android:duration="100" />
        <item android:drawable="@drawable/progress_bar_animate3" android:duration="100" />
        <item android:drawable="@drawable/progress_bar_animate4" android:duration="100" />
        <item android:drawable="@drawable/progress_bar_animate5" android:duration="100" />
        <item android:drawable="@drawable/progress_bar_animate6" android:duration="100" />
        <item android:drawable="@drawable/progress_bar_animate7" android:duration="100" />
    </animation-list>
</clip>

</item>
</layer-list>
like image 941
askilondz Avatar asked Dec 20 '12 02:12

askilondz


People also ask

How do I make my progress bar horizontal android?

In Android, by default a progress bar will be displayed as a spinning wheel but If we want it to be displayed as a horizontal bar then we need to use style attribute as horizontal. It mainly use the “android. widget. ProgressBar” class.

What is ProgressBar in android?

Android ProgressBar is a graphical view indicator that shows some progress. Android progress bar displays a bar representing the completing of the task. Progress bar in android is useful since it gives the user an idea of time to finish its task.

How do I stop indeterminate progress bar?

An indeterminate progress bar animates constantly. You can stop the animation and clear the progress bar by making the progress bar determinate and setting the current value to the minimum.


2 Answers

Yahoo! Finally ! Works ! (BUT !!!! can cause memory leak with big images. It's fixed in the post below)

This code takes the tile picture (tile1), repeats it(TileMode.REPEAT), makes shifted animation (10 fragments), adds this in Animation set.

enter image description here

private void initAnimation() {
//      R.drawable.tile1 is PNG
        Bitmap b = BitmapFactory.decodeResource(getResources(),R.drawable.tile1);
        AnimationDrawable shiftedAnimation = getAnimation(b);

//      R.id.img_3 is ImageView in my application
        View v = findViewById(R.id.img_3);
        v.setBackground(shiftedAnimation);
        shiftedAnimation.start();
}

private Bitmap getShiftedBitmap(Bitmap bitmap, int shiftX) {
    Bitmap newBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig());
    Canvas newBitmapCanvas = new Canvas(newBitmap);

    Rect srcRect1 = new Rect(shiftX, 0, bitmap.getWidth(), bitmap.getHeight());
    Rect destRect1 = new Rect(srcRect1);
    destRect1.offset(-shiftX, 0);
    newBitmapCanvas.drawBitmap(bitmap, srcRect1, destRect1, null);

    Rect srcRect2 = new Rect(0, 0, shiftX, bitmap.getHeight());
    Rect destRect2 = new Rect(srcRect2);
    destRect2.offset(bitmap.getWidth() - shiftX, 0);
    newBitmapCanvas.drawBitmap(bitmap, srcRect2, destRect2, null);

    return newBitmap;
}

private List<Bitmap> getShiftedBitmaps(Bitmap bitmap) {
    List<Bitmap> shiftedBitmaps = new ArrayList<Bitmap>();
    int fragments = 10;
    int shiftLength = bitmap.getWidth() / fragments;

    for(int i = 0 ; i < fragments; ++i){
        shiftedBitmaps.add( getShiftedBitmap(bitmap,shiftLength * i));
    }

    return shiftedBitmaps;
}

private AnimationDrawable getAnimation(Bitmap bitmap) {
    AnimationDrawable animation = new AnimationDrawable();
    animation.setOneShot(false);

    List<Bitmap> shiftedBitmaps = getShiftedBitmaps(bitmap);
    int duration = 50;

    for(Bitmap image: shiftedBitmaps){
        BitmapDrawable navigationBackground = new BitmapDrawable(getResources(), image);
        navigationBackground.setTileModeX(TileMode.REPEAT);

        animation.addFrame(navigationBackground, duration);
    }
    return animation;
}
like image 144
StepanM Avatar answered Sep 28 '22 11:09

StepanM


I don't think this can be done the way I thought it could. The reason being that I can't reference the animated-list, which at that point is a ClipDrawable, and cast it to an AnimateDrawable which is necessary so I can programmatically start the animation. It's also necessary to contain it in the clip element as that's the ProgressBar's way of masking an image so it only displays part of the image as its progressing.

Aside from faking my own progress bar using ImageViews and animating those I don't see another way around it for this specific ProgressBar.

like image 27
askilondz Avatar answered Sep 28 '22 12:09

askilondz