Để tạo icon với số đếm như trên ta sẽ thực hiện như sau:
Nếu ta chuẩn bị trước mỗi ảnh tướng ứng với một state thì thật tồi tệ vì nếu ta có n state thì ta cần n ảnh, vì vậy ta sẽ custom 1 icon có khả năng hiển thị count khác nhau.
Bước 1. Ta sẽ tạo drawable với layer-list
Đầu tiên ta cần hiểu layer-list là gì và nó hoạt động như thế nào. Về cơ bản, layer-list được dùng để kết hợp các item khác nhau trong cùng 1 drawable, mỗi item sẽ nằm ở layer trong layer-list. Các layer được liệt kê trước sẽ được vẽ trước khi drawable được load, vì vậy item dưới cùng trong layer-list sẽ được hiển thị trên cùng khi drawable được load.
Để tạo được group icon như trên ta sẽ chia thành hai layer. Ở layer bên dưới ta sẽ tạo group icon, còn layer trên cùng ta sẽ tạo count drawable để hiển thị count.
actionbar_group_icon.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@drawable/ic_group"
android:gravity="center" />
<item
android:id="@+id/ic_group_count"
android:drawable="@color/transparent" />
</layer-list>
Bước 2. Thêm icon tạo ở trên vào actionbar
tạo file menu sau đó add drawable tạo ở trên vào item như sau
tạo file menu sau đó add drawable tạo ở trên vào item như sau
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto" >
<!-- add the following item to your menu.xml -->
<item
android:id="@+id/ic_group"
android:icon="@drawable/actionbar_group_icon.xml"
android:title="@string/group_title"
app:showAsAction="always" />
</menu>
Bước 3. Tạo custom component để vẽ count trên layer top
Tạo file java CountDrawable.java extend Drawable class
Tạo file java CountDrawable.java extend Drawable class
public class CountDrawable extends Drawable {
private Paint mBadgePaint;
private Paint mTextPaint;
private Rect mTxtRect = new Rect();
private String mCount = "";
private boolean mWillDraw;
public CountDrawable(Context context) {
float mTextSize = context.getResources().getDimension(R.dimen.badge_count_textsize);
mBadgePaint = new Paint();
mBadgePaint.setColor(ContextCompat.getColor(context.getApplicationContext(), R.color.background_color));
mBadgePaint.setAntiAlias(true);
mBadgePaint.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) {
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 centerX = (width - radius - 1) +5;
float centerY = radius -5;
if(mCount.length() <= 2){
// Draw badge circle.
canvas.drawCircle(centerX, centerY, (int)(radius+5.5), mBadgePaint);
}
else{
canvas.drawCircle(centerX, centerY, (int)(radius+6.5), 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;
}
}
Bước 4. Sử dụngđể set count trên icon ta thực hiện như sau:
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
setCount(this, "9");
}
public void setCount(Context context, String count) {
MenuItem menuItem = defaultMenu.findItem(R.id.ic_group);
LayerDrawable icon = (LayerDrawable) menuItem.getIcon();
CountDrawable badge;
// Reuse drawable if possible
Drawable reuse = icon.findDrawableByLayerId(R.id.ic_group_count);
if (reuse != null && reuse instanceof CountDrawable) {
badge = (CountDrawable) reuse;
} else {
badge = new CountDrawable(context);
}
badge.setCount(count);
icon.mutate();
icon.setDrawableByLayerId(R.id.ic_group_count, badge);
}
No comments:
Post a Comment