牙叔教程 简单易懂
接着上一篇教程
autojs模仿某东分类导航栏
https://www.yuque.com/yashujs/bfug6u/novbne
上一篇教程写了导航栏的基础部分, 这篇教程我们添加导航栏的动画
他这个动画是在文字下方画一段圆弧, 是有画这个过程的, 大概300ms;
canvas画圆弧的方式是
drawArc(RectF oval, float startAngle, float sweepAngle, boolean useCenter, Paint paint)//画弧,
我们先单独测试画圆弧
ui.layout(
);
真个界面就只有一个canvas
设置canvas的canvas事件
let startAngle = 135;
let sweepAngle = -100;
let useCenter = false;
ui.board.on("draw", function (canvas) {
canvas.drawColor(colors.BLACK);
canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint); //画弧,
});
画出来的圆弧是这样的
通过修改背景的方式让他慢慢画完
我们搞一个示例看看
就给只有一个View
ui.layout(
);
给View设置背景
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
canvas["drawColor(int)"](colors.BLACK);
canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint); //画弧,
},
});
ui.board.setBackgroundDrawable(drawable);
其中的sweepAngle, 我们用 ValueAnimator 来控制
animator.addUpdateListener(
new ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate: function (animation) {
let value = animation.getAnimatedValue();
sweepAngle = -value;
...
},
})
);
慢慢画弧 演示效果
let itemLayout = (
);
然后在点击事件中, 添加动画, 这时又遇到一个问题,
这里我们设计为在滚动结束之后, 开始执行动画;
新的问题又来了, 我们怎么知道滚动结束了?
我们给rv添加一个滚动监听
rv滚动有三种状态
//停止滚动
public static final int SCROLL_STATE_IDLE = 0;
//正在被外部拖拽,一般为用户正在用手指滚动
public static final int SCROLL_STATE_DRAGGING = 1;
//自动滚动开始
public static final int SCROLL_STATE_SETTLING = 2;
我们只需要在监听 停止滚动 的时候, 开始画圆弧
圆弧的起点是哪里?
再次查看某东的动画, 可知, 圆弧在文字中间正下方, 左右各一半圆弧;
那么
圆弧的起点横坐标 = 文字控件中心横坐标 - 一个字的宽度*0.75
圆弧的起点纵坐标 = 文字底部纵坐标
在按照这个公式计算的时候, 发现一个问题: 作为背景的view宽度是0!
作为动画的背景xml是这样的
整个itemXml是这样的
let itemLayout = (
);
动画背景宽度是0的话, 我们这个计算就没用了, 宽度为0的画板, 画啥也看不见;
因此, 我们得改改这个itemLayout, 修改之后的itemLayout, 动画背景的宽高以textView为标准
let itemLayout = (
);
动画背景的宽度arcBg要在recyclerview的onBindViewHolder方法中动态设置
onBindViewHolder: function (holder, position) {
...
let textViewWidth = getViewWidth(view.name);
view.arcBg.attr("w", textViewWidth + "px");
}
动画背景的宽度解决以后, 我们就可以套用上面的公式了,
画圆弧的效果如下:
这个圆弧是瞬间绘制的, 不是慢慢画出来的, 我们要加一个 ValueAnimator 来控制这个圆弧 sweepAngle 的数值在一定时间内慢慢变大
我们来看看 这个监听器怎么写的
let updateListener = new ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate: function (animation) {
let value = animation.getAnimatedValue();
sweepAngle = -value;
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint); //画弧,
},
});
ui.board.setBackgroundDrawable(drawable);
},
});
animator.addUpdateListener(updateListener);
监听器的方法都是类似了, 只有几个参数需要发生变化, 我们有两种写监听器的思路
我选择第二种, 那么我们来看看监听器里面有哪些参数需要外部修改
其他参数都不需要外部修改, 因为某东导航栏的动画都是一模一样的, 圆弧的起点, 终点, 高度, 都没有任何变化
我们就定义一个变量, 来引用当前的动画view
let currentArcView=null;
2s慢动画效果
颜色应该加一个渐渐透明, 那么我们就再加一个 ValueAnimator, 用来管理透明度
let animator = new AnimatorSet();
let animatorSweepAngle = ValueAnimator.ofInt(0, 100);
let animatorAlpha = ValueAnimator.ofInt(0, 255);
animator.playTogether([animatorSweepAngle, animatorAlpha]);
但是问题来了, 慢慢画的效果出来了, 最后透明全都看不见了
因此, 我们这种修改背景, 模拟动画的方式需要改改
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
paint.setColor(colors.argb(currentAlpha, red, green, blue));
canvas.drawArc(oval, startAngle, sweepAngle, useCenter, paint); //画弧,
},
});
currentArcView.setBackgroundDrawable(drawable);
怎么改呢?
我们给画笔设置shader, 我们做一个 LinearGradient, 搞成渐变色那种, 从左往右, 渐渐透明
public LinearGradient(float x0, float y0, float x1, float y1, @NonNull @ColorInt int colors[], @Nullable float positions[], @NonNull TileMode tile)
let linearGradient = new LinearGradient(0, 150, 300, 150, colorArr, positions, Shader.TileMode.CLAMP);
let paint = new Paint();
paint.setShader(linearGradient);
ui.board.on("draw", function (canvas) {
canvas.drawColor(colors.BLACK);
canvas.drawRect(0, 0, 300, 300, paint);
});
渐渐透明的紫色
接下来, 我们就用shader的方式来解决动画问题, 透明度的修改就没必要了, 因为透明度已经被包含在shader里面了
// animator.playTogether([animatorSweepAngle, animatorAlpha]);
animator.playTogether([animatorSweepAngle]);
渐变的动画效果
新的问题又出现了, 我点击的是 酒水饮料, 可他还是在 个护清洁 上面做动画
这个明显是因为没有及时更新点击的控件, 我们更新即可
新的问题又来了, 点击那个控件, 那个控件就做动画, 上一个控件没有清理动画
那么, 我们需要给数据添加一个状态属性, 勾选或者没有勾选
上面是在模拟器测试的, 我们去手机上看看效果
手机上字都显示不全
除了这个问题, 还有一些别的问题, 下次再解决
手机:小米11pro
MIUI: 13.0.12
Android版本: 12
Autojs版本: 9.2.6
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途
留言与评论(共有 0 条评论) “” |