即使不可见,如何让操作栏上的进度条占用空间?

时间:2013-08-29 15:10:00

标签: android android-actionbar

我需要在ActionBar上设置进度指示器以占用空间,即使它不可见。

我正在使用:

requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true);

然后:

setProgressBarIndeterminateVisibility(false);

这似乎将进度条的可见性设置为GONE而不是INVISIBLE,这使得操作栏上的动态标签数量会暂时移动并暂时删除我的应用标题,直到完成进度。

考虑在操作栏上添加一个空操作,我可以在指示进度之前将其删除,并在完成后再次添加。还有另一种不那么混乱的方法吗?

1 个答案:

答案 0 :(得分:0)

我可以提出自己的问题(解决方法)的最佳答案。

首先,我需要知道我的ActionBar是否被分割,遵循this示例。这是为了确定在ActionBar时是否使用默认进度条。分割ActionBar时,我的自定义进度条最终会显示在ActionBar的底部,这是不可取的。

<强> /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>

在我的活动中,使用以下内容获取值:

private boolean isActionBarSplitted() {
    return getResources().getBoolean(R.bool.split_action_bar);
}

我的选项菜单设置了我的自定义进度指示器MenuItem,以便在我的应用在大型设备上时使用,或在窄设备上以横向模式使用。

/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>

在我的Activity我获取MenuItem并禁用它,以便它真的不可见,但不是GONE

@Override
public boolean onPrepareOptionsMenu(Menu menu) {
    mCustomProgressIndicator = menu.findItem(R.id.custom_progress_indicator);
    mCustomProgressIndicator.setEnabled(false);
    return super.onPrepareOptionsMenu(menu);
}

自定义进度指示器的布局:

<强> /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>

我有两个启动和停止功能指示进度:

/**
 * 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);
    }
}

您认为这样可以,但不是,在更改方向时,我的自定义ProgressBar会缩小,因此我需要检测方向更改并重置自定义进度条。这对我来说无疑是一个好主意,因为在小型设备上我需要在默认进度条和自定义之间切换,因为我的活动是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);
        }
    }
}