使用 fragmentLayout 实现,可以把小红点添加到任意 view 上。
效果 添加小红点到 textview 上
添加小红点到 imageview 上
首先定义一个圆形 drawable
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Paint; import android.graphics.PixelFormat; import android.graphics.drawable.Drawable; import android.graphics.drawable.ShapeDrawable;
import androidx.annotation.IntRange; import androidx.annotation.NonNull; import androidx.annotation.Nullable;
public class CircleDrawable extends ShapeDrawable { private Paint mPaint; private int mRadio;
public CircleDrawable(int radio, int painColor) { mPaint = new Paint(); mPaint.setAntiAlias(true); mPaint.setColor(painColor); mRadio = radio; }
@Override public void draw(@NonNull Canvas canvas) { canvas.drawCircle(mRadio, mRadio, mRadio, mPaint); }
@Override public void setAlpha(@IntRange(from = 0, to = 255) int i) { mPaint.setAlpha(i); }
@Override public void setColorFilter(@Nullable ColorFilter colorFilter) { mPaint.setColorFilter(colorFilter); }
@Override public int getOpacity() { return PixelFormat.TRANSLUCENT; }
/*** * drawable实际宽高,圆形关键 * * @return */ @Override public int getIntrinsicWidth() { return mRadio * 2; }
@Override public int getIntrinsicHeight() { return mRadio * 2; } } |
思路:
一个容器 fragmentLayout 包含两个 view (小红点view + 文本view 「当然也可以是其他的view」),通过 fragmentLayout 添加 view 重叠的特征实现
当前有待优化点:
1、通过 margin 实现小红点可以添加到任意位置「可以是有 layoutparams margin 实现」
2、其他
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.ShapeDrawable; import android.graphics.drawable.shapes.OvalShape; import android.graphics.drawable.shapes.RoundRectShape; import android.util.AttributeSet; import android.util.Printer; import android.view.Gravity; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.TextView;
import androidx.annotation.Nullable;
import com.primer.common.constant.GravityDirection; import com.primer.common.mvp.LoginInterface; import com.primer.common.util.LogHelper; import com.primer.common.util.UiHelper; import com.primer.common.view.drawable.CircleDrawable;
public class BadgeView extends TextView {
private final int DEFAULT_BADGE_RADIO = 5; private final int DEFAULT_TEXT_SIZE = 5; private final int DEFAULT_TEXT_COLOR = Color.WHITE; private final int DEFAULT_BADGE_COLOR = Color.RED; private final int DEFAULT_BADGE_GRAVITY = GravityDirection.DIRECT_TOP_LEFT;
private String mText; private int mBadgeColor = DEFAULT_BADGE_COLOR; private int mTextColor = DEFAULT_TEXT_COLOR; private int mTextSize = DEFAULT_TEXT_SIZE; private int mBadgeRadio = DEFAULT_BADGE_RADIO; private int mBadgeGravity = DEFAULT_BADGE_GRAVITY;
private FrameLayout mFragmentLayout; private ViewGroup mTargetViewGroup; private View mTarget; private Context mContext;
public BadgeView(Context context) { super(context); init(context); }
public BadgeView(Context context, @Nullable AttributeSet attrs) { super(context, attrs); init(context); }
public BadgeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); }
public BadgeView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); init(context); }
private void init(Context context) { mFragmentLayout = new FrameLayout(context); mFragmentLayout.setLayoutParams(new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); mContext = context; }
/*** * * @param content * @param target * @param textColor * @param textSize * @param badgeColor * @param badgeRadio */ public void showBadgeView(String content, View target, int textColor, int textSize, int badgeColor, int badgeRadio) { if (target == null) { throw new IllegalArgumentException("target view must not be null"); }
mTarget = target; mTargetViewGroup = (ViewGroup) target.getParent(); mTargetViewGroup.removeView(target); mTargetViewGroup.addView(mFragmentLayout, target.getLayoutParams());
setTextColor(mTextColor); setTextSize(mTextSize); setGravity(Gravity.CENTER); if (content != null && content.length() <= 3) { setText(content); }
//文字和半径之间的适配 if (content != null) { Rect rect = new Rect(); this.getPaint().getTextBounds(content, 0, content.length(), rect); if (content.length() <= 3 && rect.width() >= mBadgeRadio) { mBadgeRadio = (UiHelper.px2dip(mContext, rect.width()) / 2) + 1; } }
setBackgroundDrawable(getShapeDrawable()); mFragmentLayout.addView(target); mFragmentLayout.addView(this); mTargetViewGroup.invalidate(); }
private ShapeDrawable getShapeDrawable() { int radio = UiHelper.dip2px(mContext, mBadgeRadio); CircleDrawable drawable = new CircleDrawable(radio, mBadgeColor); return drawable; }
/*** * * @param content * @param target */ public void showBadgeView(String content, View target) { showBadgeView(content, target, DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, DEFAULT_BADGE_COLOR, DEFAULT_BADGE_RADIO); }
public void showBadgeView(View target) { showBadgeView(null, target, DEFAULT_TEXT_COLOR, DEFAULT_TEXT_SIZE, DEFAULT_BADGE_COLOR, DEFAULT_BADGE_RADIO); }
@Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { super.onMeasure(widthMeasureSpec, heightMeasureSpec); }
@Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); }
@Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); } } |
使用
1 2 3 4 5 |
private BadgeView mReadBadgeView; private TextView mRead;
mReadBadgeView = new BadgeView(getActivity()); mReadBadgeView.showBadgeView("+99", mRead); |