Reputation: 1811
I have a progressbar in drawable. I want it to fill slowly whenset progress is done. That is it I should be able to see it filling, not in a flash. Also I have a texview inside that progressbar, I want that textview to keep revolving and as soon as the set progress filling completes, the textview should stop revolving and display progress.
Here is my code:
Layout:
<ProgressBar
android:id="@+id/circularProgressBar"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="150dip"
android:layout_height="150dip"
android:layout_centerInParent="true"
android:indeterminate="false"
android:max="100"
android:progress="0"
android:progressDrawable="@drawable/progressbar" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:textSize="47sp"
android:textStyle="bold"
android:textColor="@color/Theme" />
</RelativeLayout>
progressbar.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/background">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="7.0"
android:useLevel="false" >
<solid android:color="@color/Red" />
</shape>
</item>
<item android:id="@android:id/progress">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="7.0" >
<solid android:color="@color/Theme" />
</shape>
</item>
</layer-list>
Also, I have a textview inside this progressbar, I want it to keep rotating until the progress is done. How to do that, I have an animation for that but it is not working. Here is the code:
rotate.xml
<rotate xmlns:android="http://schemas.android.com/apk/res/android" >
android:duration="4000"
android:fromdegrees="0"
android:pivotx="50%"
android:pivoty="50%"
android:todegrees="360"
android:toyscale="0.0"
</rotate>
It gives warnings like this: Unexpected text found in layout file: "android:fromdegrees="0" android:pivotx="50%" android:pivoty="50%" android:todegrees="360" android:to..."
Upvotes: 0
Views: 5190
Reputation: 9643
Below is the code I am using for gradually filling circular progressbar-
xml
<ProgressBar
android:id="@+id/progress"
android:layout_width="100dp"
android:layout_height="100dp"
style="?android:attr/progressBarStyleHorizontal"
android:indeterminate="false"
android:layout_centerInParent="true"
android:max="100"
android:visibility="gone"
android:progressDrawable="@drawable/background" />
background.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@android:id/secondaryProgress">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:useLevel="true"
android:thicknessRatio="14.0">
<gradient
android:startColor="#999999"
android:endColor="#999999"
android:centerColor="#999999"
android:type="sweep" />
</shape>
</item>
<item android:id="@android:id/background">
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:thicknessRatio="14.0"
android:useLevel="false" >
<solid android:color="@color/white" />
</shape>
</item>
<item android:id="@android:id/progress">
<rotate
android:fromDegrees="270"
android:pivotX="50%"
android:pivotY="50%"
android:toDegrees="270" >
<shape
android:innerRadiusRatio="3"
android:shape="ring"
android:useLevel="true"
android:thicknessRatio="14.0">
<rotate
android:fromDegrees="0"
android:toDegrees="360"
android:pivotX="50%"
android:pivotY="50%" />
<gradient
android:startColor="#8E58D4"
android:endColor="#8E58D4"
android:centerColor="#8E58D4"
android:type="sweep" />
</shape>
</rotate>
</item>
</layer-list>
Code
mProgressBar = (ProgressBar) activity.findViewById(R.id.progress);
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.background);
mProgressBar.setProgressDrawable(drawable);
ObjectAnimator animation = ObjectAnimator.ofInt(mProgressBar, "progress", 0, 100);
animation.setDuration(10000);
Upvotes: 0
Reputation: 1241
Use this code it will help you.
Required Stuff:
1) CustomProgressDialog
package com.est.framework.android.ui;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.sc.restclient.R;
// TODO: Auto-generated Javadoc
/**
* The Class CustomProgressDialog.
*/
public class CustomProgressDialog extends Dialog {
/**
* Instantiates a new custom progress dialog.
*
* @param context the context
* @param theme the theme
*/
public CustomProgressDialog(Context context, int theme) {
super(context, theme);
}
/* (non-Javadoc)
* @see android.app.Dialog#onWindowFocusChanged(boolean)
*/
@Override
public void onWindowFocusChanged(boolean hasFocus) {
ImageView imageView = (ImageView) findViewById(R.id.loadingImageView);
AnimationDrawable yourAnimation = (AnimationDrawable) imageView.getBackground();
yourAnimation.start();
}
/**
* Creates the dialog.
*
* @param context the context
* @param title the title
* @param message the message
* @return the custom progress dialog
*/
public static CustomProgressDialog createDialog(Context context,String title) {
CustomProgressDialog dialog = new CustomProgressDialog(context,android.R.style.Theme_Panel);
dialog.setContentView(R.layout.dialogimg);
int width = ViewGroup.LayoutParams.MATCH_PARENT;
int height = ViewGroup.LayoutParams.MATCH_PARENT;
dialog.getWindow().setLayout(width, height);
TextView mloadMsg = (TextView)dialog.findViewById(R.id.loadMsg);
if (title != null) {
mloadMsg.setText(title);
}else{
mloadMsg.setVisibility(View.GONE);
}
dialog.getWindow().getAttributes().gravity = Gravity.CENTER;
dialog.setCancelable(false);
return dialog;
}
}
2) Layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/pop_bg_bitmap"
android:gravity="center"
android:orientation="vertical" >
<ImageView
android:id="@+id/loadingImageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:background="@anim/loading_anim" />
<TextView
android:id="@+id/loadMsg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="10dp"
android:layout_gravity="center_horizontal"
android:textColor="@color/btn_stroke_text"
android:text="Loading..." />
</LinearLayout>
3) Anim
<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
android:oneshot="false">
<item android:drawable="@drawable/progress_1" android:duration="500" />
<item android:drawable="@drawable/progress_2" android:duration="500" />
<item android:drawable="@drawable/progress_3" android:duration="500" />
<item android:drawable="@drawable/progress_4" android:duration="500" />
</animation-list>
4) Drawable
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/fancybox_overlay"
android:antialias="false"
android:dither="true"
android:tileMode="repeat"
>
</bitmap>
Images :
Upvotes: 1
Reputation: 825
You may use Handler
and Runnable
.
Make the Handler execute postDelayed(yourRunnable, DELAY);
in a new method called void next()
or something.
In the run()
method of yourRunnable
, increase the progress position by X amount (very little, like 1 percent or something depending on your desire), and invalidate()
your progress bar. After the progress bar increases the progress position by X amount, invoke next()
again, which will, execute yourRunnable.run() again, which will increase the progress position by X amount (or you may gradually increase amount using a little more complex math, instead of static X amount), and so goes the cycle until the progress fills up to your desired amount.
private ProgressAnimator animator;
@Override
public void onDraw(Canvas c) {
super.onDraw(c);
if (animator.started) {
animator.next();
}
}
public void animateProgress(float end, IAnimator.PostAnimationAction postPostAnimationAction) {
animator.start(end, postPostAnimationAction);
}
private class ProgressAnimator {
static final long DELAY = 10;
// NOTE:
// "MULTIPLY_FACTOR" IS OPTIONAL.
// I USED THIS TO INCREASE THE PROGRESS SMOOTHLY AT
// DYNAMIC SPEED, NOT AT STATIC SPEED.
// IF YOU WANT STATIC INCREASE OF THE PROGRESS,
// DONT USE THIS.
static final float MULTIPLY_FACTOR = 0.2f;
float endPosition;
float remaining;
boolean started;
PostAnimationAction postAnimationAction;
Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
if (Math.abs(remaining) > 1) {
raiseProgress(/* pass the current progress position here*/);
} else {
end();
}
}
};
/**
* Constructor.
*
*/
ProgressSweepAnimator() {
init();
}
@Override
public void init() {
started = false;
}
// NOTE:
// "PostPostAnimationAction" IS OPTIONAL. I CREATED AND USED THIS
// BECAUSE I WANTED TO DO SOMETHING AFTER THE PROGRESS
// ANIMATION IS FINISHED.
public void start(float endPosition, PostAnimationAction postPostAnimationAction) {
this.endPosition = endPosition;
start(postPostAnimationAction);
}
@Override
public void start(PostAnimationAction postAnimationAction) {
// Initialize status.
started = true;
this.postAnimationAction = postAnimationAction;
// Find out the current progress.
float start = /* get the current progress position here*/;
remaining = end - start;
raiseProgress(start);
}
@Override
public void next() {
handler.postDelayed(runnable, DELAY);
}
private void raiseProgress(float from) {
float toRaise = remaining * MULTIPLY_FACTOR;
remaining -= toRaise;
raiseProgressTo(from + toRaise);
}
@Override
public void end() {
raiseTo(end);
init();
// NOTE:
// THIS IS OPTIONAL BUT MAY BE VERY USEFUL, SO I
// JUST LEFT THIS OUT HERE.
// Notify the subscriber about the completion of the Burst action.
postAnimationAction.onActionComplete();
}
}
Upvotes: 0
Reputation: 8208
Create a Property
for the progress:
final Property<ProgressBar, Integer> progressProperty = new Property<ProgressBar, Integer>(
int.class, "progress") {
@Override
public Integer get(ProgressBar object) {
return object.getProgress();
}
@Override
public void set(ProgressBar object, Integer value) {
object.setProgress(value);
}
};
Create and start an ObjectAnimator
for that property on your ProgressBar
(mProgressBar):
private void animateProgressBar(int targetProgress) {
ObjectAnimator anim = ObjectAnimator.ofInt(mProgressBar, progressProperty, targetProgress);
anim.setInterpolator(new DecelerateInterpolator());
anim.setDuration(300);
anim.start();
}
You can costumize the animation with Interpolator
s, different duration, ecc
You can also use:
private void animateProgressBar(int targetProgress) {
ObjectAnimator anim = ObjectAnimator.ofInt(mProgressBar, "progress", targetProgress);
anim.setInterpolator(new DecelerateInterpolator());
anim.setDuration(300);
anim.start();
}
without declarying the Property, but I don't like this approach that much.
Upvotes: 1
Reputation: 26
I don't know about the text rotation, but for slowly increasing the progress bar, you can try this one:
mProgressBar is a global progress bar variable which is holding the instance of your progress bar
mProgress is a global integer variable initially set to 0, to monitor the current level of your progress bar.
pSize is the amount you want to increase the progress bar from the current level.
pSleepTime is the speed you want the progress bar to fill up. I usually use 50.
private void setProgressBar(int pSize, int pSleepTime) throws InterruptedException {
for(int i=0;i<pSize && mProgress<100;i++){
mProgress++;
Thread.sleep(pSleepTime);
mProgressBar.setProgress(mProgress);
}
}
Upvotes: 0