0

Am new to Android.In My App i need to add menu using Action Bar.I created a menu using android:icon="@drawable/bell".But i also need to add text above the menu.

I tried androidlayout (android:actionLayout="@layout/feed_update_count") but not getting the solution.

My Menu Code

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

My Actual Output

Actual Output

My Expected output

Expected Output

Please help me how can i add the count part above the bell menu.Thanks in advance.

user3824494
  • 101
  • 2
  • 9
  • You can try this http://stackoverflow.com/questions/17696486/actionbar-notification-count-icon-like-google-have – Dmitriy Puchkov Jan 30 '15 at 08:28
  • Hi @gabber.I checked the above link.There giving the solution for Action Bar.It will work for API 11 and above.But am using ActionBarActivity which is a support library.I want to know how to do with using this support library. – user3824494 Jan 30 '15 at 12:06

2 Answers2

1

Hello I'm going to offer you a "better" and cleaner solution.

This is a library called ActionBarSherlock it's very useful and easy to setup and implement.

It provides very handy additional features to the action bar and it will simplify your app development.

In order to use it, you must extend the defined Activity in Sherlock lib.

To setup:

  1. Get the project from Git
  2. Import in Eclipse
  3. Setup your project to "depend" on the imported Sherlock project
  4. Watch some tutorials on how to implement it

http://actionbarsherlock.com/

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

It is a very nice idea to get used to this library because it's used a lot :)

Sorry for not providing links, but I don't have the needed reputation.

If you have any problems with the implementation you can search Stackoverflow.com because it's full of such issues.

Good luck implementing :)

Stuci
  • 571
  • 1
  • 5
  • 13
0

Hello I can tell you best approach, I dont think that for this purpose you have to use any lib. So to fulfill your requirement please follow these steps.

Step 1):- Create a custom view class (BadgeIcon is given below)

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();
}
}

Step 2:- write these custom attribute in 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>

Step 3:- Add this BadgeIcon in toolbar of your activity

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

Step 4:- you must set empty text when there is no read count like as:

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

I hope you would like to implement this. This custom class helps you to show text above any icon which you want.

Sandeep Sankla
  • 1,250
  • 12
  • 21