读呗开发过程中遇到新需求,类似于网易星球收集黑钻的界面,考虑到可能也有人会使用,索性封装成库,后面好移植使用
先看看需要实现的效果:
上面布局都是暂定的,后面封装的时候都保留了接口
public FloatView(Context context) {
this(context,null);
mcontext = context;
}
public FloatView(Context context, AttributeSet attrs) {
super(context, attrs);
mcontext = context;
}
public FloatView(Context context, AttributeSet attrs, int defStyleAttr) {
this(context, attrs);
mcontext = context;
}
LayoutParams params = new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT);
defaultView = (TextView) LayoutInflater.from(mcontext).inflate(R.layout.view_float, this, false); params.addRule(RelativeLayout.CENTER_IN_PARENT);
if (mFloat.size() != 0){
defaultView.setVisibility(GONE);
}
addView(defaultView,params);
子View随机坐标范围(保证不能出parentView的边界)
Random randomX = new Random();
Random randomY = new Random();
float x = randomX.nextFloat() * (parentWidth - childView.getMeasuredWidth());
float y = randomY.nextFloat() * (parentHeight - childView.getMeasuredHeight());
childView.setX(x);
childView.setY(y);
添加子View
for (int i = 0; i < mFloat.size(); i++) {
TextView floatview = (TextView) LayoutInflater.from(mcontext).inflate(R.layout.view_float, this, false);
setChildViewPosition(floatview);
floatview.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
addView(floatview);
}
Animation anim = new TranslateAnimation(0,0,-10,20);
anim.setInterpolator(new AccelerateDecelerateInterpolator());
anim.setDuration(ANIMATION_TIME);
anim.setRepeatCount(Integer.MAX_VALUE);
anim.setRepeatMode(Animation.REVERSE);//反方向执行
view.startAnimation(anim);
alueAnimator animator = ValueAnimator.ofFloat(parentHeight,0);
animator.setDuration(1000);
animator.setInterpolator(new LinearInterpolator());
//动画更新的监听
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
float Value = (float) animation.getAnimatedValue();
view.setAlpha(Value/parentHeight);
view.setTranslationY(view.getY()-(parentHeight-Value));
}
});
animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
removeView(view);
}
});
animator.start();
设置回调(详情见源码):
mListener.itemClick((int)view.getTag(),mFloat.get((int)view.getTag()));
1、获取的宽高为0?
view绘制过程中measure的时间和Activity的生命周期不能保持一致,所以可能在onCreate()中获取的宽高为0;
解决办法:使用post()
post(new Runnable() {
@Override
public void run() {
init();
}
});
2、子View的属性为wrap_content,获取的宽高为0,?
在获取的宽高的时候,先指定测量规则
int width = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
parentView.measure(width,height);
parentHeight = parentView.getMeasuredHeight();
parentWidth = parentView.getMeasuredWidth();
3、传输数据固定?
这里list使用Number类型的泛型,可以指定为int、float、double、long
public void setList(List extends Number> list){
...
//回调里
mListener.itemClick((int)view.getTag(),mFloat.get((int)view.getTag()));
}
GIthub地址:StarFloatView
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
ependencies {
compile 'com.github.ErChenZhang:StarFloatView:v1.1'
}
chidTextSize:小球文字大小,默认6sp
List list = new ArrayList<>();
list.add((float) 1.245);
list.add((float) 1.567);
list.add((float) 0.261);
floatview.setList(list);
floatview.setOnItemClickListener(new FloatView.OnItemClickListener() {
@Override
public void itemClick(int position, Number value) {
Toast.makeText(MainActivity.this, "当前是第"+position+"个,其值是"+value.floatValue(), Toast.LENGTH_SHORT).show();
}
});