autojs自定义控件Switch

简介: 牙叔教程 简单易懂

牙叔教程 简单易懂


使用场景


自定义控件


效果展示



autojs版本


8.8.20-0


为什么自定义控件


为了UI界面漂亮


怎样自定义控件


autojs软件自带的示例 / 界面控件 / 自定义控件 , 这是简单的例子, 可以看看


商店里面也有一些自定义控件例子,


比如


自定义控件Switch(这是大柒写的, 跟我写的自定义不一样),


MagicIndicator(这是沐泠写的)


Shape3.0


ShimmerButton


自定义控件


等等


自定义控件思路


一般我们是为了修改控件的颜色, 形状, 布局, 以及运动效果,


对应的修改思路如下:


颜色: 修改控件背景, 前景, 其中使用频率最高的是view.setBackgroundDrawable


形状: 使用canvas画形状


布局: CustomView.prototype.render


运动效果: animation


自定义控件难点


主要是距离的计算


必须搞清楚 margin, padding, view.getMeasuredHeight();


getLeft(), getWidth(), getX(), getPaddingLeft(), rect, drawRoundRect


他们之间的关系;


尤其是涉及到了文字, 文字居中更难,必须了解 getFontMetricsInt()


本教程的自定义Switch可以定义的属性


文字颜色


文字大小


轨道宽高


轨道颜色


轨道圆角


进度条颜色


小球圆角


小球颜色


小球点击事件


代码讲解


1. 停止其他脚本, 主要方便测, 不然脚本运行的多了, 容易报错
engines.all().map((ScriptEngine) => {
  if (engines.myEngine().toString() !== ScriptEngine.toString()) {
    ScriptEngine.forceStop();
  }
});


2. 导入用到的类
importClass(android.graphics.PaintFlagsDrawFilter);
importClass(android.graphics.Color);
importClass(android.animation.ObjectAnimator);
importClass(android.animation.AnimatorListenerAdapter);
importClass(android.util.TypedValue);


3. UI界面
ui.layout(
  <vertical gravity="center">
    <text textSize="30sp" text="牙叔教程" textStyle="bold" w="*" gravity="center"></text>
    <custom-view
      id="customView"
      textColor="#5e35b1"
      trackColor="#0091ea"
      progressBarColor="#ffeb3b"
      ballColor="#ff8a65"
      w="200dp"
      h="80dp"
      textSize="30sp"
      trackRadius="60"
      ballRadius="60"
    ></custom-view>
    <custom-view
    ...
    ></custom-view>
    <custom-view
    ...
    ></custom-view>
  </vertical>
);


自定义控件主要代码


1. 所有单位统一转换为px
const displayMetrics = context.getResources().getDisplayMetrics();
const all_2Px = (value) => {
  if (value.indexOf("px") >= 0) {
    let result = value.replace("px", "");
    return parseInt(result);
  } else if (value.indexOf("dp") >= 0) {
    let result = parseFloat(value.replace("dp", ""));
    result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, result, displayMetrics);
    return parseInt(result);
  } else if (value.indexOf("in") >= 0) {
    let result = parseFloat(value.replace("in", ""));
    result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_IN, result, displayMetrics);
    return parseInt(result);
  } else if (value.indexOf("mm") >= 0) {
    let result = parseFloat(value.replace("mm", ""));
    result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_MM, result, displayMetrics);
    return parseInt(result);
  } else if (value.indexOf("pt") >= 0) {
    let result = parseFloat(value.replace("pt", ""));
    result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PT, result, displayMetrics);
    return parseInt(result);
  } else if (value.indexOf("sp") >= 0) {
    let result = parseFloat(value.replace("sp", ""));
    result = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, result, displayMetrics);
    return parseInt(result);
  } else {
    return parseInt(value);
  }
};


2. render
CustomView.prototype.render = function () {
  return (
    <LinearLayout margin="6 6 6 6" padding="2 2 2 2" h="60dp" w="300dp" gravity="center_vertical">
      <card id="ball" w="53dp" h="53dp" cardCornerRadius="25dp" cardElevation="3dp">
        <View layout_width="match_parent" layout_height="match_parent"></View>
      </card>
    </LinearLayout>
  );
};


