牙叔教程 简单易懂
提词器使用场景
拍短视频
- 忘词
- 记不住台词
有了提词器, 就再也不怕忘词儿了
提词器类型
- 提词板, 属于普通的app界面
- 悬浮窗, 一般是悬浮于照相机上面, 或者某音某手上面
提词器主界面设计
- 加号按钮, 添加台本
- 台本列表,
提词板界面设计
- 上方5个菜单, 依次是: 返回, 横竖屏幕, 设置, 镜像, 从头开始;
- 中间最大的区域, 是显示台词的地方
新增台本和编辑台本的界面类似
分为上下两部分
- 上面是标题
- 下面是内容
设置界面设计
- 高度大概占据屏幕二分之一
- 修改的界面属性有:文字颜色, 背景色, 文字大小, 文字间距, 播放速度, 透明度
- 颜色勾选后, 颜色上面有一个对勾
- 左上角重置按钮, 所有属性归为初始状态
- 右上角关闭按钮, 点击之后, 会记住本次设置, 打开其他台本, 也是一样的设置
绘制加号按钮
绘制渐变色
这是一个RadialGradient, 翻译径向渐变, 或者放射渐变
绘制某音风格的按钮
这个使用的方法是
view.setForeground(drawable);
drawable中, 重写了他的draw方法, 在draw方法中, 绘制了三个圆角矩形, 同时有一定的平移和旋转
canvas.rotate
canvas.translate
绘制中间的十字
十字就简单多了, 就是横竖两条直线, 再计算一下view的宽高, 使其居中即可
完成
台本界面设计
主要是一个 <list> 标签,
小白点, 标题, 以及右侧的编辑和删除按钮, 在视觉上应该是处于同一水平线;
字数和时间
<text text="{{this.content.length}}字 | "></text>
<text text="{{this.time}}"></text>
自动计算content的字数, 时间格式使用年月日时分秒
let formatter = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
let time = "" + formatter.format(new Date());
开始提词
外部是一个<card>, 背景色与父控件颜色稍有不同, 以便在视觉上, 显示为一个按钮
提词器模式选择
这是一个dialog
let arr = ["悬浮窗模式", "提词板模式"];
let item = itemHolder.item;
dialogs.singleChoice("", arr).then(
function (index) {
...
}
);
提词板顶部菜单
提词模式有普通UI和悬浮窗两种, 为了在视觉上让两种模式界面相像, 这里使用的是按照比例来设置他们的位置
<horizontal>
<img w="0" layout_weight="1"></img>
<img w="0" layout_weight="1"></img>
<img w="0" layout_weight="1"></img>
<img w="0" layout_weight="1"></img>
<img w="0" layout_weight="1"></img>
</horizontal>;
返回按钮
ui.返回.click(function () {
engines.myEngine().forceStop();
});
横竖屏按钮
ui.旋转.click(function () {
if (yashuUtil.isHorizontalScreen()) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); //竖屏
} else {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //强制为横屏
}
});
镜像按钮
提词板中间的播放按钮
播放按钮是一个png图片, 有透明通道, 可以涂抹为任何颜色, 其他按钮, 基本也都是png图片;
点击播放按钮后, 会有3秒钟倒计时, 然后文字开始滚动
文字滚动
滚动一般使用的是<scroll>, 不过scroll滚动的时候, 即使滚动到最大值, 屏幕上依然有文字;
后来就换成了textview自带的scroll方法, 这样就可以把所有文字都滚动到屏幕之外了;
textView.scrollTo(0, value);
为了使界面匀速滚动, 这里使用了
ValueAnimator.ofFloat
同时, 插值器使用的是 LinearInterpolator
监听animator的数值变化, 对应滚动textview
animator.addUpdateListener(
new ValueAnimator.AnimatorUpdateListener({
onAnimationUpdate: function (valueAnimator) {
let value = valueAnimator.getAnimatedValue();
textView.scrollTo(0, value);
},
})
);
上面这些还算简单的, 真正复杂的是交互, 尤其是设置界面和提词板的交互, 比如:
- 调整文字大小, 提词板的文字要跟着变
- 调整播放速度, 提词板的速度也要跟着变,
- 如果调整播放速度的时候, 提词板还没有播放, 那么你要记住这次调整的数值, 以便播放的时候用对应的速度
- 设置界面关了, 本次设置的数据都要保存下来, 以免用户频繁设置, 嫌麻烦
- seekbar的默认区间是0到100, 还要各种换算合适的系数, 对应不同的属性
- 修改文字颜色同样麻烦, 文字颜色使用的是自定义控件, 为了复用, 因为背景颜色也是要选择颜色的
- 颜色选择封装了一个 <grid>标签, 还添加了一些方法, 比如获取颜色, 设置颜色;
- 颜色都是互斥的, 你选了这个颜色, 那个研究就要取消勾选
悬浮窗提词板
悬浮窗和普通UI的提词板哪里不一样呢?
第一个不一样的地方是把顶部菜单的横竖屏取消了, 因为悬浮窗无法控制横竖屏, 没有activity属性;
第二个不一样的地方是在悬浮窗底部增加了两个按钮
- 移动
- 调整悬浮窗大小
移动悬浮窗
调整悬浮窗大小
第三个不一样的地方是修改了一下背景色
细心的你还可以看到, seekbar的颜色也变了;
第三个不一样的地方是设置界面由原先的 BottomSheetDialog 更换为了悬浮窗, 也就是说, 悬浮窗模式的提词板, 一共有2个悬浮窗
- 一个悬浮窗显示台词
- 另一个悬浮窗显示设置界面
为了让悬浮窗和 BottomSheetDialog 视觉上看上去差不多, 我们把悬浮窗放在了屏幕底部;
小技巧
为了使悬浮窗出现的不太突兀, 我们一开始设置悬浮窗的透明度为0, 也就是完全透明, 等布局完成之后, 再把透明度设置为1;
关闭悬浮窗的时候, 不要真的关闭悬浮窗, 可以把悬浮窗的位置设置为 -10000, 要显示悬浮窗的时候, 再把位置设置为0, 这样就不用频繁创建悬浮窗了
试试设置
秉承 所见即所得 的理念, 我们可以实时的看到属性修改后的效果;
修改文字颜色和背景色
修改文字大小和间距
修改文字滚动速度
滚动时手指调整文章位置, 做这个功能花的时间不少,
从动图中可以看到, 调整文章位置之后, 会在调整后的文章继续滚动;
修改不透明度
提词器涉及的知识点
- ui和悬浮窗的交互
- seekbar和textview的交互
- seekbar颜色的修改
- <list>和<grid>标签的使用
- 自定义组件color-choose
- BottomSheetDialog 的使用
- 控件的居中, 居左, 居右
- textview的滚动
- textview的触摸监听
- textview的文本镜像
- 脚本引擎之间传递参数
- animator的使用和监听以及释放资源
总结
知识点很多, 这都是次要的, 最主要的还是把各个知识点拼装起来, 组成一个产品,
这个组成的过程中的思考和实践, 才是最值得研究的
环境
雷电模拟器: 4.0.63
Android版本: 7.1.2
Autojs版本: 8.8.20
名人名言
思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程
声明
部分内容来自网络 本教程仅用于学习, 禁止用于其他用途