autojs模仿某东分类导航栏

191 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第3天,点击查看活动详情 >>

牙叔教程 简单易懂

某东的导航栏效果

\

实现思路

一个可以滚动的容器里面, 装一些子控件, 点击后, 移动令其居中, 且文字加粗

UI元素

  • horizontal 横向滚动控件
  • text 文字控件
  • View 底部的红色动画

数据

一个普通的字符串数组

let categories = [
    "推荐",
    "运动",
    "电脑办公",
    "个护清洁",
    "酒水饮料",
    "家居生活",
    "日用百货",
    "美妆护肤",
    "母婴玩具",
    "食品",
    "厨具",
    "家电",
    "数码",
    "母婴童装",
    "男装",
    "美妆",
    "女装",
    "图书",
    "数码",
    "男鞋",
    "宠物",
    "工业品",
    "奢侈品",
    "生活旅行",
];

界面

"ui";
ui.layout(
    <vertical>
        <horizontal id="container"></horizontal>
    </vertical>
);

我又考虑了一下, 这里是不是应该用recyclerview

来试一下rv

ui.layout(
    <vertical>
        <androidx.recyclerview.widget.RecyclerView id="rv"></androidx.recyclerview.widget.RecyclerView>;
    </vertical>
);

\

设置布局管理器 并且绑定数据

let rv = ui.rv;
let layoutManager = new LinearLayoutManager(context);
layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL); // 设置 recyclerview 布局方式为横向布局
rv.setLayoutManager(layoutManager);
let recycleAdapter = createRecyclerViewAdapter(categories);
rv.setAdapter(recycleAdapter);

\

可以正常滚动

\

为什么间距不一样?

间距不一样的recyclerview条目布局代码

    let itemLayout = (
        <frame w="wrap_content" margin="8" h="80dp" bg="#b1d5c8">
            <text id="name" textSize="24sp" margin="0" padding="0" textColor="#5e128a" gravity="center"></text>
        </frame>
    );

只有父控件是 w="wrap_content", 我们给子控件也加上, 这个间距问题就解决了

    let itemLayout = (
        <frame w="wrap_content" margin="8" h="80dp" bg="#b1d5c8">
            <text id="name" w="wrap_content" textSize="24sp" margin="0" padding="0" textColor="#5e128a" gravity="center"></text>
        </frame>
    );

\

添加点击事件, 点击后文字居中

除了头尾的文字不居中, 中间的大部分文字都要居中

我们是先点击子控件, 然后把子控件居中, 那么既然响应了点击事件, 那么子控件一定是可见的;

首先我们判断他在中间的左侧, 还是右侧,

然后往左移动或者往右移动一段距离,使其居中,

首先以右侧为例, 我们一开始就点击右侧的文字,

那么应该向左移动的距离怎么计算?

如下图, 我们把右侧的D控件, 移动到中间, 这段距离怎么计算?

\

首先, D可见, 不代表D显示完全, 他可能只显示了一半, 或者一少半,

但是如果要居中, 我们必须知道D的宽度,

D在居中的时候, left的值 = (recycerview的宽度/2) - (D宽度/2)

要移动的距离 = D在右侧的left值 - D居中的left值

那么我们需要知道的几个数值是:

  1. D的宽度 view.getMeasuredWidth();
  2. rv的宽度 rv.getWidth()
  3. 右侧D的left view.getLeft()

我们来执行以下上面的方法, 看能不能获取正确的数值

let left = view.getLeft();
log("left = " + left); // left = 1260
let width = view.getWidth();
log("width = " + width); // width = 336
log("view.width = " + view.width); // view.width = 336
let measuredWidth = view.getMeasuredWidth();
log("measuredWidth = " + measuredWidth); // measuredWidth = 336
log("ui.rv.width = " + ui.rv.width); // ui.rv.width = 1440

经过测试, 宽度获取是正确的

接下来计算距离, 接着移动

let centerViewLeft = (ui.rv.width - view.width) / 2;
log("centerViewLeft = " + centerViewLeft);
let moveDistance = view.getLeft() - centerViewLeft;
log("moveDistance = " + moveDistance);
rv.smoothScrollBy(moveDistance, 0);

实现了居中

\

\

上面实现了点击右侧控件居中, 同理实现左侧居中

\

判断在左侧还是右侧

通过判断控件的中心点, 在rv中心点的左侧还是右侧

let isLeft = view.getLeft() + view.width / 2 <= rv.width / 2 ? true : false;

这个isLeft命名怎么样? 有没有更好的名字?

滚动居中实现了, 动画有时间再加

环境

手机:小米11pro
MIUI: 13.0.12
Android版本: 12
Autojs版本: 9.2.6

名人名言

思路是最重要的, 其他的百度, bing, stackoverflow, github, 安卓文档, autojs文档, 最后才是群里问问 --- 牙叔教程\

声明

部分内容来自网络 本教程仅用于学习, 禁止用于其他用途\

微信公众号 牙叔教程