I use the built-in action bar. I want to display an animated bootloader on the action bar when retrieving data and display a refresh icon if not. The simple way I found is to use two menu items and show one / hide the other, and then vice versa. So here is my menu:
<item android:id="@+id/menuItemRefresh" android:title="Refresh" android:showAsAction="always" android:icon="@drawable/ic_menu_refresh" android:visible="false" /> <item android:id="@+id/menuItemProgress" android:actionLayout="@layout/progress" android:showAsAction="always" android:visible="true" />
I use actionLayout (as you can see) because I did not understand how to create an undefined progressbar change in my Menu. Here is the corresponding Layout action:
<?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:orientation="vertical" android:id="@+id/layoutProgress" > <ProgressBar android:id="@+id/menuItemRefresh" android:layout_width="30dp" android:layout_height="30dp" android:layout_marginLeft="13dp" android:layout_marginRight="13dp" /> </LinearLayout>
My activity:
public class MainActivity extends Activity implements OnItemClickListener { Handler handler; MenuItem menuItemProgress; MenuItem menuItemRefresh; int currentPage; List<CloudAppItem> items; boolean currentlyLoading = false; ListView listView; FilesAdapter filesAdapter; LinearLayout emptyView; @Override public void onCreate(Bundle savedInstanceState) { Log.i("MainActivity", "Started"); super.onCreate(savedInstanceState); setContentView(R.layout.main); setHandler(); setListing(); loadItems(); } @Override protected void onResume() { super.onResume(); if (isFirstRun() && haveCredentialsChanged()) { setFirstRun(false); } if (isFirstRun()) { firstRun(); } else if (haveCredentialsChanged()) { setCredentialsChanged(false); loadFiles(true, 0); } else { loadFiles(false, 0); } } @Override public Object onRetainNonConfigurationInstance() { return items; } @Override public boolean onCreateOptionsMenu(Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.menu, menu); this.menuItemProgress = menu.findItem(R.id.menuItemProgress); this.menuItemRefresh = menu.findItem(R.id.menuItemRefresh); return super.onCreateOptionsMenu(menu); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menuItemPreferences: startActivity(new Intent(MainActivity.this, PreferencesActivity.class)); break; case R.id.menuItemRefresh: loadFiles(true, 0); break; } return false; } private boolean isFirstRun() { return Prefs.getPreferences(this).getBoolean(Prefs.FIRST_RUN, true); } private void firstRun() { AlertDialog.Builder builder = new AlertDialog.Builder(this); builder.setMessage("First run"); builder.setCancelable(false); builder.setPositiveButton("ok", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { startActivity(new Intent(MainActivity.this, PreferencesActivity.class)); } }); AlertDialog alert = builder.create(); alert.show(); } private void setFirstRun(boolean b) { Prefs.getPreferences(this).edit().putBoolean(Prefs.FIRST_RUN, b).commit(); } private boolean haveCredentialsChanged() { return Prefs.getPreferences(this).getBoolean(Prefs.CREDENTIALS_CHANGED, false); } private void setCredentialsChanged(boolean b) { Prefs.getPreferences(this).edit().putBoolean(Prefs.CREDENTIALS_CHANGED, b).commit(); } private void setListing() { listView = (ListView) findViewById(R.id.listView); emptyView = (LinearLayout) findViewById(R.id.emptyView); listView.setOnItemClickListener(this); listView.setEmptyView(emptyView); } @SuppressWarnings("unchecked") private void loadItems() { Object obj = getLastNonConfigurationInstance(); if (obj != null) { items = (List<CloudAppItem>) obj; MainActivity.this.handler.sendEmptyMessage(0); } else { if (!isFirstRun()) loadFiles(true, 0); } } private void showProgressIcon(boolean show) { if(this.menuItemProgress != null && this.menuItemRefresh != null) { if(show) { this.menuItemProgress.setVisible(true); this.menuItemRefresh.setVisible(false); } else { this.menuItemRefresh.setVisible(true);
Everything works fine and works when the application starts. The problem occurs when you turn the phone.
Stack:
FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start activity ComponentInfo{com.quanturium.androcloud/com.quanturium.androcloud.MainActivity}: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.ProgressBar$SavedState at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1955) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1980) at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3347) at android.app.ActivityThread.access$700(ActivityThread.java:122) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1150) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:137) at android.app.ActivityThread.main(ActivityThread.java:4340) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:511) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551) at dalvik.system.NativeStart.main(Native Method) Caused by: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.ProgressBar$SavedState at android.widget.ProgressBar.onRestoreInstanceState(ProgressBar.java:1093) at android.view.View.dispatchRestoreInstanceState(View.java:9876) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330) at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:2330) at android.view.View.restoreHierarchyState(View.java:9854) at com.android.internal.policy.impl.PhoneWindow.restoreHierarchyState(PhoneWindow.java:1625) at android.app.Activity.onRestoreInstanceState(Activity.java:906) at android.app.Activity.performRestoreInstanceState(Activity.java:878) at android.app.Instrumentation.callActivityOnRestoreInstanceState(Instrumentation.java:1100) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1933) ... 12 more
The Layout action (@ + id / menuItemProgress) seems to be causing the problem. Everything is fine with the update item (@ + id / menuItemRefresh). I wrote as a comment where the problem is. When I comment out the line βPROBLEMβ: rotation works well.