Android MenuItem setActionView(null) crash
On android 4.0.3 if you call MenuItem.setActionView(null) and then rotate the screen, my application will crash.
What I am trying to do is emulate the actionbar of the GMail app where if you click an item it turns into a progress bar.
However, it now saves the state of the ActionView and when it tries to restore it it says this.
Unable to start activity ComponentInfo{}: java.lang.ClassCastException: android.view.AbsSavedState$1 cannot be cast to android.widget.ProgressBar$SavedState
Does anyone have working code for this? or a way to fix it?
Oh I use actionbarsherlock if that matter. It shouldn't because on 4.03 it just calls all the system calls.
Code:
OnCreate() refreshMenuActionView = new ProgressBar(this.getActivity()); refreshMenuActionView.setIndeterminateDrawable(this.getActivity().getResources().getDrawable(R.drawable.refresh_spinner)); AsyncTask.onPostExecute if ( refreshMenuItem != null ) { refreshMenuItem.setActionView(null); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.loadable_menu, menu); refreshMenuItem = menu.findItem(R.id.refreshMenuItem); if ( downloader != null && downloader.getStatus() == AsyncTask.Status.RUNNING ) { refreshMenuItem.setActionView(refreshMenuActionView); } searchMenuItem = menu.findItem(R.id.searchMenuItem); super.onCreateOptionsMenu(menu, inflater); }
XML:
<?xml version="1.0" encoding="utf-8"?> <menu xmlns:android="http://schemas.android.com/apk/res/android" > <item android:id="@+id/refreshMenuItem" android:title="@string/refresh_item_title" android:icon="@drawable/ic_menu_refresh" android:showAsAction="ifRoom" /> <item android:id="@+id/searchMenuItem" android:title="@string/search_item_title" android:icon="@drawable/ic_menu_search" android:showAsAction="always" /> </menu>
Answers
Could you post a bit more of the code around the click that turns into a ProgressBar?
I use ABS and here's some code that launches an AsyncTask and ProgressBar when the user clicks a button (the code is inside a SherlockFragment):
public class LoginFragment extends SherlockFragment { ... loginButton = (Button) getActivity().findViewById(R.id.loginButton); loginButton.setOnClickListener(loginListener); public OnClickListener loginListener = new OnClickListener() { @Override public void onClick(View v) { ProgressDialog progressDialog = new ProgressDialog(getActivity()); progressDialog.setMessage("Logging in..."); LoginTask loginTask = new LoginTask((Polling) getActivity(), progressDialog); loginTask.execute();
Then, the ProgressDialog is controlled throughout the ASyncTask (setVisibility in each method):
public class LoginTask extends AsyncTask<String, Void, Integer> { private ProgressDialog progressDialog; private Polling activity; private int id = -1; private JSONParser jsonParser; private static String loginURL = ""; private static String registerURL = ""; private static String KEY_SUCCESS = "success"; private static String KEY_ERROR = "error"; private static String KEY_ERROR_MSG = "error_msg"; private static String KEY_UID = "uid"; private static String KEY_NAME = "name"; private static String KEY_EMAIL = "email"; private static String KEY_CREATED_AT = "created_at"; private int responseCode = 0; public LoginTask(Polling activity, ProgressDialog progressDialog) { this.activity = activity; this.progressDialog = progressDialog; } @Override protected void onPreExecute() { progressDialog.show(); } protected Integer doInBackground(String... arg0) { // check for login response try { if (json.getString(KEY_SUCCESS) != null) { String res = json.getString(KEY_SUCCESS); if(Integer.parseInt(res) == 1){ //user successfully logged in // Store user details in SQLite Database DatabaseHandler db = new DatabaseHandler(activity.getApplicationContext()); JSONObject json_user = json.getJSONObject("user"); //Log.v("name", json_user.getString(KEY_NAME)); // Clear all previous data in database userFunction.logoutUser(activity.getApplicationContext()); db.addUser(json_user.getString(KEY_NAME), json_user.getString(KEY_EMAIL), json.getString(KEY_UID), json_user.getString(KEY_CREATED_AT)); responseCode = 1; // Close Login Screen //finish(); }else{ responseCode = 0; // Error in login } } } catch (NullPointerException e) { e.printStackTrace(); } catch (JSONException e) { e.printStackTrace(); } return responseCode; } @Override protected void onPostExecute(Integer responseCode) { if (responseCode == 1) { progressDialog.dismiss(); activity.loginReport(responseCode); } if (responseCode == 0) { progressDialog.dismiss(); activity.loginReport(responseCode); } }
}