autojs多级列表

牙叔教程 简单易懂

效果预览

思路

列表使用一个recyclerview, 所谓的多级用深度来表示,

深度用padding来控制.


为什么不使用多个recyclerview, 因为水太深, 一般人把握不住


以上思路来自 假nodejs用户群群主


UI代码

ui.layout(
    
        
    
);


创建嵌套列表数据

代码

let data = [];
for (let i = 0; i < 10; i++) {
    let item = { id: i, text: "item" + i, children: [] };
    for (let j = 0; j < 10; j++) {
        let sub = { id: j, text: "sub" + j, children: [] };
        for (let k = 0; k < 10; k++) {
            let sub2 = { id: k, text: "sub2" + k, children: [] };
            for (let l = 0; l < 10; l++) {
                let sub3 = { id: l, text: "sub3" + l, children: [] };
                sub2.children.push(sub3);
            }
            sub.children.push(sub2);
        }
        item.children.push(sub);
    }
    data.push(item);
}


数据格式

[
    {
        id: 0,
        text: "item0",
        children: [
            {
                id: 0,
                text: "sub0",
                children: [
                    {
                        id: 0,
                        text: "sub20",
                        children: [
                            { id: 0, text: "sub30", children: [] },
                            { id: 1, text: "sub31", children: [] },
                            { id: 2, text: "sub32", children: [] },
                            { id: 3, text: "sub33", children: [] },
                            { id: 4, text: "sub34", children: [] },
                            { id: 5, text: "sub35", children: [] },
                            { id: 6, text: "sub36", children: [] },
                            { id: 7, text: "sub37", children: [] },
                            { id: 8, text: "sub38", children: [] },
                            { id: 9, text: "sub39", children: [] },
                        ],
                    },


编写adapter

最简单的apapter是这样的

function createRecyclerViewAdapter(items) {
    let itemLayout = ;
    return RecyclerView.Adapter({
        onCreateViewHolder: function (parent, viewType) {
            log("onCreateViewHolder");
            // 视图创建
            let view;
            let holder;
            view = ui.inflate(itemLayout, parent, false);
            holder = JavaAdapter(RecyclerView.ViewHolder, {}, view);
            return holder;
        },
        onBindViewHolder: function (holder, position) {
            log("onBindViewHolder");
            // 数据绑定
            let view = holder.itemView;
            view.attr("bg", "#32d9c5");
            view.setText("123");
        },
        getItemCount: function () {
            return items.length;
        },
    });
}


我们在这个基础上修改成多级列表的adapter


多级列表分析

  • 左侧有一个箭头向右, 点击之后向下
  • 没有箭头的就用 点符号 · 代替
  • 子控件padding, 一层一层逐渐变深
  • 控件类型, 判断依据是数据, 是否有 children


所需图片

ui.layout(
    
        
        
        
    
);


思路

一开始我们给用户展示的, 肯定是没有展开的数据, 因此数据是有状态的,原始数据放一边,

我们用新的数组来和recyclerviewadapter合作


给数据加上状态判断: expand(展开)

let items = [];
var len = data.length;
for (var i = 0; i < len; i++) {
    let item = data[i];
    item.expand = false;
    items.push(item);
}


视图创建

简单的文字图片

onCreateViewHolder: function (parent, viewType) {
    log("onCreateViewHolder");
    // 视图创建
    let view;
    let holder;
    let itemLayout;
    itemLayout = (
        
            
            
        
    );
    view = ui.inflate(itemLayout, parent, false);
    holder = JavaAdapter(RecyclerView.ViewHolder, {}, view);
    return holder;
},

绑定数据

onBindViewHolder: function (holder, position) {
    let view = holder.itemView;
    let item = items[position];
    let depth = item.depth;
    let padding = paddingBase * depth;
    view.setPadding(padding, 0, 0, 0);
    view.content.setText(item.text);
},


来看看现在的效果


添加图片

文字左侧放图片, 如果有子控件就放圆圈图片, 没有子控件, 就放箭头图片

onBindViewHolder: function (holder, position) {
    let view = holder.itemView;
    let item = items[position];
    let depth = item.depth;
    let padding = paddingBase * depth;
    view.setPadding(padding, 0, 0, 0);
    if (item.children && item.children.length > 0) {
        view.state.attr("src", "@drawable/ic_keyboard_arrow_right_black_48dp");
    } else {
        view.state.attr("src", "@drawable/ic_adjust_black_48dp");
    }
    view.content.setText(item.text);
},


添加点击事件

当用户点击条目的时候, 我们要判断该条目能不能展开或者折叠,

我们先讨论展开

当用户点击的时候, 判断条目的 expand 状态, 如果是false, 说明还没有展开, 如果是true, 说明展开了;


条目一共有三种类型:

  • 没有子控件
  • 未展开的控件
  • 展开的控件


点击事件触发展开子控件效果

if (!item.expand) {
    // 点击后, 展开子控件
    item.expand = true;
    view.state.attr("src", "@drawable/ic_keyboard_arrow_down_black_48dp");
    let children = item.children;
    let len = children.length;
    for (let i = 0; i < len; i++) {
        let child = children[i];
        child.depth = item.depth + 1;
        items.splice(position + i + 1, 0, child);
    }
    recycleAdapter.notifyItemRangeInserted(position + 1, len);
}

展开子控件的效果


点击后折叠

当用户点击已经展开的子控件时, 就应该折叠子控件了;

用户不是依次折叠, 而是可能点击了任何一层;


同时, 还要考虑, 子控件的状态是折叠了, 还是展开了;

折叠的子控件数据, 全部删除

let count = countChild(item);
log("count: " + count);
items.splice(position + 1, count);
view.state.attr("src", "@drawable/ic_keyboard_arrow_right_black_48dp");
item.expand = false;
recycleAdapter.notifyItemRangeRemoved(position + 1, count);


展开以及折叠效果


控件着色

每条数据应该有自己的颜色, 以便肉眼可以分隔每条数据, 颜色是一个渐变色, 通过色轮的角度来控制颜色

hsl[0] = hsl[0] + angleStep;
if (hsl[0] > 360) {
    hsl[0] = hsl[0] - 360;
}
view.attr("bg", colors.toString(ColorUtils.HSLToColor(hsl)));


总结

以上就是用一个recyclerview模拟多级列表的方法, 中心思想是把多级列表的数组躺平, 变成一维数组, 这样才可以使用recyclerview;

其中的关键点是理解, 从哪个位置到那个位置的数据应该删除(或增加)


环境


设备: 小米11pro
Android版本: 12
Autojs版本: 9.2.13


名人名言


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


声明


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

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章