autojs修改下拉框高度

牙叔教程 简单易懂


基础下拉框

let arr = [];
for (var i = 0; i < 100; i++) {
    arr.push("选项: " + i);
}
let entries = arr.join("|");
ui.layout(
    
        
        
        
    
);

选项12下面还有几十个选项


我自己的原则是能用就行, 但是有的人就觉得这个下拉框太长了, 看着不爽, 想把它弄得短一点,

那么应该怎么做?


首先查一下网上的例子, 基本上是这样的

let arr = [];
for (var i = 0; i < 100; i++) {
    arr.push("选项: " + i);
}
let entries = arr.join("|");

ui.layout(
    
        
    
);
let sp = ui.mySpinner;
let clazz = java.lang.Class.forName("android.widget.Spinner");
let popup = clazz.getDeclaredField("mPopup");
popup.setAccessible(true);
let popupWindow = popup.get(sp);
popupWindow.setHeight(100);

反射获取mPopup字段, 然后获取下拉框 字段名叫mPopup的实例, 再设置他的高度,

你试一下就知道了, 在autojs是不生效的


spinner的下拉框有两种模式, 一种是弹框, 一种是下拉框, 可以通过修改mode来切换

spinnerMode="dropdown"
spinnerMode="dialog"


上面反射修改的就是在 dropdown模式下的下拉框的高度,

dialog模式是没有这个setHeight方法的, 因为会报错


模式在spinner的源码中有说

public Spinner(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes, int mode,
        Theme popupTheme) {
    ...
    switch (mode) {
        case MODE_DIALOG: {
            mPopup = new DialogPopup();
            mPopup.setPromptText(a.getString(R.styleable.Spinner_prompt));
            break;
        }

        case MODE_DROPDOWN: {
            final DropdownPopup popup = new DropdownPopup(
                    mPopupContext, attrs, defStyleAttr, defStyleRes);

上面的mPopup就是这个代码里的popup, 也就是那个 new DropdownPopup


那么为什么autojs不能用, 而网上大部分都是这个解决方案呢?

autojs和安卓有啥不一样? 不都是安卓吗?


仔细想想, 还是有不一样的地方,

我们打印一下spinner

com.stardust.autojs.core.ui.widget.JsSpinner{f96a032 VFED..CL. ......I. 0,0-0,0 #1c9} 

autojs的spinner是对安卓的spinner的再封装,


popupWindow 也打印一下

let popupWindow = popup.get(sp);
log(popupWindow);
// android.widget.Spinner$DropdownPopup@3ccd85e


这个没问题, 毕竟封装就是继承了Spinner, spinner的继承顺序是:

com.stardust.autojs.core.ui.widget.JsSpinner extends androidx.appcompat.widget.AppCompatSpinner


然后

androidx.appcompat.widget.AppCompatSpinnerextends android.widget.spinner


那么这个私有字段 mPopup 是属于谁的呢?

属于 androidx.appcompat.widget.AppCompatSpinner


我们来验证一下, 这个继承, 如果父子类有同名字段的话, 到底使用谁的值

首先定义一个父类

public class Father {
    private String name = "father";
}

再定义一个子类

public class Son extends Father {
    private String name = "son";
    public void who(){
        System.out.println("I am "+name);
    }
}

然后创建son实例, 再调用实例的who方法

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello world!");
        Son son=new Son();
        son.who();
    }
}


控制台打印的是 I am son


如果子类没有name字段

public class Son extends Father {
    public void who(){
        System.out.println("I am "+name);
    }
}

因为父类的name字段也是private, 所以子类也访问不到, 改成public, 子类此时访问的name字段的值, 就是父类的值


我们来试试修改父类 androidx.appcompat.widget.AppCompatSpinner的mPopup的值, 看看高度能不能改变

"ui";
let arr = [];
for (var i = 0; i < 100; i++) {
    arr.push("选项: " + i);
}
let entries = arr.join("|");
ui.layout(
    
        
    
);
ui.post(function () {
    let sp = ui.mySpinner;
    var dcl = context.getClassLoader();
    var clazz = dcl.loadClass("androidx.appcompat.widget.AppCompatSpinner");
    let popup = clazz.getDeclaredField("mPopup");
    popup.setAccessible(true);
    let popupWindow = popup.get(sp);
    popupWindow.setHeight(300);
}, 300);

一模一样的代码, 除了把15行的类名换成 androidx.appcompat.widget.AppCompatSpinner

这次修改高度就成功了.


这个修改下拉框高度的问题就解决了, 这个解决方案告诉我们, 在把网上的安卓代码改成autojs的时候, 注意autojs是把安卓封装了一层的, 记住这个知识点以后, 就可以避免以后掉进一些坑


环境

雷电模拟器:9.0.17
Android版本: 9
Autojs版本: 9.2.10


名人名言

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


声明

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

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

相关文章

推荐文章