android - 使用 FloatingSearchView android 在操作菜单栏上显示徽章
问题描述
我正在为搜索栏使用arimorty/floatingsearchview库,它工作正常,但现在我想要一个带有红色圆圈/徽章的通知图标,没有计数,但找不到制作它的方法。
活动中:
<com.arlib.floatingsearchview.FloatingSearchView
android:id="@+id/floating_search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:floatingSearch_searchHint="Search..."
app:floatingSearch_suggestionsListAnimDuration="250"
app:floatingSearch_showSearchKey="false"
app:floatingSearch_leftActionMode="showHamburger"
app:floatingSearch_menu="@menu/searchbar_sidemenu"
app:floatingSearch_close_search_on_keyboard_dismiss="true"
android:paddingEnd="10dp"
android:paddingStart="10dp"
android:paddingTop="10dp"/>
菜单代码:
<?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/action_notification"
android:title="Notification"
app:showAsAction="ifRoom"
android:icon="@drawable/ic_notifications_none_black_24dp"/>
</menu>
我尝试了其他答案,但没有一个对我有用。
如果需要,我将解释/澄清或分享 java 代码。
[更新]
我试图实现这个答案和其他答案。
在 GitHub repo 中搜索并找到了这个但不明白。
解决方案
改变你的搜索图标使用这个:
myIcon.setDrawable(setBadgeCount(context, R.drawable.ic_shopping_cart_primary, 1));
使用这个类来改变 drawable 与 badgedDrawable:
public static 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));
assert icon != null;
icon.mutate();
icon.setDrawableByLayerId(R.id.ic_badge, badge);
icon.setDrawableByLayerId(R.id.ic_main_icon, mainIcon);
return icon;
}
创建此类:
import android.content.Context;
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;
import androidx.annotation.NonNull;
public class BadgeDrawable extends Drawable {
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) {
float mTextSize = dpToPx(context); //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) {
return TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, (float) 8, context.getResources().getDisplayMetrics());
}
@Override
public void draw(@NonNull 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;
}
}
setCount
如果你mWillDraw = !count.equalsIgnoreCase("0");
想显示true
没有数字
资源:
ic_badge_drawable.xml
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/ic_main_icon"
android:drawable="@drawable/ic_shopping_cart_primary"
android:gravity="center" />
<!-- set a place holder Drawable so android:drawable isn't null -->
<item android:id="@+id/ic_badge"
android:drawable="@drawable/ic_shopping_cart_primary" />
</layer-list>
用任何drawable替换ic_shopping_cart_primary,这不是uset,只是默认的
查看代码并更改 setCount 以通过“”(空格)
推荐阅读
- java - 如何自动设置 chromedriver 路径?
- c# - Asp.net Core MVC - 在表单发布到控制器操作中的控制器 IEnumerable 模型为空
- c# - HttpRequestMessage 在发送请求后被处理
- jenkins - 获取 Jenkins 多分支管道中的分支列表
- unit-testing - 张量流测试中的渴望和图形执行
- dask - 我可以在 dask/helm-chart 中将 requirements.txt 指定为 EXTRA_PIP_PACKAGES
- vba - 如何在不寻常的时间格式之间转换 golang
- r - R 中 MI 数据的描述性统计:取 3
- ubuntu-18.04 - Ubuntu 18.04 在安装时崩溃到 tty1
- java - 提取刷新令牌值