Showing refreshing message in Action Bar

≡放荡痞女 提交于 2019-12-08 03:19:07

问题


I'm using an Action Bar (a regular one, not sherlock) in my android app, and when the app opens I want to show a refreshing message in the action bar. This means I want to hide the menu items and title (similar to how the GMail app appears when it's refreshing).

What is the best approach for this? Is it using a contextual action bar?

Is it possible to show the refreshing animation just below the action bar, like in the GMail app (ie, the blue lines sliding over).

I know I can use a 3rd party pull-to-refresh, but I'd prefer not to use this (as I don't need the pull-to-refresh capability).

I'm targeting Jelly Bean and newer devices.

Thanks!


回答1:


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.



来源:https://stackoverflow.com/questions/23145206/showing-refreshing-message-in-action-bar

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