Dodaj licznik znaczków do ikony menu nawigacyjnego hamburgera w Androidzie

Moje pytanie jest takie samo jak to pytanie (które jest , a nie duplikatem tego pytania ).

Jedyna odpowiedź na to pytanie nie działa mi jak, zamiast zmieniać domyślną ikonkę hamburgera na zostawić tytułu działania, dodaje tylko dodatkową ikonę hamburgera do prawo tytułu mojej działalności.

Więc jak właściwie dostać to:

Ikona hamburgera Android z licznikiem odznak

Grzebałem w tym cały dzień, ale nigdzie nie mam.

Widzę, że Toolbar mA metodę setNavigationIcon(Drawable drawable). Idealnie, chciałbym użyć layout (który zawiera ikonę hamburgera i widok odznaki) zamiast Drawable, ale nie jestem pewien, czy/jak to jest osiągalne-lub czy jest lepszy sposób?

uwaga-to nie jest pytanie o to, jak utworzyć widok znaczka. Już to stworzyłem i zaimplementowałem na nav same pozycje menu. Więc jestem teraz po prostu trzeba dodać podobny widok znaczek do domyślnej ikony hamburgera.

Author: Andrew T., 2017-05-09

1 answers

Od wersji 24.2.0 biblioteki wsparcia, Wersja V7 ActionBarDrawerToggle oferuje metodę setDrawerArrowDrawable() jako sposób na dostosowanie ikony przełączania. {[6] } jest klasą, która zapewnia domyślną ikonę i może być podklasowana, aby zmienić ją w razie potrzeby.

Jako przykład, klasa BadgeDrawerArrowDrawable nadpisuje metodę draw(), aby dodać podstawową czerwoną i białą plakietkę po losowaniu klasy superclass. Pozwala to na zachowanie animacji strzałek hamburgera pod spodem.

import android.content.Context;
import android.graphics.Color;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.support.v7.graphics.drawable.DrawerArrowDrawable;
import java.util.Objects;

public class BadgeDrawerArrowDrawable extends DrawerArrowDrawable {

    // Fraction of the drawable's intrinsic size we want the badge to be.
    private static final float SIZE_FACTOR = .3f;
    private static final float HALF_SIZE_FACTOR = SIZE_FACTOR / 2;

    private Paint backgroundPaint;
    private Paint textPaint;
    private String text;
    private boolean enabled = true;

    public BadgeDrawerArrowDrawable(Context context) {
        super(context);

        backgroundPaint = new Paint();
        backgroundPaint.setColor(Color.RED);
        backgroundPaint.setAntiAlias(true);

        textPaint = new Paint();
        textPaint.setColor(Color.WHITE);
        textPaint.setAntiAlias(true);
        textPaint.setTypeface(Typeface.DEFAULT_BOLD);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setTextSize(SIZE_FACTOR * getIntrinsicHeight());
    }

    @Override
    public void draw(Canvas canvas) {
        super.draw(canvas);

        if (!enabled) {
            return;
        }

        final Rect bounds = getBounds();
        final float x = (1 - HALF_SIZE_FACTOR) * bounds.width();
        final float y = HALF_SIZE_FACTOR * bounds.height();
        canvas.drawCircle(x, y, SIZE_FACTOR * bounds.width(), backgroundPaint);

        if (text == null || text.length() == 0) {
            return;
        }

        final Rect textBounds = new Rect();
        textPaint.getTextBounds(text, 0, text.length(), textBounds);
        canvas.drawText(text, x, y + textBounds.height() / 2, textPaint);
    }

