L'icône de compte de notification Actionbar (badge) comme Google a
Existe-t-il un badge standard android ou une méthode pour afficher l'icône de notification de la barre d'action avec un compte comme sur Google examples?
Si non, alors quelle est la meilleure façon de faire?
Je suis nouveau sur android, s'il vous plaît aider.
8 réponses
je ne suis pas sûr si c'est la meilleure solution ou pas, mais c'est ce dont j'ai besoin.
S'il vous plaît dites-moi si vous savez ce qui doit être changé pour une meilleure performance ou qualité. Dans mon cas, j'ai un bouton.
article personnalisé sur mon menu - main.xml
<item
android:id="@+id/badge"
android:actionLayout="@layout/feed_update_count"
android:icon="@drawable/shape_notification"
android:showAsAction="always">
</item>
forme Personnalisée drawable (carré à fond) - 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 pour ma vue-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 établissement et la mise à jour de mon point de vue
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();
}
je vais juste partager mon code au cas où quelqu'un voudrait quelque chose comme ça:
-
mise en page/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_notification_icon.xml
Note style et android:cliquable propriétés. ceux-ci font la disposition de la taille d'un bouton et de faire le fond gris lorsqu'il est touché.
<?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
une image de 64x64 pixels avec des paddings de 10 pixels de tous les côtés. Vous êtes censé avoir 8 pixels de largeur, mais je trouve que la plupart des éléments par défaut sont légèrement plus petits que cela. Bien sûr, vous voudrez utiliser différentes tailles pour différentes densités.
-
drawable/rounded_square.xml
ici, # ff222222 (couleur # 222222 avec alpha # ff (entièrement visible)) est la couleur de fond de ma barre d'Action.
<?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
ici, nous le rendons cliquable et actualisable! J'ai créé un auditeur abstrait qui fournit la création Toast sur onLongClick, le code a été prise à partir de les sources de la 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; } }
Juste à ajouter. Si quelqu'un veut mettre en œuvre une bulle de cercle remplie, heres le code (appelez-le 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>
vous devrez peut-être ajuster l'épaisseur en fonction de vos besoins.
EDIT:
Voici la disposition pour le bouton (le nom 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>
dans le Menu Créer l'article:
<item
android:id="@+id/menu_messages"
android:showAsAction="always"
android:actionLayout="@layout/badge_layout"/>
Dans onCreateOptionsMenu
obtenir une référence à l'élément de Menu:
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();
}
}
});
après réception de la notification pour les messages, régler le nombre:
itemMessagesBadgeTextView.setText("" + count);
itemMessagesBadgeTextView.setVisibility(View.VISIBLE);
iconButtonMessages.setTextColor(getResources().getColor(R.color.white));
ce code utilise Iconify-fontawesome .
compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.+'
je n'aime pas ActionView
solutions basées sur,
mon idée est:
- créer un layout avec
TextView
, queTextView
sera peuplé par application -
quand vous devez dessiner un
MenuItem
:2.1. gonfler mise en page
2.2. appelez
measure()
&layout()
(sinonview
sera 0px x 0px, il est trop petit pour la plupart des cas d'utilisation)2.3. définir le
TextView
's texte2.4. faire "screenshot" de la vue
2.6. définir
MenuItem
l 'icône basée sur bitmap créé sur 2.4 -
profit!
donc, le résultat devrait être quelque chose comme
- créer layout voici un exemple simple
<?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
est ce Vert TextView
's background,
@drawable/ic_menu_gallery
n'est pas vraiment nécessaire ici, c'est juste pour prévisualiser le résultat de layout dans IDE.
-
ajouter le code dans
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; }
-
mettre en Œuvre l'accumulation de l'icône de la méthode:
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); }
le code complet est ici: https://github.com/cvoronin/ActionBarMenuItemCounter
Ok, pour @AndrewS solution à travailler avec v7 appCompat bibliothèque :
<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();
}
Le reste du code est le même.
essayez d'examiner les réponses à ces questions, en particulier la deuxième qui a un code d'échantillon:
comment mettre en œuvre les valeurs dynamiques sur L'article de menu dans Android
Comment obtenir du texte sur une icône ActionBar?
de ce que je vois, vous aurez besoin de créer votre propre application personnalisée ActionView
. Une alternative pourrait être une coutume Drawable
. Notons qu'il semble y avoir pas natif de la mise en œuvre d'une notification à compter de la Barre d'Action.
EDIT: la réponse que vous cherchiez, avec le code: Custom Notification View avec sample implementation
lorsque vous utilisez toolbar:
....
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);
}
et dans votre appel de données de charge rafraîchmenu ():
private void refreshMenu() {
comment_count.setVisibility(View.VISIBLE);
comment_count.setText("" + post_data.getComment_count());
}
au lieu de gérer la forme personnalisée et dessinable pourquoi ne pas utiliser le mécanisme Android intégré?
Vous pouvez utiliser le style de badge dans TextView
et utiliser le style personnalisé selon votre thème.
santé. :)
<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" />