[android] Das Aktionsleisten-Benachrichtigungszählersymbol (Badge) wie Google hat


Answers

Ich teile meinen Code nur für den Fall, dass jemand so etwas möchte:

  • Layout / Menü / Menü_Aktionsbalken.xml

    <?xml version="1.0" encoding="utf-8"?>
    
    <menu xmlns:android="http://schemas.android.com/apk/res/android">
        ...
        <item android:id="@+id/menu_hotlist"
            android:actionLayout="@layout/action_bar_notifitcation_icon"
            android:showAsAction="always"
            android:icon="@drawable/ic_bell"
            android:title="@string/hotlist" />
        ...
    </menu>
    
  • layout / action_bar_notifiction_icon.xml

    Hinweis Stil und Android: klickbare Eigenschaften. diese machen das Layout zur Größe einer Schaltfläche und machen den Hintergrund bei Berührung grau.

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:orientation="vertical"
        android:gravity="center"
        android:layout_gravity="center"
        android:clickable="true"
        style="@android:style/Widget.ActionButton">
    
        <ImageView
            android:id="@+id/hotlist_bell"
            android:src="@drawable/ic_bell"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:layout_margin="0dp"
            android:contentDescription="bell"
            />
    
        <TextView xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/hotlist_hot"
            android:layout_width="wrap_content"
            android:minWidth="17sp"
            android:textSize="12sp"
            android:textColor="#ffffffff"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:text="@null"
            android:layout_alignTop="@id/hotlist_bell"
            android:layout_alignRight="@id/hotlist_bell"
            android:layout_marginRight="0dp"
            android:layout_marginTop="3dp"
            android:paddingBottom="1dp"
            android:paddingRight="4dp"
            android:paddingLeft="4dp"
            android:background="@drawable/rounded_square"/>
    </RelativeLayout>
    
  • drawable-xhdpi / ic_bell.png

    Ein 64 x 64 Pixel großes Bild mit 10 Pixel breiten Paddings von allen Seiten. Sie sollen 8 Pixel breite Paddings haben, aber ich finde die meisten Standard-Elemente etwas kleiner. Natürlich sollten Sie verschiedene Größen für unterschiedliche Dichten verwenden.

  • zeichnbare / gerundete_square.xml

    Hier ist # ff222222 (Farbe # 222222 mit Alpha #ff (voll sichtbar)) die Hintergrundfarbe meiner Aktionsleiste.

    <?xml version="1.0" encoding="utf-8"?>
    
    <shape
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <corners android:radius="2dp" />
        <solid android:color="#ffff0000" />
        <stroke android:color="#ff222222" android:width="2dp"/>
    </shape>
    
  • com / ubergeek42 / WeechatAndroid / WeechatAktivität.java

    Hier machen wir es anklickbar und aktualisierbar! Ich habe einen abstrakten Listener erstellt, der auf onLongClick Toast erstellt, der Code stammt aus den Quellen von ActionBarSherlock .

    private int hot_number = 0;
    private TextView ui_hot = null;
    
    @Override public boolean onCreateOptionsMenu(final Menu menu) {
        MenuInflater menuInflater = getSupportMenuInflater();
        menuInflater.inflate(R.menu.menu_actionbar, menu);
        final View menu_hotlist = menu.findItem(R.id.menu_hotlist).getActionView();
        ui_hot = (TextView) menu_hotlist.findViewById(R.id.hotlist_hot);
        updateHotCount(hot_number);
        new MyMenuItemStuffListener(menu_hotlist, "Show hot message") {
            @Override
            public void onClick(View v) {
                onHotlistSelected();
            }
        };
        return super.onCreateOptionsMenu(menu);
    }
    
    // call the updating code on the main thread,
    // so we can call this asynchronously
    public void updateHotCount(final int new_hot_number) {
        hot_number = new_hot_number;
        if (ui_hot == null) return;
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (new_hot_number == 0)
                    ui_hot.setVisibility(View.INVISIBLE);
                else {
                    ui_hot.setVisibility(View.VISIBLE);
                    ui_hot.setText(Integer.toString(new_hot_number));
                }
            }
        });
    }
    
    static abstract class MyMenuItemStuffListener implements View.OnClickListener, View.OnLongClickListener {
        private String hint;
        private View view;
    
        MyMenuItemStuffListener(View view, String hint) {
            this.view = view;
            this.hint = hint;
            view.setOnClickListener(this);
            view.setOnLongClickListener(this);
        }
    
        @Override abstract public void onClick(View v);
    
        @Override public boolean onLongClick(View v) {
            final int[] screenPos = new int[2];
            final Rect displayFrame = new Rect();
            view.getLocationOnScreen(screenPos);
            view.getWindowVisibleDisplayFrame(displayFrame);
            final Context context = view.getContext();
            final int width = view.getWidth();
            final int height = view.getHeight();
            final int midy = screenPos[1] + height / 2;
            final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
            Toast cheatSheet = Toast.makeText(context, hint, Toast.LENGTH_SHORT);
            if (midy < displayFrame.height()) {
                cheatSheet.setGravity(Gravity.TOP | Gravity.RIGHT,
                        screenWidth - screenPos[0] - width / 2, height);
            } else {
                cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
            }
            cheatSheet.show();
            return true;
        }
    }
    
