在Android Action Bar Activity中如何添加菜单以及通知计数?

时间:2015-01-30 07:45:46

标签: android android-actionbar

Android的新手。在我的应用程序中,我需要使用操作栏添加菜单。我使用android:icon="@drawable/bell"创建了一个菜单。但我还需要在菜单上方添加文本。

我尝试了androidlayout(android:actionLayout="@layout/feed_update_count")但没有得到解决方案。

我的菜单代码

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.example.qh_test.GkPageActivity" >

    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never"/>
   <item
        android:id="@+id/flag_noty"
        android:title="@string/flag_noty"
        android:icon="@drawable/bell"
        app:showAsAction="ifRoom"/>         
</menu>

我的实际输出

Actual Output

我的预期输出

Expected Output

请帮助我如何在钟形菜单上方添加计数部分。提前谢谢。

2 个答案:

答案 0 :(得分:1)

你好我能为你提供一个更好的&#34;更清洁的解决方案。

这是一个名为ActionBarSherlock的库,它非常有用且易于设置和实现。

它为操作栏提供了非常方便的附加功能,它将简化您的应用程序开发。

为了使用它,您必须在Sherlock lib中扩展已定义的Activity。

设置:

  1. 从Git
  2. 获取项目
  3. 在Eclipse中导入
  4. 将您的项目设置为&#34;依赖&#34;关于进口的Sherlock项目
  5. 观看有关如何实施它的一些教程
  6. http://actionbarsherlock.com/

    http://www.grokkingandroid.com/adding-actionbarsherlock-to-your-project/

    习惯这个库是一个非常好的主意,因为它经常使用了很多:)

    很抱歉没有提供链接,但我没有所需的声誉。

    如果您对实施有任何问题,可以搜索Stackoverflow.com,因为它充满了这些问题。

    祝你好运:)

答案 1 :(得分:0)

您好我可以告诉您最好的方法,我不认为为此目的您必须使用任何lib。因此,为了满足您的要求,请按照以下步骤操作。

步骤1): - 创建自定义视图类(下面给出BadgeIcon)

