将带计数器的按钮添加到工具栏中

时间:2016-05-11 10:22:48

标签: android toolbar android-custom-view

我的工具栏

enter image description here

如何在购物车下制作计数器?

enter image description here

3 个答案:

答案 0 :(得分:7)

这应该是实现这个目标的方法

  • 创建一个BadgeDrawable类,用于绘制通知计数以及令人eye目的红色背景圈(如屏幕截图所示)。
  • 在XML中定义LayerDrawable以设置为MenuItem的android:图标。 LayerDrawable的底层是MenuItem的图标(通常是.png),顶层是BadgeDrawable。
  • 模拟查询Activity中的通知计数,更新BadgeDrawable的计数,然后调用Activity#invalidateOptionsMenu()强制ActionBar菜单刷新。

输出

enter image description here

<强> 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;
    }
}

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

现在位于 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);
        }
    }
}

实用工具类 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

答案 1 :(得分:1)

你必须为它创建一个自定义drawable(我让你找到如何以你想要的方式创建一个)。让我们称之为myDrawable。然后在菜单xml文件中引用它:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/myMenuId"
        android:icon="@drawable/myDrawable"
        android:showAsAction="always" />

</menu>

答案 2 :(得分:1)