您的位置:首页 > 其它

BadgeView实现源码分析

2016-08-07 12:26 246 查看
BadgeView实现:public class BadgeView extends TextView-->本质是TextView   (BadgetView:徽章,奖章)
使用
View target = findViewById(R.id.target_view);
BadgeView badge = new BadgeView(this, target);
badge.setText("1");	// TextView自带的方法
badge.show();

源码分析:
1.入口1 BadgeView badge = new BadgeView(this, target);
public BadgeView(Context context, View target) {
this(context, null, android.R.attr.textViewStyle, target, 0);
}

public BadgeView(Context context, AttributeSet attrs, int defStyle, View target, int tabIndex) {
super(context, attrs, defStyle);
init(context, target, tabIndex);
}

private void init(Context context, View target, int tabIndex) {

this.context = context;
this.target = target;
this.targetTabIndex = tabIndex;

// apply defaults
badgePosition = DEFAULT_POSITION;
badgeMarginH = dipToPixels(DEFAULT_MARGIN_DIP);
badgeMarginV = badgeMarginH;
badgeColor = DEFAULT_BADGE_COLOR;

setTypeface(Typeface.DEFAULT_BOLD);
int paddingPixels = dipToPixels(DEFAULT_LR_PADDING_DIP);
setPadding(paddingPixels, 0, paddingPixels, 0);
setTextColor(DEFAULT_TEXT_COLOR);

fadeIn = new AlphaAnimation(0, 1);
fadeIn.setInterpolator(new DecelerateInterpolator());
fadeIn.setDuration(200);

fadeOut = new AlphaAnimation(1, 0);
fadeOut.setInterpolator(new AccelerateInterpolator());
fadeOut.setDuration(200);

isShown = false;

applyTo(this.target);

}
/*
实现核心:
找到目标控件target,将该控件从其父控件中移除,并且添加一个新控件FrameLayout(这个控件添加原来目标控件和添加当前控件BadgeView)
*/
private void applyTo(View target) {

LayoutParams lp = target.getLayoutParams();
ViewParent parent = target.getParent();	// 找到目标控件的父控件
FrameLayout container = new FrameLayout(context);

// TODO verify that parent is indeed a ViewGroup
ViewGroup group = (ViewGroup) parent;
int index = group.indexOfChild(target);

group.removeView(target);
group.addView(container, index, lp);

container.addView(target);

this.setVisibility(View.GONE);	// 默认情况BadgetView是不可见
container.addView(this);

group.invalidate();	// 刷新显示
}

入口2:badge.show();
public void show() {
show(false, null);
}

private void show(boolean animate, Animation anim) {

applyLayoutParams();	// 实现:setLayoutParams(lp); lp为target的布局

if (animate) {	// 开启动画显示
this.startAnimation(anim);
}

this.setVisibility(View.VISIBLE);	// 使BadgetView可见,默认情况是不可见(构造的时候设置为GONE)
isShown = true;
}

总结:
1.BageView实现原理:把原本target去除掉,然后对target进行包装成FrameLayout,并添加到target原本位置中
1.1 找到target的parent
1.2 获取target在其parent中的位置,并把target从其对应的parent中移除掉
1.3 创建一个Framelayout把target和BadgetView添加到FrameLayout
1.4 把Framelayout添加到1.2步骤删除掉target的位置上去(这样原本target就好像没被删除一样)

2.实现的思路2:
类似之前ImageView的适配任何尺寸的宽高(谷歌应用市场),把要设置BadgetView的target外嵌套一个FrameLayout,然后通过
在FrameLayout中添加BadgetView这个控件,来实现类似功能
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: