Gibt es ein Android Standardabzeichen oder eine Standardmethode zum Anzeigen des Benachrichtigungssymbols für die Aktionsleiste mit einer Zählung wie in Google-Beispielen?
Wenn nicht, wie schaffen Sie es dann am besten?
Ich bin neu in Android, bitte helfen Sie.
Ich bin nicht sicher, ob dies die beste Lösung ist oder nicht, aber es ist das, was ich brauche.
Bitte teilen Sie mir mit, ob Sie wissen, was geändert werden muss, um eine bessere Leistung oder Qualität zu erzielen. In meinem Fall habe ich einen Knopf.
Benutzerdefiniertes Element in meinem Menü - main.xml
<item
Android:id="@+id/badge"
Android:actionLayout="@layout/feed_update_count"
Android:icon="@drawable/shape_notification"
Android:showAsAction="always">
</item>
Benutzerdefinierte Form, die gezeichnet werden kann (Hintergrundquadrat) - shape_notification.xml
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle">
<stroke Android:color="#22000000" Android:width="2dp"/>
<corners Android:radius="5dp" />
<solid Android:color="#CC0001"/>
</shape>
Layout für meine Ansicht - feed_update_count.xml
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@+id/notif_count"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:minWidth="32dp"
Android:minHeight="32dp"
Android:background="@drawable/shape_notification"
Android:text="0"
Android:textSize="16sp"
Android:textColor="@Android:color/white"
Android:gravity="center"
Android:padding="2dp"
Android:singleLine="true">
</Button>
MainActivity - Einstellung und Aktualisierung meiner Ansicht
static Button notifCount;
static int mNotifCount = 0;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getSupportMenuInflater();
inflater.inflate(R.menu.main, menu);
View count = menu.findItem(R.id.badge).getActionView();
notifCount = (Button) count.findViewById(R.id.notif_count);
notifCount.setText(String.valueOf(mNotifCount));
return super.onCreateOptionsMenu(menu);
}
private void setNotifCount(int count){
mNotifCount = count;
invalidateOptionsMenu();
}
Bearbeiten Seit Version 26 der Unterstützungsbibliothek (oder von Androidx) müssen Sie kein benutzerdefiniertes OnLongClickListener
mehr implementieren, um den Tooltip anzuzeigen. Nennen Sie das einfach:
TooltipCompat.setTooltipText(menu_hotlist, getString(R.string.hint_show_hot_message));
Ich teile nur meinen Code, falls jemand so etwas möchte:
layout/menu/menu_actionbar.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_notifitcation_icon.xml
Beachten Sie Stil und Android: anklickbare Eigenschaften. Dadurch wird das Layout auf die Größe einer Schaltfläche gebracht und der Hintergrund beim Berühren 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 Abständen von allen Seiten. Sie sollten 8 Pixel breite Abstände haben, aber ich finde, dass die meisten Standardelemente etwas kleiner sind. Natürlich möchten Sie unterschiedliche Größen für unterschiedliche Dichten verwenden.
drawable/round_square.xml
Hier ist # ff222222 (Farbe # 222222 mit Alpha #ff (vollständig 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/WeechatActivity.Java
Hier machen wir es anklickbar und aktualisierbar! Ich habe einen abstrakten Listener erstellt, der die Erstellung von Toasts auf onLongClick ermöglicht. 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;
}
}
Nur um hinzuzufügen. Wenn jemand eine gefüllte Kreisblase implementieren möchte, ist hier der Code (name it bage_circle.xml
):
<shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="ring"
Android:useLevel="false"
Android:thickness="9dp"
Android:innerRadius="0dp"
>
<solid
Android:color="#F00"
/>
<stroke
Android:width="1dip"
Android:color="#FFF" />
<padding
Android:top="2dp"
Android:bottom="2dp"/>
</shape>
Möglicherweise müssen Sie die Dicke an Ihre Bedürfnisse anpassen.
EDIT: Hier ist das Layout für die Schaltfläche (name it badge_layout.xml
):
<RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
<com.joanzapata.iconify.widget.IconButton
Android:layout_width="44dp"
Android:layout_height="44dp"
Android:textSize="24sp"
Android:textColor="@color/white"
Android:background="@drawable/action_bar_icon_bg"
Android:id="@+id/badge_icon_button"/>
<TextView
Android:id="@+id/badge_textView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignTop="@id/badge_icon_button"
Android:layout_alignRight="@id/badge_icon_button"
Android:layout_alignEnd="@id/badge_icon_button"
Android:text="10"
Android:paddingEnd="8dp"
Android:paddingRight="8dp"
Android:paddingLeft="8dp"
Android:gravity="center"
Android:textColor="#FFF"
Android:textSize="11sp"
Android:background="@drawable/badge_circle"/>
</RelativeLayout>
Im Menü Element erstellen:
<item
Android:id="@+id/menu_messages"
Android:showAsAction="always"
Android:actionLayout="@layout/badge_layout"/>
In onCreateOptionsMenu
wird auf den Menüpunkt verwiesen:
itemMessages = menu.findItem(R.id.menu_messages);
badgeLayout = (RelativeLayout) itemMessages.getActionView();
itemMessagesBadgeTextView = (TextView) badgeLayout.findViewById(R.id.badge_textView);
itemMessagesBadgeTextView.setVisibility(View.GONE); // initially hidden
iconButtonMessages = (IconButton) badgeLayout.findViewById(R.id.badge_icon_button);
iconButtonMessages.setText("{fa-envelope}");
iconButtonMessages.setTextColor(getResources().getColor(R.color.action_bar_icon_color_disabled));
iconButtonMessages.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (HJSession.getSession().getSessionId() != null) {
Intent intent = new Intent(getThis(), HJActivityMessagesContexts.class);
startActivityForResult(intent, HJRequestCodes.kHJRequestCodeActivityMessages.ordinal());
} else {
showLoginActivity();
}
}
});
Legen Sie nach Erhalt der Benachrichtigung für Nachrichten die Anzahl fest:
itemMessagesBadgeTextView.setText("" + count);
itemMessagesBadgeTextView.setVisibility(View.VISIBLE);
iconButtonMessages.setTextColor(getResources().getColor(R.color.white));
Dieser Code verwendet Iconify-fontawesome .
compile 'com.joanzapata.iconify:Android-iconify-fontawesome:2.1.+'
Ich mag keine ActionView
basierten Lösungen, meine Idee ist:
TextView
, damit TextView
von der Anwendung ausgefüllt wirdwenn Sie ein MenuItem
zeichnen müssen:
2.1. Layout aufblasen
2.2. rufen Sie measure()
& layout()
auf (andernfalls ist view
0px x 0px, es ist für die meisten Anwendungsfälle zu klein)
2.3. Setze den Text von TextView
2.4. mach "screenshot" von der ansicht
2.6. Setze das Icon von MenuItem
basierend auf der Bitmap, die in 2.4 erstellt wurde
profitieren!
das Ergebnis sollte also so ähnlich sein
<?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 der grüne TextView
Hintergrund, @drawable/ic_menu_gallery
wird hier nicht wirklich benötigt, sondern dient lediglich zur Vorschau des Layout-Ergebnisses in IDE.
code in onCreateOptionsMenu
/onPrepareOptionsMenu
einfügen
@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;
}
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
Ok, für @ AndrewS die Lösung für v7 appCompat library:
<menu
xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:someNamespace="http://schemas.Android.com/apk/res-auto" >
<item
Android:id="@+id/saved_badge"
someNamespace:showAsAction="always"
Android:icon="@drawable/shape_notification" />
</menu>
.
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
menu.clear();
inflater.inflate(R.menu.main, menu);
MenuItem item = menu.findItem(R.id.saved_badge);
MenuItemCompat.setActionView(item, R.layout.feed_update_count);
View view = MenuItemCompat.getActionView(item);
notifCount = (Button)view.findViewById(R.id.notif_count);
notifCount.setText(String.valueOf(mNotifCount));
}
private void setNotifCount(int count){
mNotifCount = count;
supportInvalidateOptionsMenu();
}
Der Rest des Codes ist der gleiche.
Sehen Sie sich die Antworten auf diese Fragen an, insbesondere die zweite mit Beispielcode:
So implementieren Sie dynamische Werte für einen Menüpunkt in Android
Wie bekomme ich Text auf ein ActionBar Icon?
Nach dem, was ich sehe, müssen Sie Ihre eigene benutzerdefinierte ActionView
-Implementierung erstellen. Eine Alternative könnte ein benutzerdefiniertes Drawable
sein. Beachten Sie, dass anscheinend keine systemeigene Implementierung einer Benachrichtigungsanzahl für die Aktionsleiste vorhanden ist.
BEARBEITEN: Die Antwort, die Sie gesucht haben, mit Code: Benutzerdefinierte Benachrichtigungsansicht mit Beispielimplementierung
Wenn Sie die Symbolleiste verwenden:
....
private void InitToolbar() {
toolbar = (Toolbar) findViewById(R.id.my_awesome_toolbar);
toolbartitle = (TextView) findViewById(R.id.titletool);
toolbar.inflateMenu(R.menu.show_post);
toolbar.setOnMenuItemClickListener(this);
Menu menu = toolbar.getMenu();
MenuItem menu_comments = menu.findItem(R.id.action_comments);
MenuItemCompat
.setActionView(menu_comments, R.layout.menu_commentscount);
View v = MenuItemCompat.getActionView(menu_comments);
v.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// Your Action
}
});
comment_count = (TextView) v.findViewById(R.id.count);
}
und rufen Sie in Ihren Ladedaten refreshMenu () auf:
private void refreshMenu() {
comment_count.setVisibility(View.VISIBLE);
comment_count.setText("" + post_data.getComment_count());
}
Ich habe eine sehr gute Lösung gefunden hier , ich benutze sie mit kotlin.
Zuerst müssen Sie im Zeichenordner item_count.xml
Erstellen:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:shape="rectangle">
<corners Android:radius="8dp" />
<solid Android:color="#f20000" />
<stroke
Android:width="2dip"
Android:color="#FFF" />
<padding
Android:bottom="5dp"
Android:left="5dp"
Android:right="5dp"
Android:top="5dp" />
</shape>
In Ihrem Activity_Main
Layout sehen einige so aus:
<RelativeLayout
Android:id="@+id/badgeLayout"
Android:layout_width="40dp"
Android:layout_height="40dp"
Android:layout_toRightOf="@+id/badge_layout1"
Android:layout_gravity="end|center_vertical"
Android:layout_marginEnd="5dp">
<RelativeLayout
Android:id="@+id/relative_layout1"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content">
<Button
Android:id="@+id/btnBadge"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:background="@mipmap/ic_notification" />
</RelativeLayout>
<TextView
Android:id="@+id/txtBadge"
Android:layout_width="18dp"
Android:layout_height="18dp"
Android:layout_alignRight="@id/relative_layout1"
Android:background="@drawable/item_count"
Android:text="22"
Android:textColor="#FFF"
Android:textSize="7sp"
Android:textStyle="bold"
Android:gravity="center"/>
</RelativeLayout>
Und Sie können wie folgt ändern:
btnBadge.setOnClickListener { view ->
Snackbar.make(view,"badge click", Snackbar.LENGTH_LONG) .setAction("Action", null).show()
txtBadge.text = "0"
}
Ich habe einen besseren Weg gefunden, es zu tun. wenn du so etwas benutzen willst
Verwenden Sie diese Abhängigkeit
compile 'com.nex3z:notification-badge:0.1.0'
erstellen Sie eine XML-Datei in Drawable und speichern Sie sie als Badge.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:Android="http://schemas.Android.com/apk/res/Android">
<item>
<shape Android:shape="oval">
<solid Android:color="#66000000"/>
<size Android:width="30dp" Android:height="40dp"/>
</shape>
</item>
<item Android:bottom="1dp" Android:right="0.6dp">
<shape Android:shape="oval">
<solid Android:color="@color/Error_color"/>
<size Android:width="20dp" Android:height="20dp"/>
</shape>
</item>
</layer-list>
Nun, wo immer Sie dieses Abzeichen verwenden möchten, verwenden Sie folgenden Code in XML. Mit dessen Hilfe können Sie dieses Abzeichen in der oberen rechten Ecke Ihres Bildes oder irgendetwas sehen.
<com.nex3z.notificationbadge.NotificationBadge
Android:id="@+id/badge"
Android:layout_toRightOf="@id/Your_ICON/IMAGE"
Android:layout_alignTop="@id/Your_ICON/IMAGE"
Android:layout_marginLeft="-16dp"
Android:layout_marginTop="-8dp"
Android:layout_width="28dp"
Android:layout_height="28dp"
app:badgeBackground="@drawable/Badge"
app:maxTextLength="2"
></com.nex3z.notificationbadge.NotificationBadge>
Jetzt endlich auf yourFile.Java diese 2 einfache Sache benutzen .. 1) Definieren
NotificationBadge mBadge;
2) wo deine Schleife oder irgendetwas, das diese Zahl zählt, dies benutzt:
mBadge.setNumber(your_LoopCount);
hier zeigt mBadge.setNumber(0)
nichts an.
Ich hoffe das hilft.