2015-10-18 62 views
13

我想通知用户有关通过导航抽屉可访问的应用程序中的新未读消息。我正在考虑通知徽章的东西类似苹果有,但在工具栏上的抽屉切换。工具栏上的抽屉徽章通知切换 - Android

这是我现在有: This is what I have now

这就是我想要的: This is what I want

我怎样才能做到这一点?

+1

你有什么已经尝试过? – stkent

+0

@stkent我正在考虑用我自己的观点取代抽屉图标,但我对此并不高兴。有没有其他的选择? – Soriyyx

+0

不是我所知道的。您可以使用可绘制的库存作为解决方案中的基础图像,例如基于http://stackoverflow.com/questions/29558303/change-icon-of-navigation-drawer – stkent

回答

-1

我通过在我的主布局中添加一个TextView来实现此目标,并且定位了切换。 在我mainactivity.xml我加入这个

<RelativeLayout 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 
    <TextView 
     android:id="@+id/badge_ham" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:layout_marginLeft="26dp" 
     android:layout_marginTop="14dp" 
     android:textSize="9sp" /> 
</RelativeLayout> 

,并添加徽章:

private void addBadgeToHamburger(int badge){ 
    badge_ham.setVisibility(View.VISIBLE); 
    String counter = Integer.toString(badge); 
    String s = " " + counter + " "; 
    SpannableString sColored = new SpannableString(s); 

    sColored.setSpan(new RoundedBackgroundSpan(Color.RED, Color.WHITE), s.length() - 3, s.length(), 0); 
    badge_ham.setText(sColored); 
} 
+0

能够在Kitkat中显示徽章...但对于Lollipop,奇怪的是,当您引用徽章视图时,在您的案例'badge_ham'中,它引发了NullPointerException。你遇到过这种情况吗? –

+0

-1不完整的答案。 RoundedBackgroundSpan是我们必须考虑的事情吗?发现了一些类似的实现,但没有使用相同的构造函数。 – Odys

+0

有没有人得到了这个工作? – acabezas

4

enter image description here

我用里面android.support.design.widget.AppBarLayout简单的TextView请检查以下完整代码

MainActivity.java

import android.os.Bundle; 
import android.support.v4.view.GravityCompat; 
import android.support.v4.widget.DrawerLayout; 
import android.support.v7.app.ActionBar; 
import android.support.v7.app.AppCompatActivity; 
import android.support.v7.widget.Toolbar; 
import android.view.Menu; 
import android.widget.TextView; 

public class MainActivity extends AppCompatActivity { 