public class BadgeIcon extends ImageView {

public static final int TOP_LEFT = 1;
public static final int TOP_RIGHT = 2;
public static final int BOTTOM_RIGHT = 3;
public static final int BOTTOM_LEFT = 4;
public static final int TOP_CENTER = 5;
public static final int RIGHT_CENTER = 6;
public static final int BOTTOM_CENTER = 7;
public static final int LEFT_CENTER = 8;
public static final int CENTER = 9;

private static final int DEFAULT_BADGE_TEXT_COLOR = 0xffff0000;
private static final int DEFAULT_BADGE_BG_COLOR = 0xff00ff00;
private static final int DEFAULT_BADGE_PADDING = 4;
private static final int DEFAULT_BADGE_TEXT_SIZE = 18;
private static final int DEFAULT_BADGE_MARGIN = 0;

private static final String TAG = "IconBadge";
private Paint mBackgroundPaint;
private TextPaint mPaint;
private StaticLayout mTextLayout;
private CharSequence mBadgeText;
private CharSequence mNewText;

private int mBadgeTextSize = DEFAULT_BADGE_TEXT_SIZE;
private int mBadgeTextColor = DEFAULT_BADGE_TEXT_COLOR;
private int mBadgeBackgroundColor = DEFAULT_BADGE_BG_COLOR;
private int mBadgePadding = DEFAULT_BADGE_PADDING;
private int mBadgePosition = TOP_RIGHT;
private int mPrevBadgeTextSize = DEFAULT_BADGE_TEXT_SIZE;
private int mLeftMargin = DEFAULT_BADGE_MARGIN;
private int mRightMargin = DEFAULT_BADGE_MARGIN;
private int mTopMargin = DEFAULT_BADGE_MARGIN;
private int mBottomMargin = DEFAULT_BADGE_MARGIN;

public BadgeIcon(Context context) {
    super(context);
    init(context, null);
}

public BadgeIcon(Context context, AttributeSet attrs) {
    super(context, attrs);
    init(context, attrs);
}

public BadgeIcon(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
    init(context, attrs);
}

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public BadgeIcon(Context context, AttributeSet attrs, int defStyleAttr, int 
defStyleRes) {
    super(context, attrs, defStyleAttr, defStyleRes);
    init(context, attrs);
}

private void init(Context context, AttributeSet attrs) {

    if (attrs != null) {
        TypedArray a = context.obtainStyledAttributes(attrs, 
     R.styleable.BadgeIcon);
        mBadgePosition = a.getInteger(R.styleable.BadgeIcon_badgePosition, 
   TOP_LEFT);
        mBadgeBackgroundColor = 
 a.getColor(R.styleable.BadgeIcon_badgeBackgroundColor, 
 DEFAULT_BADGE_BG_COLOR);
        mBadgePadding = a.getDimensionPixelOffset(R.styleable.BadgeIcon_badgeTextPadding, DEFAULT_BADGE_PADDING);
        mBadgeTextColor = a.getColor(R.styleable.BadgeIcon_badgeTextColor, DEFAULT_BADGE_TEXT_COLOR);
        mBadgeTextSize = a.getDimensionPixelSize(R.styleable.BadgeIcon_badgeTextSize, DEFAULT_BADGE_TEXT_SIZE);
        mBadgeText = a.getText(R.styleable.BadgeIcon_badgeText);
        mLeftMargin = a.getDimensionPixelOffset(R.styleable.BadgeIcon_badgeMarginLeft, DEFAULT_BADGE_MARGIN);
        mRightMargin = a.getDimensionPixelOffset(R.styleable.BadgeIcon_badgeMarginRight, DEFAULT_BADGE_MARGIN);
        mTopMargin = a.getDimensionPixelOffset(R.styleable.BadgeIcon_badgeMarginTop, DEFAULT_BADGE_MARGIN);
        mBottomMargin = a.getDimensionPixelOffset(R.styleable.BadgeIcon_badgeMarginBottom, DEFAULT_BADGE_MARGIN);

        if (a.hasValue(R.styleable.BadgeIcon_badgeMargin)) {
            int margin = a.getDimensionPixelOffset(R.styleable.BadgeIcon_badgeMargin, DEFAULT_BADGE_MARGIN);
            mLeftMargin = margin;
            mRightMargin = margin;
            mBottomMargin = margin;
            mTopMargin = margin;
        }

        a.recycle();
    }

    mPaint = new TextPaint();
    mPaint.setTextSize(mBadgeTextSize);
    mPaint.setAntiAlias(true);
    mPaint.setColor(mBadgeTextColor);

    mBackgroundPaint = new Paint();
    mBackgroundPaint.setColor(mBadgeBackgroundColor);
    mBackgroundPaint.setAntiAlias(true);
    mBackgroundPaint.setStyle(Paint.Style.FILL);

    mPrevBadgeTextSize = mBadgeTextSize;

    if (isInEditMode()) {
        setBadgeText("2");
    }
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    int width = MeasureSpec.getSize(widthMeasureSpec);

    // Create a layout for sub-text.
    if (mNewText != null && !mNewText.equals(mBadgeText)) {
        mBadgeText = mNewText;
        generateNewStaticLayout(width);

    } else if (mPrevBadgeTextSize != mBadgeTextSize) {
        // change in text size
        generateNewStaticLayout(width);
        mPrevBadgeTextSize = mBadgeTextSize;
    }
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}

private void generateNewStaticLayout(int width) {
    mTextLayout = new StaticLayout(
            mBadgeText,
            mPaint,
            width,
            Layout.Alignment.ALIGN_NORMAL,
            1.0f,
            0.0f,
            true);
}

public void setBadgeText(CharSequence text) {

    if (text == null) {
        return;
    }

    int width = getMeasuredWidth();
    if (width == 0) {
        mNewText = text;
        return;
    }

    boolean change = true;

    if (mTextLayout != null) {
        if (mBadgeText != null && mBadgeText.equals(text)) {
            change = false;
        }
    }

    mBadgeText = text;
    if (change) {
        generateNewStaticLayout(width);
        mNewText = mBadgeText;
        requestLayout();
        invalidate();
    }
}

@Override
public void onDraw(Canvas c) {
    super.onDraw(c);

    if (mTextLayout != null && mBadgeText != null && mBadgeText.length() != 
 0) {

        int w = (int)mTextLayout.getLineWidth(0);
        int b = mTextLayout.getLineBottom(0);
       // Log.i(TAG, w + ", " + b + ", " + mBadgePosition);
        c.save();

        int d = Math.max(w, b);
        if (d % 2 == 1) {
            d += 1;
        }

        int cx = c.getWidth()/2;
        int cy = c.getHeight()/2;

        /*int paddingRight = getPaddingRight();
        int paddingLeft = getPaddingLeft();
        int paddingBottom = getPaddingBottom();
        int paddingTop = getPaddingTop();*/

        int paddingRight = mRightMargin;
        int paddingLeft = mLeftMargin;
        int paddingBottom = mBottomMargin;
        int paddingTop = mTopMargin;

        /*paddingRight = 0;
        paddingLeft = 0;
        paddingTop = 0;
        paddingBottom = 0;*/

        if (mBadgePosition == TOP_RIGHT) {
            cx = c.getWidth() - paddingRight - (d / 2 + mBadgePadding);
            cy = paddingTop + (d / 2 + mBadgePadding);
        } else if (mBadgePosition == TOP_LEFT) {
            cx = paddingLeft + (d/2 + mBadgePadding);
            cy = paddingTop + (d / 2 + mBadgePadding);
        } else if (mBadgePosition == BOTTOM_LEFT) {
            cx = paddingLeft+ (d/2 + mBadgePadding);
            cy = c.getHeight() - paddingBottom - (d / 2 + mBadgePadding);
        } else if (mBadgePosition == BOTTOM_RIGHT) {
            cx = c.getWidth() - paddingRight - (d / 2 + mBadgePadding);
            cy = c.getHeight() - paddingBottom - (d / 2 + mBadgePadding);
        } else if (mBadgePosition == LEFT_CENTER) {
            cx = paddingLeft + (d/2 + mBadgePadding);
            cy = c.getHeight()/2;
        } else if (mBadgePosition == RIGHT_CENTER) {
            cx = c.getWidth() - paddingRight - (d / 2 + mBadgePadding);
            cy = c.getHeight()/2;
        } else if (mBadgePosition == TOP_CENTER) {
            cx = c.getWidth()/2;
            cy = paddingTop + (d / 2 + mBadgePadding);
        } else if (mBadgePosition == BOTTOM_CENTER) {
            cx = c.getWidth()/2;
            cy = c.getHeight() - paddingBottom - (d / 2 + mBadgePadding);
        }

        int l = cx - (w / 2);
        int t = cy - (b / 2);

        c.drawCircle(cx, cy, d/2 + mBadgePadding, mBackgroundPaint);

        c.translate(l, t);
        mTextLayout.draw(c);
        c.restore();
    }
}

public void setBadgeTextSize(int mBadgeTextSize) {

    if (this.mBadgeTextSize == mBadgeTextSize) {
        // no change
        return;
    }

    this.mBadgeTextSize = mBadgeTextSize;
    mPaint.setTextSize(mBadgeTextSize);

    int width = getMeasuredWidth();
    if (width == 0) {
        return;
    }

    mTextLayout = new StaticLayout(mBadgeText, mPaint, width,
            Layout.Alignment.ALIGN_NORMAL, 1.0f, 0.0f, true);
    mPrevBadgeTextSize = mBadgeTextSize;
    requestLayout();
    invalidate();
}

public void setBadgeTextColor(int mBadgeTextColor) {
    if (this.mBadgeTextColor == mBadgeTextColor) {
        // no change
        return;
    }

    this.mBadgeTextColor = mBadgeTextColor;
    mPaint.setColor(mBadgeTextColor);
    invalidate();
}

public void setBadgeBackgroundColor(int mBadgeBackgroundColor) {
    if (this.mBadgeBackgroundColor == mBadgeBackgroundColor) {
        // no change
        return;
    }

    this.mBadgeBackgroundColor = mBadgeBackgroundColor;
    invalidate();
}

public void setBadgePadding(int mBadgePadding) {
    if (this.mBadgePadding == mBadgePadding) {
        // no change
        return;
    }
    this.mBadgePadding = mBadgePadding;
    invalidate();
}

public void setBadgePosition(int position) {
    if (this.mBadgePosition == position) {
        // no change
        return;
    }
    this.mBadgePosition = position;
    invalidate();
}

public void setLeftMargin(int mLeftMargin) {
    this.mLeftMargin = mLeftMargin;
    invalidate();
}

public void setRightMargin(int mRightMargin) {
    this.mRightMargin = mRightMargin;
    invalidate();
}

public void setTopMargin(int mTopMargin) {
    this.mTopMargin = mTopMargin;
    invalidate();
}

public void setBottomMargin(int mBottomMargin) {
    this.mBottomMargin = mBottomMargin;
    invalidate();
}

public void setMargin(int margin) {
    mTopMargin = margin;
    mBottomMargin = margin;
    mLeftMargin = margin;
    mRightMargin = margin;
    invalidate();
}
}

