The best answer I could come up with to my own question (a workaround).
First off I need to know if my ActionBar
is split or not, following this example. This is to determine whether use the default progress bar when the ActionBar
or not. When the ActionBar
is split my custom progress bar would end up on the bottom part of the ActionBar
, which is not desired.
/values/bools.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="split_action_bar">false</bool>
</resources>
/values-port/bools.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="split_action_bar">true</bool>
</resources>
/values-large/bools.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="split_action_bar">false</bool>
</resources>
In my activity, fetching the value with:
private boolean isActionBarSplitted() {
return getResources().getBoolean(R.bool.split_action_bar);
}
I have my option menu set up with my custom progress indicator MenuItem
to use when my app is on large devices or in landscape mode on narrow devices.
/menu/options_menu.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/custom_progress_indicator"
android:showAsAction="always"/>
<item
android:id="@+id/another_menu_item"
android:icon="@android:drawable/btn_default"
android:showAsAction="ifRoom"/>
<item
android:id="@+id/yet_another_menu_item"
android:icon="@android:drawable/btn_default"
android:showAsAction="ifRoom"/>
</menu>
In my Activity
I fetch the MenuItem
and disable it so it will truly be invisible, but not GONE
.
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
mCustomProgressIndicator = menu.findItem(R.id.custom_progress_indicator);
mCustomProgressIndicator.setEnabled(false);
return super.onPrepareOptionsMenu(menu);
}
Layout for the custom progress indicator:
/layout/custom_progress_bar.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ProgressBar android:id="@+id/progress"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
I have the two functions for start and stop indicating progress:
/**
* Indicates progress on the action bar
*/
private void startIndicatingProgress() {
mIndicatingProgress = true;
if (isActionBarSplitted()) {
// if we have a split action bar, use the default progress indicator
setProgressBarIndeterminateVisibility(true);
} else {
if (mCustomProgressIndicator != null) {
// this function may get called during onResume where
// mCustomProgressIndicator is not set
LayoutInflater inflater = (LayoutInflater)
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View progressBarLayoutView = inflater.inflate(
R.layout.custom_progress_bar, null);
View progressBar = progressBarLayoutView
.findViewById(R.id.progress);
LayoutParams layoutParams = progressBar.getLayoutParams();
// well now, not sure what the width of MenuItems is (since it
// seems impossible to find out)
// so adjusting the height of the ActionBar with 8, better than
// to hardcode a value I guess
layoutParams.width = actionBar.getHeight() + 8;
mCustomProgressIndicator.setActionView(progressBarLayoutView);
}
}
}
/**
* Returns true if the ActionBar is currently split
*
* @return
*/
private boolean isActionBarSplitted() {
return getResources().getBoolean(R.bool.split_action_bar);
}
/**
* Stops indicating progress
*/
private void stopIndicatingProgress() {
mIndicatingProgress = false;
// always stop default progress indicator
setProgressBarIndeterminateVisibility(false);
// this function may get called in onResume where
// mCustomProgressIndicator is not set
if (mCustomProgressIndicator != null) {
mCustomProgressIndicator.setActionView(null);
}
}
You'd think this would be ok, but no, when changing orientation my custom ProgressBar
gets shrinked, so I need to detect orientation changes and reset the custom progress bar. This is anyways a good idea for me, since on small devices I need to switch between default progress bar and custom since my activity is android:uiOptions="splitActionBarWhenNarrow"
:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE
|| newConfig.orientation == Configuration.ORIENTATION_PORTRAIT) {
if (mIndicatingProgress) {
// restart indicating progress to avoid feature of shrinking
// custom progress
// bar and switch between custom and default if needed
stopIndicatingProgress();
startIndicatingProgress();
}
// also remove custom progress indicator if split action bar
// so it won't take up space on the action bar when using
// default progress indicator
if (isActionBarSplitted()) {
// this seems to be the equivalent of View.setVisibility(View.GONE)
mCustomProgressIndicator.setVisible(false);
} else {
mCustomProgressIndicator.setVisible(true);
}
}
}