项目需要 效果如图
第一次使用了 BadgeView 这个第三方控件
badgeview中常用的方法:
1. setTargetView(View) --> 设置哪个控件显示数字提醒,参数就是一个view对象
2. setBadgeCount(int) --> 设置提醒的数字
3. setBadgeGravity(Gravity) --> 设置badgeview的显示位置
4. setBackgroundColor() --> 设置badgeview的背景色,当然还可以设置背景图片
5. setBackgroundResource() --> 设置背景图片
6. setTypeface() --> 设置显示的字体
7. setShadowLayer() --> 设置字体的阴影
- badgeView = new BadgeView(this);
- badgeView.setTargetView(layout);
- badgeView.setBadgeGravity(Gravity.BOTTOM | Gravity.CENTER);
- badgeView.setBadgeCount(4);
- badgeView = new BadgeView(this);
- badgeView.setTargetView(layout);
- badgeView.setBackground(12, Color.parseColor("#9b2eef"));
- badgeView.setText("提示");
badgeview.java
import android.content.Context; | |
import android.graphics.Color; | |
import android.graphics.Typeface; | |
import android.graphics.drawable.ShapeDrawable; | |
import android.graphics.drawable.shapes.RoundRectShape; | |
import android.util.AttributeSet; | |
import android.util.Log; | |
import android.util.TypedValue; | |
import android.view.Gravity; | |
import android.view.View; | |
import android.view.ViewGroup; | |
import android.widget.FrameLayout; | |
import android.widget.FrameLayout.LayoutParams; | |
import android.widget.TabWidget; | |
import android.widget.TextView; | |
public class BadgeView extends TextView { | |
private boolean mHideOnNull = true; | |
public BadgeView(Context context) { | |
this(context, null); | |
} | |
public BadgeView(Context context, AttributeSet attrs) { | |
this(context, attrs, android.R.attr.textViewStyle); | |
} | |
public BadgeView(Context context, AttributeSet attrs, int defStyle) { | |
super(context, attrs, defStyle); | |
init(); | |
} | |
private void init() { | |
if (!(getLayoutParams() instanceof LayoutParams)) { | |
LayoutParams layoutParams = | |
new LayoutParams( | |
android.view.ViewGroup.LayoutParams.WRAP_CONTENT, | |
android.view.ViewGroup.LayoutParams.WRAP_CONTENT, | |
Gravity.RIGHT | Gravity.TOP); | |
setLayoutParams(layoutParams); | |
} | |
// set default font | |
setTextColor(Color.WHITE); | |
setTypeface(Typeface.DEFAULT_BOLD); | |
setTextSize(TypedValue.COMPLEX_UNIT_SP, 11); | |
setPadding(dip2Px(5), dip2Px(1), dip2Px(5), dip2Px(1)); | |
// set default background | |
setBackground(9, Color.parseColor("#d3321b")); | |
setGravity(Gravity.CENTER); | |
// default values | |
setHideOnNull(true); | |
setBadgeCount(0); | |
} | |
public void setBackground(int dipRadius, int badgeColor) { | |
int radius = dip2Px(dipRadius); | |
float[] radiusArray = new float[] { radius, radius, radius, radius, radius, radius, radius, radius }; | |
RoundRectShape roundRect = new RoundRectShape(radiusArray, null, null); | |
ShapeDrawable bgDrawable = new ShapeDrawable(roundRect); | |
bgDrawable.getPaint().setColor(badgeColor); | |
setBackground(bgDrawable); | |
} | |
/** | |
* @return Returns true if view is hidden on badge value 0 or null; | |
*/ | |
public boolean isHideOnNull() { | |
return mHideOnNull; | |
} | |
/** | |
* @param hideOnNull the hideOnNull to set | |
*/ | |
public void setHideOnNull(boolean hideOnNull) { | |
mHideOnNull = hideOnNull; | |
setText(getText()); | |
} | |
/* | |
* (non-Javadoc) | |
* | |
* @see android.widget.TextView#setText(java.lang.CharSequence, android.widget.TextView.BufferType) | |
*/ | |
@Override | |
public void setText(CharSequence text, BufferType type) { | |
if (isHideOnNull() && (text == null || text.toString().equalsIgnoreCase("0"))) { | |
setVisibility(View.GONE); | |
} else { | |
setVisibility(View.VISIBLE); | |
} | |
super.setText(text, type); | |
} | |
public void setBadgeCount(int count) { | |
setText(String.valueOf(count)); | |
} | |
public Integer getBadgeCount() { | |
if (getText() == null) { | |
return null; | |
} | |
String text = getText().toString(); | |
try { | |
return Integer.parseInt(text); | |
} catch (NumberFormatException e) { | |
return null; | |
} | |
} | |
public void setBadgeGravity(int gravity) { | |
FrameLayout.LayoutParams params = (LayoutParams) getLayoutParams(); | |
params.gravity = gravity; | |
setLayoutParams(params); | |
} | |
public int getBadgeGravity() { | |
FrameLayout.LayoutParams params = (LayoutParams) getLayoutParams(); | |
return params.gravity; | |
} | |
public void setBadgeMargin(int dipMargin) { | |
setBadgeMargin(dipMargin, dipMargin, dipMargin, dipMargin); | |
} | |
public void setBadgeMargin(int leftDipMargin, int topDipMargin, int rightDipMargin, int bottomDipMargin) { | |
FrameLayout.LayoutParams params = (LayoutParams) getLayoutParams(); | |
params.leftMargin = dip2Px(leftDipMargin); | |
params.topMargin = dip2Px(topDipMargin); | |
params.rightMargin = dip2Px(rightDipMargin); | |
params.bottomMargin = dip2Px(bottomDipMargin); | |
setLayoutParams(params); | |
} | |
public int[] getBadgeMargin() { | |
FrameLayout.LayoutParams params = (LayoutParams) getLayoutParams(); | |
return new int[] { params.leftMargin, params.topMargin, params.rightMargin, params.bottomMargin }; | |
} | |
public void incrementBadgeCount(int increment) { | |
Integer count = getBadgeCount(); | |
if (count == null) { | |
setBadgeCount(increment); | |
} else { | |
setBadgeCount(increment + count); | |
} | |
} | |
public void decrementBadgeCount(int decrement) { | |
incrementBadgeCount(-decrement); | |
} | |
/* | |
* Attach the BadgeView to the TabWidget | |
* | |
* @param target the TabWidget to attach the BadgeView | |
* | |
* @param tabIndex index of the tab | |
*/ | |
public void setTargetView(TabWidget target, int tabIndex) { | |
View tabView = target.getChildTabViewAt(tabIndex); | |
setTargetView(tabView); | |
} | |
/* | |
* Attach the BadgeView to the target view | |
* | |
* @param target the view to attach the BadgeView | |
*/ | |
public void setTargetView(View target) { | |
if (getParent() != null) { | |
((ViewGroup) getParent()).removeView(this); | |
} | |
if (target == null) { | |
return; | |
} | |
if (target.getParent() instanceof FrameLayout) { | |
((FrameLayout) target.getParent()).addView(this); | |
} else if (target.getParent() instanceof ViewGroup) { | |
// use a new Framelayout container for adding badge | |
ViewGroup parentContainer = (ViewGroup) target.getParent(); | |
int groupIndex = parentContainer.indexOfChild(target); | |
parentContainer.removeView(target); | |
FrameLayout badgeContainer = new FrameLayout(getContext()); | |
ViewGroup.LayoutParams parentLayoutParams = target.getLayoutParams(); | |
badgeContainer.setLayoutParams(parentLayoutParams); | |
target.setLayoutParams(new ViewGroup.LayoutParams( | |
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); | |
parentContainer.addView(badgeContainer, groupIndex, parentLayoutParams); | |
badgeContainer.addView(target); | |
badgeContainer.addView(this); | |
} else if (target.getParent() == null) { | |
Log.e(getClass().getSimpleName(), "ParentView is needed"); | |
} | |
} | |
/* | |
* converts dip to px | |
*/ | |
private int dip2Px(float dip) { | |
return (int) (dip * getContext().getResources().getDisplayMetrics().density + 0.5f); | |
} | |
} |
这个方法比较偷懒 直接用第三方就好了 后来感觉消息提示数量的位置不好调整 就放弃了这个方法 直接自己写个简单布局
<RelativeLayout android:id="@+id/image_message" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_gravity="right" android:layout_centerVertical="true"> <ImageView android:layout_width="30dp" android:layout_height="20dp" android:layout_centerInParent="true" android:layout_marginRight="@dimen/x30" android:src="@mipmap/bell" /> <TextView android:id="@+id/tv_messagenumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentRight="true" android:layout_marginRight="10dp" android:layout_marginTop="10dp" android:background="@drawable/red" android:gravity="center" android:textColor="@color/white" android:textSize="10sp" android:visibility="gone" />
</RelativeLayout>
message为消息数量
if (message > 0 && message < 100) { tv_messagenumber.setVisibility(View.VISIBLE); tv_messagenumber.setText("" + message); } else if (message >= 100) { tv_messagenumber.setVisibility(View.VISIBLE); tv_messagenumber.setText("99+"); } else { tv_messagenumber.setVisibility(View.GONE); }
就这样了 麻烦一点 但是对于提示的位置方便修改 也达到了我要的效果