步骤2: - 在attr.xml中编写这些自定义属性

<declare-styleable name="BadgeIcon">
    <attr name="badgeTextSize" format="dimension"/>
    <attr name="badgeTextColor" format="color"/>
    <attr name="badgeTextPadding" format="dimension"/>
    <attr name="badgeBackgroundColor" format="color"/>
    <attr name="badgeText" format="string"/>
    <attr name="badgePosition">
        <flag name="top_left" value="0x01"/>
        <flag name="top_right" value="0x02"/>
        <flag name="bottom_right" value="0x03"/>
        <flag name="bottom_left" value="0x04"/>
        <flag name="top_center" value="0x05"/>
        <flag name="right_center" value="0x06"/>
        <flag name="bottom_center" value="0x07"/>
        <flag name="left_center" value="0x08"/>
        <flag name="center" value="0x09"/>
    </attr>
    <attr name="badgeMarginTop" format="dimension"/>
    <attr name="badgeMarginBottom" format="dimension"/>
    <attr name="badgeMarginRight" format="dimension"/>
    <attr name="badgeMarginLeft" format="dimension"/>
    <attr name="badgeMargin" format="dimension"/>
</declare-styleable>

步骤3: - 在活动工具栏中添加此BadgeIcon

<android.support.design.widget.AppBarLayout
        android:id="@+id/appbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:fitsSystemWindows="true"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:contentInsetLeft="0dp"
            android:contentInsetStart="0dp"
            android:elevation="0dp"
            android:fitsSystemWindows="false"
            android:transitionName="@string/transition_background"
            app:contentInsetLeft="0dp"
            app:contentInsetStart="0dp"
            app:contentInsetStartWithNavigation="0dp"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            tools:targetApi="21">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent">


                <BadgeIcon
                    android:id="@+id/notification_button"
                    android:layout_width="@dimen/home_top_icon_size"
                    android:layout_height="@dimen/home_top_icon_size"
                    android:layout_gravity="center_vertical"
                    android:background="@drawable/background_transp_ripple"
                    android:paddingLeft="@dimen/home_top_icon_padding"
                    android:paddingRight="@dimen/home_top_icon_padding"
                    android:src="@drawable/ic_notifications_white_24dp"
                    app:badgeBackgroundColor="@color/theme_app"
                    app:badgeMargin="@dimen/home_top_icon_badge_margin"
                    app:badgePosition="top_right"
                    app:badgeText="144"
                    app:badgeTextColor="@color/white_100_percent"
                    app:badgeTextPadding="2dp"
                    app:badgeTextSize="8sp" />

            </LinearLayout>

        </android.support.v7.widget.Toolbar>

步骤4: - 当没有读数时,你必须设置空文本,如:

   if (count != 0) {
        mNotificationButton.setBadgeText(String.valueOf(count));
    } else {
        mNotificationButton.setBadgeText("");
    }

我希望你能实现这一点。此自定义类可帮助您在任何图标上方显示文本。