    private DrawerLayout mDrawerLayout; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     initViews(); 
    } 

    private void initViews() { 
     mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); 
     setUpToolbar(); 
    } 

    private void setUpToolbar() { 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     final ActionBar ab = getSupportActionBar(); 
     ab.setHomeAsUpIndicator(R.drawable.navigation_drawericon); 
     ab.setDisplayHomeAsUpEnabled(true); 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     getMenuInflater().inflate(R.menu.home_menu, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(android.view.MenuItem item) { 
     switch (item.getItemId()) { 
      case android.R.id.home: 
       mDrawerLayout.openDrawer(GravityCompat.START); 
       return true; 
     } 
     return super.onOptionsItemSelected(item); 
    } 

    private void updateCounter(int count) { 
     ((TextView) findViewById(R.id.tv_nav_drawer_count)).setText(count + ""); 
    } 

    public void closeDrawer() { 
     mDrawerLayout.closeDrawers(); 
    } 
    } 

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?> 
    <android.support.v4.widget.DrawerLayout 
     xmlns:android="http://schemas.android.com/apk/res/android" 
     android:id="@+id/drawer_layout" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     android:background="@android:color/white" 
     android:fitsSystemWindows="true"> 

     <include layout="@layout/container_layout"/> 

     <android.support.design.widget.NavigationView 
      android:id="@+id/navigation_view" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent" 
      android:layout_gravity="start" 
      android:fitsSystemWindows="true"> 

     </android.support.design.widget.NavigationView> 


    </android.support.v4.widget.DrawerLayout> 

container_layout.xml

<android.support.design.widget.CoordinatorLayout 
      xmlns:android="http://schemas.android.com/apk/res/android" 
      xmlns:app="http://schemas.android.com/apk/res-auto" 
      android:id="@+id/main_content" 
      android:layout_width="match_parent" 
      android:layout_height="match_parent"> 

      <android.support.design.widget.AppBarLayout 
       android:id="@+id/appbar" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> 

       <android.support.v7.widget.Toolbar 
        android:id="@+id/toolbar" 
        android:layout_width="match_parent" 
        android:layout_height="?attr/actionBarSize" 
        android:background="?attr/colorPrimary" 
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/> 


       <TextView 
        android:id="@+id/tv_nav_drawer_count" 
        android:layout_width="15dp" 
        android:layout_height="15dp" 
        android:layout_marginLeft="30dp" 
        android:layout_marginTop="-45dp" 
        android:background="@drawable/menu_text_bg" 
        android:gravity="center" 
        android:text="10" 
        android:textColor="@android:color/white" 
        android:textSize="8dp"/> 


      </android.support.design.widget.AppBarLayout> 

      <FrameLayout 
       android:id="@+id/home_frame_container" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" 
       android:layout_marginTop="?actionBarSize"/> 


     </android.support.design.widget.CoordinatorLayout> 

home_menu.xml

 <?xml version="1.0" encoding="utf-8"?> 
     <menu xmlns:android="http://schemas.android.com/apk/res/android" 
       xmlns:app="http://schemas.android.com/apk/res-auto"> 

      <item 
       android:id="@+id/menu_search" 
       android:icon="@android:drawable/ic_menu_search" 
       android:orderInCategory="101" 
       android:title="Search" 
       app:showAsAction="always"/> 
     </menu> 

menu_text_bg.xml

<vector xmlns:android="http://schemas.android.com/apk/res/android" 
     android:width="24dp" 
     android:height="24dp" 
     android:viewportHeight="24.0" 
     android:viewportWidth="24.0"> 
    <path 
     android:fillColor="@android:color/holo_red_dark" 
     android:pathData="M12,12m-10,0a10,10 0,1 1,20 0a10,10 0,1 1,-20 0"/> 
</vector> 
+0

感谢您的回答。你的解决方案适用于一个屏幕(老实说,这是我第一次以这种方式思考,我甚至用'toolbar'里的'textview'编写了类似于你的代码,但是当我意识到我需要重写布局 –

+0

如果您的TextView在工具栏下滑动,就像它发生在我身上一样,请将“android:elevation”值设置为高于工具栏的值以修复绘制顺序。 –

7

enter image description here

enter image description here

我发现在互联网上这真的很酷BadgeDrawable类,你可以使用这个类添加徽章数到任何可绘制。请按照以下步骤操作。

第1步:先将下面的类添加到您的项目中。

import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.ColorFilter; 
import android.graphics.Paint; 
import android.graphics.PixelFormat; 
import android.graphics.Rect; 
import android.graphics.Typeface; 
import android.graphics.drawable.Drawable; 
import android.util.TypedValue; 


/** 
* Created by Admin on 2/25/2016. 
*/ 
public class BadgeDrawable extends Drawable { 

    private float mTextSize; 
    private Paint mBadgePaint; 
    private Paint mBadgePaint1; 
    private Paint mTextPaint; 
    private Rect mTxtRect = new Rect(); 

    private String mCount = ""; 
    private boolean mWillDraw = false; 


    public BadgeDrawable(Context context) { 
     mTextSize = dpToPx(context, 8); //text size 
     mBadgePaint = new Paint(); 
     mBadgePaint.setColor(Color.RED); 
     mBadgePaint.setAntiAlias(true); 
     mBadgePaint.setStyle(Paint.Style.FILL); 
     mBadgePaint1 = new Paint(); 
     mBadgePaint1.setColor(Color.parseColor("#EEEEEE")); 
     mBadgePaint1.setAntiAlias(true); 
     mBadgePaint1.setStyle(Paint.Style.FILL); 

     mTextPaint = new Paint(); 
     mTextPaint.setColor(Color.WHITE); 
     mTextPaint.setTypeface(Typeface.DEFAULT); 
     mTextPaint.setTextSize(mTextSize); 
     mTextPaint.setAntiAlias(true); 
     mTextPaint.setTextAlign(Paint.Align.CENTER); 
    } 

    private float dpToPx(Context context, float value) { 
     Resources r = context.getResources(); 
     float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, r.getDisplayMetrics()); 
     return px; 
    } 


    @Override 
    public void draw(Canvas canvas) { 
     if (!mWillDraw) { 
      return; 
     } 
     Rect bounds = getBounds(); 
     float width = bounds.right - bounds.left; 
     float height = bounds.bottom - bounds.top; 
     // Position the badge in the top-right quadrant of the icon. 

    /*Using Math.max rather than Math.min */ 
//  float radius = ((Math.max(width, height)/2))/2; 
     float radius = width * 0.15f; 
     float centerX = (width - radius - 1) +10; 
     float centerY = radius -5; 
     if(mCount.length() <= 2){ 
      // Draw badge circle. 
      canvas.drawCircle(centerX, centerY, radius+9, mBadgePaint1); 
      canvas.drawCircle(centerX, centerY, radius+7, mBadgePaint); 
     } 
     else{ 
      canvas.drawCircle(centerX, centerY, radius+10, mBadgePaint1); 
      canvas.drawCircle(centerX, centerY, radius+8, mBadgePaint); 
     } 
     // Draw badge count text inside the circle. 
     mTextPaint.getTextBounds(mCount, 0, mCount.length(), mTxtRect); 
     float textHeight = mTxtRect.bottom - mTxtRect.top; 
     float textY = centerY + (textHeight/2f); 
     if(mCount.length() > 2) 
     canvas.drawText("99+", centerX, textY, mTextPaint); 
     else 
     canvas.drawText(mCount, centerX, textY, mTextPaint); 
    } 

    /* 
    Sets the count (i.e notifications) to display. 
     */ 
    public void setCount(String count) { 
     mCount = count; 
     // Only draw a badge if there are notifications. 
     mWillDraw = !count.equalsIgnoreCase("0"); 
     invalidateSelf(); 
    } 

    @Override 
    public void setAlpha(int alpha) { 
     // do nothing 
    } 

    @Override 
    public void setColorFilter(ColorFilter cf) { 
     // do nothing 
    } 

    @Override 
    public int getOpacity() { 
     return PixelFormat.UNKNOWN; 
    } 
} 

第2步:现在创建一个可绘制(在我的情况下,它是ic_badge_drawable.xml)。然后复制并粘贴下面的XML文本。

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:id="@+id/ic_main_icon" 
     android:drawable="@drawable/ic_burger" 
     android:gravity="center" /> 


    <!-- set a place holder Drawable so android:drawable isn't null --> 
    <item android:id="@+id/ic_badge" 
     android:drawable="@drawable/ic_burger" /> 
</layer-list> 

在这里你可以通过任何drawable现在,稍后我们可以传递任何drawable给那些。这些就像占位符。

第3步:我们已经设置了一切。现在你可以使用下面的方法来设置任何可绘制的徽章数。

private Drawable setBadgeCount(Context context, int res, int badgeCount){ 
     LayerDrawable icon = (LayerDrawable) ContextCompat.getDrawable(context, R.drawable.ic_badge_drawable); 
     Drawable mainIcon = ContextCompat.getDrawable(context, res); 
     BadgeDrawable badge = new BadgeDrawable(context); 
     badge.setCount(String.valueOf(badgeCount)); 
     icon.mutate(); 
     icon.setDrawableByLayerId(R.id.ic_badge, badge); 
     icon.setDrawableByLayerId(R.id.ic_main_icon, mainIcon); 

     return icon; 
    } 

第4步:我用它来改变我的默认汉堡图标。

setSupportActionBar(toolbar); 
getSupportActionBar().setHomeAsUpIndicator(setBadgeCount(this,R.drawable.ic_burger, 3)); 
getSupportActionBar().setDisplayHomeAsUpEnabled(true); 
getSupportActionBar().setDisplayShowCustomEnabled(true); // enable overriding the default toolbar layout 
getSupportActionBar().setDisplayShowTitleEnabled(false);// disable the default title element here (for centered title) 
1

我知道它晚了,但仍然。 如果您使用的Android侧边导航菜单作为首发然后会有一个文件名app_bar_main.xml 在这个文件中,你会看到如下一些代码除了的TextViewTextView的负责展示徽章只是根据你的需要初始化它MainActivity你在哪里初始化的工具栏,并改变其知名度(可见当计数正别的了),现在你可以看到它的知名度

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
tools:context="com.thumbsol.beakns.activities.MainActivity"> 

<android.support.design.widget.AppBarLayout 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:theme="@style/AppTheme.AppBarOverlay"> 

    <android.support.v7.widget.Toolbar 
     android:id="@+id/toolbar" 
     android:layout_width="match_parent" 
     android:layout_height="?attr/actionBarSize" 
     android:background="?attr/colorPrimary" 
     app:popupTheme="@style/AppTheme.PopupOverlay"></android.support.v7.widget.Toolbar> 

    <TextView 
     android:id="@+id/hamburger_count" 
     android:layout_width="25dp" 
     android:layout_height="25dp" 
     android:layout_marginLeft="30dp" 
     android:layout_marginTop="-45dp" 
     android:background="@drawable/red_circle_bacground" 
     android:gravity="center" 
     android:text="10" 
     android:textColor="@android:color/white" 
     android:visibility="gone" /> 

    </android.support.design.widget.AppBarLayout> 

    <include layout="@layout/content_main" /> 

,这里是red_circle_bacground.xml的代码,把它放在绘制

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
<solid android:color="#f00" /> 
<corners 
    android:bottomLeftRadius="30dp" 
    android:bottomRightRadius="30dp" 
    android:topLeftRadius="30dp" 
    android:topRightRadius="30dp" /> 

    <size 
    android:height="25dp" 
    android:width="25dp"/> 
</shape> 
+0

非常容易和伟大的解决方案!谢谢 – JWqvist

+0

很高兴知道你不受欢迎@JWqvist – Zed