Je souhaite informer l'utilisateur du nouveau message non lu dans l'application, accessible via le tiroir de navigation. Je pensais au badge de notification quelque chose de similaire à Apple mais avec un tiroir dans la barre d’outils.
Comment puis-je y arriver?
J'ai trouvé cette classe BadgeDrawable vraiment cool sur Internet et vous pouvez ajouter un nombre de badges à n'importe quel tirage utilisant cette classe. Veuillez suivre les étapes ci-dessous.
Étape 1: ajoutez d'abord la classe ci-dessous à votre projet.
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;
}
}
Étape 2: Créez maintenant un dessin (dans mon cas, il s'agit de ic_badge_drawable.xml). Ensuite, copiez et collez ci-dessous le texte 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>
ici, vous pouvez passer n'importe quel tirage pour le moment, plus tard, nous pouvons passer le tirage à ceux-ci. Ce sont juste comme des détenteurs de place.
Étape 3: Nous avons déjà tout configuré. Vous pouvez maintenant utiliser la méthode ci-dessous pour définir le nombre de badges pour tous les tirables.
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;
}
Étape 4: Je l’ai utilisé comme ci-dessous pour changer l’icône de mon hamburger par défaut.
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)
J'ai utilisé TextView simple dans Android.support.design.widget.AppBarLayout, veuillez vérifier le code complet ci-dessous.
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>
conteneur_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>
Je sais qu'il est tard mais quand même. si vous utilisez le menu de navigation latéral Android comme démarreur, il y aura un nom de fichier app_bar_main.xml dans ce fichier, vous verrez du code comme ci-dessous, à l'exception du TextView this TextView est responsable de l'affichage du badge, il suffit de l'initialiser dans MainActivity où vous initialisez votre barre d'outils et de changer sa visibilité en fonction de vos besoins (visible lorsque le décompte est positif) dès que vous le pouvez voir sa visibilité est parti
<?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" />
et voici le code de red_circle_bacground.xml mettez-le en drawable
<?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>
En vous basant sur la réponse de TDSoft, vous pouvez raccourcir davantage la procédure en étendant DrawerArrowDrawable.
Étape 1: (sauf DrawerArrowDrable, essentiellement identique à la classe Badge de TDSoft).
public class BadgeNavigationDrawable extends DrawerArrowDrawable{
private float mTextSize;
private Paint mBadgePaint;
private Paint mBadgePaint1;
private Paint mTextPaint;
private Rect mTxtRect = new Rect();
private String mCount = "";
private boolean mWillDraw = false;
/**
* @param context used to get the configuration for the drawable from
*/
public BadgeNavigationDrawable(Context context) {
super(context);
setColor(context.getResources().getColor(R.color.accent));
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);
}
@Override
public void draw(Canvas canvas) {
super.draw(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;
}
private float dpToPx(Context context, float value) {
Resources r = context.getResources();
float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, value, r.getDisplayMetrics());
return px;
}
}
Étape 2: C’est tout ce dont vous avez besoin. Si vous devez mettre à jour votre icône de tiroir de navigation, appelez - Vos événements sont tous conservés.
BadgeNavigationDrawable drawerIcon = new BadgeNavigationDrawable(MainActivity.this);
drawerIcon.setCount(String.valueOf(count));
mDrawerToggle.setDrawerArrowDrawable(drawerIcon);
mDrawerToggle.syncState();