Question

Gibt es einen Android-Standard-Ausweis oder eine Methode, um das Benachrichtigungssymbol für die Aktionsleiste mit einer Zählung wie in Google-Beispielen anzuzeigen?

Wenn nicht, was ist dann der beste Weg?
Ich bin neu bei Android, bitte helfen.




Anstatt benutzerdefinierte Form zu verwalten und zu zeichnen, warum nicht eingebauten Android-Mechanismus zu verwenden? Sie können den Badge-Stil in TextView und den benutzerdefinierten Stil gemäß Ihrem Thema verwenden.

Prost. :)

        <TextView
                android:id="@+id/fabCounter"
                style="@style/Widget.Design.FloatingActionButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentEnd="true"
                android:layout_centerVertical="true"
                android:layout_marginEnd="10dp"
                android:padding="5dp"
                android:text="10"
                android:textColor="@android:color/black"
                android:textSize="14sp" />




Sehen Sie sich die Antworten auf diese Fragen an, insbesondere die zweite, die Beispielcode enthält:

Wie man dynamische Werte auf dem Menüpunkt in Android implementiert

Wie bekomme ich Text auf einem ActionBar Icon?

Von dem, was ich sehe, müssen Sie Ihre eigene benutzerdefinierte ActionView Implementierung erstellen. Eine Alternative könnte eine benutzerdefinierte Drawable . Beachten Sie, dass keine native Implementierung einer Benachrichtigungsanzahl für die Aktionsleiste angezeigt wird.

EDIT: Die Antwort, die Sie suchten, mit Code: Benutzerdefinierte Benachrichtigungsansicht mit Beispielimplementierung




Ich mag ActionView basierte Lösungen nicht, meine Idee ist:

  1. Erstellen Sie ein Layout mit TextView , dass TextView von der Anwendung TextView wird
  2. wenn Sie ein MenuItem zeichnen MenuItem :

    2.1. Layout aufblasen

    2.2. Rufen Sie measure() und layout() (sonst wird die view 0px x 0px, für die meisten Anwendungsfälle zu klein)

    2.3. TextView den TextView Text

    2.4. Machen Sie "Screenshot" der Ansicht

    2.6. MenuItem das MenuItem -Symbol basierend auf der unter 2.4 erstellten Bitmap ein

  3. profitieren!

Also, Ergebnis sollte etwas wie sein

  1. Layout erstellen ist hier ein einfaches Beispiel
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/counterPanel"
    android:layout_width="32dp"
    android:layout_height="32dp"
    android:background="@drawable/ic_menu_gallery">
    <RelativeLayout
        android:id="@+id/counterValuePanel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

        <ImageView
            android:id="@+id/counterBackground"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/unread_background" />

        <TextView
            android:id="@+id/count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="1"
            android:textSize="8sp"
            android:layout_centerInParent="true"
            android:textColor="#FFFFFF" />
    </RelativeLayout>
</FrameLayout>

@drawable/unread_background ist, dass der grüne TextView -Hintergrund, @drawable/ic_menu_gallery hier nicht wirklich benötigt wird, es ist nur eine Vorschau des Layout-Ergebnisses in der IDE.

  1. onCreateOptionsMenu Sie Code in onCreateOptionsMenu / onPrepareOptionsMenu

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.menu_main, menu);
    
        MenuItem menuItem = menu.findItem(R.id.testAction);
        menuItem.setIcon(buildCounterDrawable(count, R.drawable.ic_menu_gallery));
    
        return true;
    }
    
  2. Implementieren Sie die build-the-icon-Methode:

    private Drawable buildCounterDrawable(int count, int backgroundImageId) {
        LayoutInflater inflater = LayoutInflater.from(this);
        View view = inflater.inflate(R.layout.counter_menuitem_layout, null);
        view.setBackgroundResource(backgroundImageId);
    
        if (count == 0) {
            View counterTextPanel = view.findViewById(R.id.counterValuePanel);
            counterTextPanel.setVisibility(View.GONE);
        } else {
            TextView textView = (TextView) view.findViewById(R.id.count);
            textView.setText("" + count);
        }
    
        view.measure(
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    
        view.setDrawingCacheEnabled(true);
        view.setDrawingCacheQuality(View.DRAWING_CACHE_QUALITY_HIGH);
        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);
    
        return new BitmapDrawable(getResources(), bitmap);
    }
    

Der vollständige Code ist hier: https://github.com/cvoronin/ActionBarMenuItemCounter




Links