Add button with a counter into the toolbar

后端 未结 3 1728
无人共我
无人共我 2021-01-16 22:56

My ToolBar

How can I make counter under the cart?

相关标签:
3条回答
  • 2021-01-16 23:09

    You have to create a custom drawable for that (I let you find how to create one the way you want it). Lets call it myDrawable. Then in your menu xml file you reference it with:

    <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
        <item
            android:id="@+id/myMenuId"
            android:icon="@drawable/myDrawable"
            android:showAsAction="always" />
    
    </menu>
    
    0 讨论(0)
  • 2021-01-16 23:22

    This should be the approach to achieve this

    • Create a BadgeDrawable class that draws a count of notification plus an eye-popping red background circle (like in the screenshot ).
    • Define a LayerDrawable in XML to set as the android:icon of our MenuItem. The bottom layer of the LayerDrawable is the MenuItem's icon (typically a .png), and the top layer is the BadgeDrawable.
    • Simulate querying the count of notifications in our Activity, update the BadgeDrawable's count, then call Activity#invalidateOptionsMenu() to force the ActionBar Menu to refresh.

    Output will be

    BadgeDrawable.java

    public class BadgeDrawable extends Drawable {
    
        private float mTextSize;
        private Paint mBadgePaint;
        private Paint mTextPaint;
        private Rect mTxtRect = new Rect();
    
        private String mCount = "";
        private boolean mWillDraw = false;
    
        public BadgeDrawable(Context context) {
            mTextSize = context.getResources().getDimension(R.dimen.badge_text_size);
    
            mBadgePaint = new Paint();
            mBadgePaint.setColor(Color.RED);
            mBadgePaint.setAntiAlias(true);
            mBadgePaint.setStyle(Paint.Style.FILL);
    
            mTextPaint = new Paint();
            mTextPaint.setColor(Color.WHITE);
            mTextPaint.setTypeface(Typeface.DEFAULT_BOLD);
            mTextPaint.setTextSize(mTextSize);
            mTextPaint.setAntiAlias(true);
            mTextPaint.setTextAlign(Paint.Align.CENTER);
        }
    
        @Override
        public void draw(Canvas canvas) {
            if (!mWillDraw) {
                return;
            }
    
            Rect bounds = getBounds();
            float width = bounds.right - bounds.left;
            float height = bounds.bottom - bounds.top;
    
            // Position the badge in the top-right quadrant of the icon.
            float radius = ((Math.min(width, height) / 2) - 1) / 2;
            float centerX = width - radius - 1;
            float centerY = radius + 1;
    
            // Draw badge circle.
            canvas.drawCircle(centerX, centerY, radius, mBadgePaint);
    
            // Draw badge count text inside the circle.
            mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect);
            float textHeight = mTxtRect.bottom - mTxtRect.top;
            float textY = centerY + (textHeight / 2f);
            canvas.drawText(mCount, centerX, textY, mTextPaint);
        }
    
        /*
        Sets the count (i.e notifications) to display.
         */
        public void setCount(int count) {
            mCount = Integer.toString(count)
    
            // Only draw a badge if there are notifications.
            mWillDraw = count > 0;
            invalidateSelf();
        }
    
        @Override
        public void setAlpha(int alpha) {
            // do nothing
        }
    
        @Override
        public void setColorFilter(ColorFilter cf) {
            // do nothing
        }
    
        @Override
        public int getOpacity() {
            return PixelFormat.UNKNOWN;
        }
    }
    

    For /res/drawable/ic_menu_notifications.xml

    <?xml version="1.0" encoding="utf-8"?>
    <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
        <item
            android:id="@+id/ic_notification"
            android:drawable="@drawable/ic_action_email"
            android:gravity="center" />
    
        <!-- set a place holder Drawable so android:drawable isn't null -->
        <item
            android:id="@+id/ic_badge"
            android:drawable="@drawable/ic_action_email" />
    </layer-list>
    

    /res/menu/menu_home.xml

    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:id="@+id/action_notifications"
            android:title="Notifications"
            android:icon="@drawable/ic_menu_notifications"
            android:showAsAction="always"/>
    </menu>
    

    Now in the HomeActivity.java

    public class HomeActivity extends Activity {
    
        private int mNotificationsCount = 0;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_home);
    
            // Run a task to fetch the notifications count
            new FetchCountTask().execute();
        }
    
    
        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
            getMenuInflater().inflate(R.menu.home, menu);
    
            // Get the notifications MenuItem and 
            // its LayerDrawable (layer-list)
            MenuItem item = menu.findItem(R.id.action_notifications);
            LayerDrawable icon = (LayerDrawable) item.getIcon();
    
            // Update LayerDrawable's BadgeDrawable
            Utils.setBadgeCount(this, icon, mNotificationsCount);
    
            return true;
        }
    
        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
            if (item.getItemId() == R.id.action_notifications) {
                // TODO: display unread notifications.
                return true;
            }
            return super.onOptionsItemSelected(item);
        }
    
        /*
        Updates the count of notifications in the ActionBar.
         */
        private void updateNotificationsBadge(int count) {
            mNotificationsCount = count;
    
            // force the ActionBar to relayout its MenuItems.
            // onCreateOptionsMenu(Menu) will be called again.
            invalidateOptionsMenu(); 
        }
    
        /*
        Sample AsyncTask to fetch the notifications count
        */
        class FetchCountTask extends AsyncTask<Void, Void, Integer> {
    
            @Override
            protected Integer doInBackground(Void... params) {
                // example count. This is where you'd 
                // query your data store for the actual count.
                return 5; 
            }
    
            @Override
            public void onPostExecute(Integer count) {
                updateNotificationsBadge(count);
            }
        }
    }
    

    Utility class Utils.java

    public class Utils {
    
        public static void setBadgeCount(Context context, LayerDrawable icon, int count) {
    
            BadgeDrawable badge;
    
            // Reuse drawable if possible
            Drawable reuse = icon.findDrawableByLayerId(R.id.ic_badge);
            if (reuse != null && reuse instanceof BadgeDrawable) {
                badge = (BadgeDrawable) reuse;
            } else {
                badge = new BadgeDrawable(context);
            }
    
            badge.setCount(count);
            icon.mutate();
            icon.setDrawableByLayerId(R.id.ic_badge, badge);
        }
    }
    

    Reference Link for Full Code

    0 讨论(0)
  • 2021-01-16 23:27

    Follow this links,

    http://www.viralandroid.com/2016/01/adding-badge-notification-count-to-android-actionbar-icon.htmlenter link description here

    https://github.com/mikepenz/Android-ActionItemBadgeenter link description here

    0 讨论(0)
提交回复
热议问题