携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情 >>
牙叔教程 简单易懂
接着上一篇教程: autojs模仿某东分类导航栏
某东不同分辨率效果
上一篇最后我们在模拟器上调试的代码, 在手机上文字显示不全,
我们来看看某东在不同分辨率下的显示情况
540X960
\
720X1280
\
900X1600
\
1080X1920
\
基本一致
我们再看看之前自己写的导航栏
1080X1920
540X960
\
完全不一样, 剩下的分辨率就不用看了
我们今天就来处理这个分辨率导致布局不一样的问题
分析宽高
一行5个类目, 字数 12 + 6, 一行大概18个字符的宽度, 不考虑右侧的分类;
我们要在一行放置18个字, 且每个分辨率都是18个字,
首先我们第一个基准分辨率, 模拟器当前设定的是 720X1280,
基本思路是: 以基准分辨率为准, 布局设计好以后, 其他分辨率换算为具体的像素值, 以便进行多分辨率布局适应.
这是18个字的效果
ui.layout(
<vertical>
<text id="content" textSize='20dp' bg='#cccccc' ></text>
</vertical>
);
ui.content.setText("牙叔".repeat(8)+'末尾');
文字单位选用的20dp
我们看看别的分辨率显示的效果怎么样
三种分辨率文字效果是一模一样的
\
为了使文字宽高在不同分辨率效果一样, 我们以后就使用dp来作为文字单位
添加文字的textSize属性
之前导航栏的子布局是
let itemLayout = (
<frame w="wrap_content" margin="8" h="60dp">
<View id="arcBg" h="match_parent" />
<text id="name" layout_gravity="center" w="wrap_content" h="wrap_content" margin="0" padding="0" textColor="#5e128a" gravity="center"></text>
</frame>
);
文字是没有设置textSize的, 我们加上去, textSize="20dp"
\
效果还是不一样
为什么设置了dp, 效果还是不一样
之前在onbindviewholder中, 我们会动态设置textsize大小, 我们先注释掉, 看看效果
\
这下文字大小就完全一致了
那么我们设置同样的字体大小, 效果又如何?
照理说应该一样才对, 现在是完全禁忌不一样, 我们用安卓的方法, 修改字体大小试试
原来修改字体大小是
view.name.attr("textSize", "20dp");
我们改为
view.name.setTextSize(android.util.TypedValue.COMPLEX_UNIT_DIP, 20);
\
aj修改字体大小有bug, 我们用安卓原生的setTextSize就没问题
文字宽度和动画的顺序问题
onBindViewHolder是RecyclerView数据更新的统一处理位置, 我们在这里会改变文字的大小;
我们来测试一下四个时刻的文字view的宽度
- setTextSize之前
- setTextSize之后
- ui.post
- ui.post 一秒后
我们只测试选中状态的文字宽度
动画是在点击之后, 也就是文字view已经可以看见了, 但是可能还不是选中状态, 而且可能发生滚动,
所以我们还要看一下点击的时候宽度的变化
- 点击之后
- 点击之后开始滚动, 滚动结束后
这说明只要view可见一部分, 那么就和整体可见, 宽度是一致的
宽高确定了, 那么就可以开始测试动画了, 动画是在滚动完成之后来绘制的
动画绘制
现在的问题是动画没反应
代码是这样的
animatorSweepAngle.addUpdateListener(
new ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate: function (animation) {
let value = animation.getAnimatedValue();
sweepAngle = -value;
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
canvas.drawColor(Color.GREEN);
},
});
log("currentArcView = " + currentArcView);
currentArcView.setBackgroundDrawable(drawable);
},
})
);
currentArcView = android.view.View{d2591f8 V.ED..... ......ID 0,0-160,120 #2}
view的宽高是有的, canvas调用drawColor绘制颜色也没问题, 但view背景就是没变成绿色, 好奇怪呀?
我们先不用animator, 先单独测试设置背景
"ui";
ui.layout(
<vertical>
<View id="test" w="100dp" h="100dp"></View>
</vertical>
);
let currentArcView = ui.test;
var drawable = new android.graphics.drawable.Drawable({
draw: function (canvas) {
canvas.drawColor(android.graphics.Color.GREEN);
},
});
currentArcView.setBackgroundDrawable(drawable);
单独测试是可以的;
上面这个是模拟器的效果, 我们在手机上也测试一下
手机上显示的是白色
我们把canvas绘制颜色的方法限制一下参数类型
把
canvas.drawColor(android.graphics.Color.GREEN);
改成
canvas["drawColor(int)"](android.graphics.Color.GREEN);
改完以后, 在手机上和模拟上就都是绿色了
我们多加点日志
onBindViewHolder: function (holder, position) {
log("onBindViewHolder");
我每点击一次文字控件, 就会打印一次 onBindViewHolder;
那么onbind和动画孰先孰后呢?
我们继续添加日志
'onBindViewHolder: 进入',
'onBindViewHolder: setText',
'drawArc: 进入',
'drawArc: setText' ]
先 onbind 后 drawarc, 顺序和预期一样,
如果修改背景不行的话, 我们试试修改文字
view2.setText('aaaaaaaa')
点击以后文字确实修改了, 可是又很快变回原来的 推荐. 这是为什么呢?
这里就有一个知识点, 你觉得你能单独控制recyclerview里的view吗?
从实际情况来看, 并不能, 就能勉强能, 也有各种各样的bug,
所以, 我们把动画迁移到 onBindViewHolder 中.
可以看到, 用同样的方法修改背景色, 是没问题的
什么时候触发动画?
- 从未选中状态变成了选中状态
- 滚动完成以后
- 通知recyclerview控件可以开始动画了
先来看第一条, 从未选中状态变成了选中状态:
如果本来就是选中的, 那么我们什么都不需要做;
如果不是选中的, 那么开始判断有没有滚动完成;
这个选中状态的判断是在 onCreateViewHolder 中的控件点击事件中处理的;
view.click(function (view) {
let position = holder.getPosition();
if (items[position].selected) {
return true;
}
...
再看第二条: 滚动完成以后
这个肯定是在监听里面才能知道, 我们添加的监听是
rv.addOnScrollListener(
new Packages.androidx.recyclerview.widget.RecyclerView.OnScrollListener({
onScrollStateChanged: function (recyclerView, newState) {
if (newState == 0) {
// 滚动完成
...
\
最后是第三条, 在滚动完成后, 通知recyclerview更新
if (newState == 0) {
recycleAdapter.notifyItemChanged(currentCategory.num);
}
通知更新以后, 触发onBindViewHolder
接下来开始迁移真正的动画部分, 下次再说
环境
手机:小米11pro
MIUI: 13.0.12
Android版本: 12
Autojs版本: 9.2.6
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程\
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途\