Actionbar notification count icon (badge) like Google has

匿名 (未验证) 提交于 2019-12-03 01:04:01

问题:

Is there a android standard badge or method to show action bar notification icon with a count like on Google examples?

If not, then what is the best way to make it?
I'm new to android, please help.

回答1:

I am not sure if this is the best solution or not, but it is what I need.

Please tell me if you know what is need to be changed for better performance or quality. In my case, I have a button.

Custom item on my menu - main.xml

Custom shape drawable (background square) - shape_notification.xml

Layout for my view - feed_update_count.xml

 

MainActivity - setting and updating my view

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(); } 


回答2:

I'll just share my code in case someone wants something like this:

  • layout/menu/menu_actionbar.xml

         ...          ... 
  • layout/action_bar_notifitcation_icon.xml

    Note style and android:clickable properties. these make the layout the size of a button and make the background gray when touched.

  • drawable-xhdpi/ic_bell.png

    A 64x64 pixel image with 10 pixel wide paddings from all sides. You are supposed to have 8 pixel wide paddings, but I find most default items being slightly smaller than that. Of course, you'll want to use different sizes for different densities.

  • drawable/rounded_square.xml

    Here, #ff222222 (color #222222 with alpha #ff (fully visible)) is the background color of my Action Bar.

  • com/ubergeek42/WeechatAndroid/WeechatActivity.java

    Here we make it clickable and updatable! I created an abstract listener that provides Toast creation on onLongClick, the code was taken from from the sources of 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 


回答3:

Just to add. If someone wants to implement a filled circle bubble, heres the code (name it bage_circle.xml):

You may have to adjust the thickness according to your need.

EDIT: Here's the layout for button (name it badge_layout.xml):

In Menu create item:

In onCreateOptionsMenu get reference to the Menu item:

    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();             }         }     }); 

After receiving notification for messages, set the count:

itemMessagesBadgeTextView.setText("" + count); itemMessagesBadgeTextView.setVisibility(View.VISIBLE); iconButtonMessages.setTextColor(getResources().getColor(R.color.white)); 

This code uses Iconify-fontawesome.

compile 'com.joanzapata.iconify:android-iconify-fontawesome:2.1.+' 


回答4:

I don't like ActionView based solutions, my idea is:

  1. create a layout with TextView, that TextView will be populated by application
  2. when you need to draw a MenuItem:

    2.1. inflate layout

    2.2. call measure() & layout() (otherwise view will be 0px x 0px, it's too small for most use cases)

    2.3. set the TextView's text

    2.4. make "screenshot" of the view

    2.6. set MenuItem's icon based on bitmap created on 2.4

  3. profit!

so, result should be something like

  1. create layout here is a simple example

@drawable/unread_background is that green TextView's background, @drawable/ic_menu_gallery is not really required here, it's just to preview layout's result in IDE.

  1. add code into 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. Implement build-the-icon method:

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

The complete code is here: https://github.com/cvoronin/ActionBarMenuItemCounter



回答5:

Ok, for @AndrewS solution to work with v7 appCompat library:

.

@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(); } 

The rest of the code is the same.



回答6:

Try looking at the answers to these questions, particularly the second one which has sample code:

How to implement dynamic values on menu item in Android

How to get text on an ActionBar Icon?

From what I see, You'll need to create your own custom ActionView implementation. An alternative might be a custom Drawable. Note that there appears to be no native implementation of a notification count for the Action Bar.

EDIT: The answer you were looking for, with code: Custom Notification View with sample implementation



回答7:

When you use 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); } 

and in your load data call refreshMenu():

private void refreshMenu() {     comment_count.setVisibility(View.VISIBLE);     comment_count.setText("" + post_data.getComment_count()); } 


回答8:

Instead of managing custom shape and drawable why not to use inbuilt Android mechanism? You can use badge style in TextView and use custom style as per your theme.

Cheers. :)

        



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!