牙叔教程 简单易懂
这种移动背景的效果, 怎么做呢?
我们把背景看成一个小球, 小球可以在某个空间内自由移动, 他需要一个目标的坐标信息,
然后需要一个从当前的起点, 到目标点的移动规则,
小球也可以在移动的时候变换形态, 比如圆形, 椭圆, 圆角矩形等
- 小球可以活动的空间, 我们可以看成是一个父控件, 小球只能在父控件的宽高之内移动;
- 小球的移动规则, 对应的是加速度, 这个由属性动画控制;
- 小球的角色是当某个控件的背景, 比如文字控件, 他的半径, 或者说, 宽高, 是由文字控件的宽高决定的
基本分析完成, 我们设计一下对应的接口
- 父控件有宽高, width, height
- 小球要移动, 有起点和目标点, startPoint, targetPoint
- 小球的加速度, 内部用属性动画即可, 需不要暴露接口
- 小球的宽高, 由文字控件决定, 文字控件的宽高有的一样, 有的不一样, targetViewWidth
- 未来我们要把小球绑定到导航栏之类的做背景使用, 未来在说未来, 我们先把当前基本的搞好
移动背景的实现方式
有两种
- 父子控件, 两个控件
- 单个控件, 内部用canvas绘制
我觉得两个控件消耗大, 我们选择第二种
开始写代码
第一步: 写一个基本的自定义控件
自定义控件的基本方法可以看这篇教程
autojs自定义组件 https://www.yuque.com/yashujs/bfug6u/rbho2n
"ui";
importClass(android.view.View);
var MyView = (function () {
//继承至ui.Widget
util.extend(MyView, ui.Widget);
function MyView() {
ui.Widget.call(this);
}
MyView.prototype.render = function () {
return <View bg="#ff00ff"></View>;
};
ui.registerWidget("my-view", MyView);
return MyView;
})();
ui.layout(
<vertical>
<my-view w="300dp" h="100dp"></my-view>
</vertical>
);
这就是一个可以设置宽高的基本的自定义控件
第二步: 绘制小球
小球是作为背景来使用, 一般给文字控件做背景, 文字背景的形状基本是圆角矩形
我们来绘制一个圆角矩形
MyView.prototype.drawRoundRect = function (rect, color) {
color = colors.parseColor(color);
this.paint.setColor(color);
let view = this.view;
let that = this;
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
var paint = new android.graphics.Paint();
paint.setColor(color);
canvas.drawRoundRect(rect, this.rx, this.ry, that.paint);
},
});
view.setBackgroundDrawable(drawable);
};
还差一个rect, 这个rect就是一个矩形, 矩形大小应该包括文字控件,
现在没有文字控件, 所以我们自己构造一个rect,
假设rect的left top right bottom 是(120, 53, 312,168)
MyView.prototype.drawBall = function (left, top, right, bottom, color) {
let rect = new RectF(left, top, right, bottom);
this.drawRoundRect(rect, color);
};
MyView.prototype.onFinishInflation = function (view) {
this.drawBall(120, 53 - status_bar_height, 312, 168 - status_bar_height, "#00ffff");
};
我们在onFinishInflation方法中, 绘制圆角矩形
让小球移动
在不该变矩形大小的情况下, 移动就是修改横坐标的值, 我们来写个move方法,
目前我们没有绑定任何文本控件, 没有具体的移动数值, 就随便写个数字
MyView.prototype.comeAndGo = function (comeLeft, goLeft, color) {
let top = this.initRect.top;
let bottom = this.initRect.bottom;
let that = this;
let width = this.initRect.right - this.initRect.left;
var valueAnimator = android.animation.ValueAnimator.ofFloat(comeLeft, goLeft);
valueAnimator.setDuration(1000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE); //无限循环
valueAnimator.setRepeatMode(ValueAnimator.REVERSE); //ValueAnimator.RESTART(重复),ValueAnimator.REVERSE(反方向重复)
valueAnimator.setInterpolator(new android.view.animation.AnticipateOvershootInterpolator());
valueAnimator.addUpdateListener(
new ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate: function (valueAnimator) {
let value = valueAnimator.getAnimatedValue();
left = value;
right = value + width;
let rect = new RectF(left, top, right, bottom);
that.drawRoundRect(rect, color);
},
})
);
valueAnimator.start();
};
调用这个来回动comeAndGo方法, 第一个参数和第二个参数是起点横坐标, 第三个是前景色
this.comeAndGo(60, 300, this.foreColor);
这个动画使用的插值器是 AnticipateOvershootInterpolator, 他的效果是
其变化开始向后甩,然后向前甩,过冲到目标值,最后又回到了终值
重复方式是 ValueAnimator.REVERSE,
更多的插值器介绍可以看这个博客:
Android动画之Interpolator(插值器)
https://blog.csdn.net/pzm1993/article/details/77926373
那么, 到此为止, 这个会移动的背景, 他的雏形就有了, 改天再拓展
环境
雷电: 4.0.63
Android版本: 7
Autojs版本: 8.8.20
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途