    public void setEnabled(boolean enabled) {
        if (this.enabled != enabled) {
            this.enabled = enabled;
            invalidateSelf();
        }
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setText(String text) {
        if (!Objects.equals(this.text, text)) {
            this.text = text;
            invalidateSelf();
        }
    }

    public String getText() {
        return text;
    }

    public void setBackgroundColor(int color) {
        if (backgroundPaint.getColor() != color) {
            backgroundPaint.setColor(color);
            invalidateSelf();
        }
    }

    public int getBackgroundColor() {
        return backgroundPaint.getColor();
    }

    public void setTextColor(int color) {
        if (textPaint.getColor() != color) {
            textPaint.setColor(color);
            invalidateSelf();
        }
    }

    public int getTextColor() {
        return textPaint.getColor();
    }
}

Przykład tego może być ustawiony na przełączniku w dowolnym momencie po jego utworzeniu, a właściwości odznaki ustawiane bezpośrednio na drawable w razie potrzeby.

Jak opisano poniżej, Context używane dla niestandardowego DrawerArrowDrawable należy uzyskać za pomocą ActionBar#getThemedContext() lub Toolbar#getContext(), aby zapewnić użycie prawidłowych wartości stylu. Na przykład:

private ActionBarDrawerToggle toggle;
private BadgeDrawerArrowDrawable badgeDrawable;
...

toggle = new ActionBarDrawerToggle(this, ...);
badgeDrawable = new BadgeDrawerArrowDrawable(getSupportActionBar().getThemedContext());

toggle.setDrawerArrowDrawable(badgeDrawable);
badgeDrawable.setText("1");
...

zrzuty ekranu


Aby nieco uprościć sprawy, lepiej byłoby również podklasować ActionBarDrawerToggle i obsługiwać wszystko za pomocą przełącznika przykład.

import android.app.Activity;
import android.content.Context;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class BadgeDrawerToggle extends ActionBarDrawerToggle {

    private BadgeDrawerArrowDrawable badgeDrawable;

    public BadgeDrawerToggle(Activity activity, DrawerLayout drawerLayout,
                             int openDrawerContentDescRes,
                             int closeDrawerContentDescRes) {
        super(activity, drawerLayout, openDrawerContentDescRes,
              closeDrawerContentDescRes);
        init(activity);
    }

    public BadgeDrawerToggle(Activity activity, DrawerLayout drawerLayout,
                             Toolbar toolbar, int openDrawerContentDescRes,
                             int closeDrawerContentDescRes) {
        super(activity, drawerLayout, toolbar, openDrawerContentDescRes,
              closeDrawerContentDescRes);
        init(activity);
    }

    private void init(Activity activity) {
        Context c = getThemedContext();
        if (c == null) {
            c = activity;
        }
        badgeDrawable = new BadgeDrawerArrowDrawable(c);
        setDrawerArrowDrawable(badgeDrawable);
    }

    public void setBadgeEnabled(boolean enabled) {
        badgeDrawable.setEnabled(enabled);
    }

    public boolean isBadgeEnabled() {
        return badgeDrawable.isEnabled();
    }

    public void setBadgeText(String text) {
        badgeDrawable.setText(text);
    }

    public String getBadgeText() {
        return badgeDrawable.getText();
    }

    public void setBadgeColor(int color) {
        badgeDrawable.setBackgroundColor(color);
    }

    public int getBadgeColor() {
        return badgeDrawable.getBackgroundColor();
    }

    public void setBadgeTextColor(int color) {
        badgeDrawable.setTextColor(color);
    }

    public int getBadgeTextColor() {
        return badgeDrawable.getTextColor();
    }

    private Context getThemedContext() {
        // Don't freak about the reflection. ActionBarDrawerToggle
        // itself is already using reflection internally.
        try {
            Field mActivityImplField = ActionBarDrawerToggle.class
                .getDeclaredField("mActivityImpl");
            mActivityImplField.setAccessible(true);
            Object mActivityImpl = mActivityImplField.get(this);
            Method getActionBarThemedContextMethod = mActivityImpl.getClass()
                .getDeclaredMethod("getActionBarThemedContext");
            return (Context) getActionBarThemedContextMethod.invoke(mActivityImpl);
        }
        catch (Exception e) {
            return null;
        }
    }
}

Dzięki temu odznaka niestandardowa zostanie ustawiona automatycznie, a wszystko związane z przełączaniem może być zarządzane za pomocą jednego obiektu.

BadgeDrawerToggle jest zamiennikiem ActionBarDrawerToggle, a jego konstruktory są dokładnie takie same.

private BadgeDrawerToggle badgeToggle;
...

badgeToggle = new BadgeDrawerToggle(this, ...);
badgeToggle.setBadgeText("1");
...
 77
Author: Mike M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-10 18:56:24