Showing refreshing message in Action Bar

早过忘川 提交于 2019-12-06 15:50:17

I want to hide the menu items and title (similar to how the GMail app appears when it's refreshing).

This can be done by using WindowManager.addView(View, LayoutParams). Here's an example of displaying a message on top of the ActionBar that should give you a pretty solid idea about how to proceed.

The layout

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/message"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:gravity="center"
    android:textColor="@android:color/white"
    android:textSize="18sp" />

Implementation

/** The attribute depicting the size of the {@link ActionBar} */
private static final int[] ACTION_BAR_SIZE = new int[] {
        android.R.attr.actionBarSize
};

/** The notification layout */
private TextView mMessage;

private void showLoadingMessage() {
    // Remove any previous notifications
    removeLoadingMessage();

    // Initialize the layout
    if (mMessage == null) {
        final LayoutInflater inflater = getLayoutInflater();
        mMessage = (TextView) inflater.inflate(R.layout.your_layout, null);
        mMessage.setBackgroundColor(getResources().getColor(android.R.color.holo_blue_dark));
        mMessage.setText("Loading...");
    }

    // Add the View to the Window
    getWindowManager().addView(mMessage, getActionBarLayoutParams());
}

private void removeLoadingMessage() {
    if (mMessage != null && mMessage.getWindowToken() != null) {
        getWindowManager().removeViewImmediate(mMessage);
        mMessage = null;
    }
}

/**
 * To use, @see {@link WindowManager#addView(View, LayoutParams)}
 * 
 * @return The {@link WindowManager.LayoutParams} to assign to a
 *         {@link View} that can be placed on top of the {@link ActionBar}
 */
private WindowManager.LayoutParams getActionBarLayoutParams() {
    // Retrieve the height of the status bar
    final Rect rect = new Rect();
    getWindow().getDecorView().getWindowVisibleDisplayFrame(rect);
    final int statusBarHeight = rect.top;

    // Retrieve the height of the ActionBar
    final TypedArray actionBarSize = obtainStyledAttributes(ACTION_BAR_SIZE);
    final int actionBarHeight = actionBarSize.getDimensionPixelSize(0, 0);
    actionBarSize.recycle();

    // Create the LayoutParams for the View
    final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            LayoutParams.MATCH_PARENT, actionBarHeight,
            WindowManager.LayoutParams.TYPE_APPLICATION_PANEL,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.TOP;
    params.x = 0;
    params.y = statusBarHeight;
    return params;
}

Results

Conclusion

This implementation is very similar to Gmail and other apps, minus the pull-to-refresh pattern.

When you call showLoadingMessage, post a Runnable or use a View.OnClickListener. You don't want to call WindowManager.addView too early or you'll throw a WindowManager.BadTokenException. Also, it's important to call removeLoadingMessage in Activity.onDestroy, otherwise you run the risk of leaking the View you add to the Window.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!