3. 注册自定义控件
ui.registerWidget("custom-view", CustomView);


4. 定义各种属性
this.defineAttr("textColor", (view, attr, value, defineSetter) => {
  textColor = colors.parseColor(value);
});
this.defineAttr("w", (view, attr, value, defineSetter) => {
  view.attr("w", value);
});
this.defineAttr("h", (view, attr, value, defineSetter) => {
  view.attr("h", value);
});
this.defineAttr("trackRadius", (view, attr, value, defineSetter) => {
  trackRadius = all_2Px(value);
});
this.defineAttr("ballRadius", (view, attr, value, defineSetter) => {
  ballRadius = all_2Px(value);
});
this.defineAttr("textSize", (view, attr, value, defineSetter) => {
  textSize = all_2Px(value);
});
this.defineAttr("trackColor", (view, attr, value, defineSetter) => {
  trackColor = colors.parseColor(value);
});
this.defineAttr("progressBarColor", (view, attr, value, defineSetter) => {
  progressBarColor = colors.parseColor(value);
});
this.defineAttr("ballColor", (view, attr, value, defineSetter) => {
  ballColor = colors.parseColor(value);
  view.getChildAt(0).getChildAt(0).setBackgroundColor(ballColor);
});
​```


5. 定义点击事件对应的动画
view.ball.on("click", () => {
  log("click");
  moveBall(view.ball);
  view.widget.clickAction();
});


6. 定义动画监听
animator.addUpdateListener(
  new android.animation.ValueAnimator.AnimatorUpdateListener({
    onAnimationUpdate: function (valueAnimator) {
      drawProgressBar(ballView.getParent(), valueAnimator, ball);
    },
  })
);


声明

部分内容来自网络

本教程仅用于学习, 禁止用于其他用途



相关文章
|
测试技术 Android开发
autojs横屏截图的正确姿势
牙叔教程 简单易懂
3636 0
autojs普通版控制台美化
autojs普通版控制台美化
1380 0
|
开发框架 JavaScript 前端开发
百度富文本编辑器配置(vue3)
百度富文本编辑器配置(vue3)
|
Ubuntu Windows
Ubuntu截图快捷键
Ubuntu截图快捷键
4510 0
|
8月前
|
安全 数据安全/隐私保护
屏幕自动点击器, 手机自动点击器, 自动连点器屏幕【autojs】
完整UI界面:包含悬浮窗控制面板,支持拖动位置调整 核心功能:单点/连续点击、位置记录、任务执行与停止
|
9月前
|
Web App开发 安全 数据安全/隐私保护
利用Python+Requests实现抖音无水印视频下载
利用Python+Requests实现抖音无水印视频下载
|
8月前
|
安全 Android开发 数据安全/隐私保护
安卓手机屏幕连点器,屏幕自动点击器,手机自动点击器【autojs】
完整UI界面:包含坐标设置、间隔时间、随机偏移等参数配置区域
|
SQL Oracle 关系型数据库
迁移方案详解 | 使用YMP从异构数据库迁移到YashanDB
迁移方案详解 | 使用YMP从异构数据库迁移到YashanDB
|
存储 Java Android开发
Android系统 设置第三方应用为默认Launcher实现和原理分析
Android系统 设置第三方应用为默认Launcher实现和原理分析
2773 0
|
Kubernetes 中间件 数据安全/隐私保护
traefik配置用户登录,限制K8S的web服务访问
像Elastic-APM, Traefik-Dashboard等页面,是没有用户登录限制的,如果我们希望给他们加上用户登录限制,我们需要在traeifk里给对应的ingress添加登录用的Middleware,那么该如何添加呢?本文以给K8S部署的traefik dashboard为例进行添加
1118 0
traefik配置用户登录,限制K8S的web服务访问

热门文章

最新文章