Indeterminate Loading Text in Android
Filed Under (android, java, programming) by Nathan Schwermann on 01-08-2010
Recently I made a handy little Android widget that displays a message and animates 3 periods after it to indicate that work is being done. Its just another alternative to using a ProgressBar set to indeterminate. I used the timed UI updating technique described in the devguide
First we extend the TextView class and included some extra members.
public class LoadingTextWidget extends TextView {
Handler mHandler;
StringBuilder mBuilder;
String mText;
int mCount, mStringSize;
final int DELAY = 400;
public LoadingTextWidget(Context context, AttributeSet attrs) {
super(context, attrs);
mText = (String)getText();
mBuilder = new StringBuilder(mText);
mCount = 0;
mHandler = new Handler();
mStringSize = (int) getPaint().measureText(mText + "...");
setWidth(mStringSize);
mHandler.post(AnimatePeriod);
}
Next we implement a runnable to animate the periods every 400 ms.
Runnable AnimatePeriod = new Runnable() {
@Override
public void run() {
mCount++;
mBuilder.append('.');
if(mCount == 4){
mCount = 0;
mBuilder.delete(0, mBuilder.length());
mBuilder.append(mText);
}
setText(mBuilder.toString());
setWidth(mStringSize);
mHandler.postDelayed(AnimatePeriod, DELAY);
}
};
Lastly remember to clean up after yourself.
@Override
protected void onDetachedFromWindow() {
mHandler.removeCallbacks(AnimatePeriod);
super.onDetachedFromWindow();
}
}
Now we just create the object in an Android layout file.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<net.schwiz.views.LoadingTextWidget
style="@style/LoadingText"
android:text="Loading"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
One thing to note about the style attributes is that the gravity is set to left. This way the actual text doesn’t move on the screen as the periods animate.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LoadingText">
<item name="android:textSize">14dip</item>
<item name="android:textColor">#FFFFFF</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">left</item>
<item name="android:textStyle">bold</item>
</style>
</resources>
