Android 遍历界面所有的View

关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。

专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。

目录

一、导读

我们继续总结学习,温故知新。

二、概览

本文讲述如何遍历获取页面中所有的view,并输出对应的id,textview文本内容,imageview实际大小及设置的图片大小。

可用于检测android应用中的大图。

三、实践

不多说,直接上代码,

图片大小检测思路。

java 复制代码
    fun checkBitmapFromView(){
        //1、遍历activity中的各个View控件
        //2、获取View控件加载的Bitmap
        //3、对比Bitmap宽高与View宽高
    }

示例代码:

遍历获取所有的view,并输出相应的信息

java 复制代码
    List<View> viewList=new ArrayList<>();
    @Override
    protected void onResume() {
        super.onResume();
        logoIcon.postDelayed(new Runnable() {
            @Override
            public void run() {
                getAllViews((ViewGroup) getWindow().getDecorView());
                for (View view: viewList) {

                    if(view instanceof TextView) {
                        Log.d("xyz", view.toString());
                        Log.d("xyz", ((TextView)view).getText().toString());

                    } else if(view instanceof ImageView) {
                        Log.d("xyz", view.toString());
                        checkBitmap(view, ((ImageView)view).getDrawable());
                    } else {
                        Log.d("xyz", view.toString());
                    }
                }
            }
        }, 3000);
    }
java 复制代码
    //获取所有的子view,我们这里只保存imageview及textview,用于测试
    private List<View> getAllViews(ViewGroup viewGroup){
        for(int i=0;i< viewGroup.getChildCount(); i++){
            View view = viewGroup.getChildAt(i);
            if(view instanceof ViewGroup) {
                getAllViews((ViewGroup) view);
            } else {
                if(view instanceof ImageView || view instanceof TextView) {
                    viewList.add(view);
                }
                if(view.getVisibility() == View.VISIBLE) {
                }
            }
        }
        return viewList;
    }

ImageView大小检测

java 复制代码
    private void checkBitmap(Object thiz, Drawable drawable) {
        if (drawable instanceof BitmapDrawable && thiz instanceof View) {
            final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();

            final View view = (View) thiz;
            int width = view.getWidth();
            int height = view.getHeight();

            if (bitmap != null) {
                if (width > 0 && height > 0) {
                    // 图标宽高都大于view带下的2倍以上,则警告
                    if (bitmap.getWidth() >= (width << 1)
                            && bitmap.getHeight() >= (height << 1)) {
//                        warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("Bitmap size too large"));
                    }
                    warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("log"));
                } else {
                    final Throwable stackTrace = new RuntimeException();
                    view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
                        @Override
                        public boolean onPreDraw() {
                            int w = view.getWidth();
                            int h = view.getHeight();
                            if (w > 0 && h > 0) {
                                if (bitmap.getWidth() >= (w << 1)
                                        && bitmap.getHeight() >= (h << 1)) {
//                                    warn(bitmap.getWidth(), bitmap.getHeight(), w, h, stackTrace);
                                }
                                warn(bitmap.getWidth(), bitmap.getHeight(), w, h, stackTrace);
                                view.getViewTreeObserver().removeOnPreDrawListener(this);
                            }
                            return true;
                        }
                    });
                }
            } else {

                warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("bitmap null"));
            }
        }
    }

    private void warn(int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight, Throwable t) {
        String warnInfo = new StringBuilder("Bitmap info: ")
                .append("\n real size: (").append(bitmapWidth).append(',').append(bitmapHeight).append(')')
                .append("\n desired size: (").append(viewWidth).append(',').append(viewHeight).append(')')
                .append("\n call stack trace: \n").append(Log.getStackTraceString(t)).append('\n')
                .toString();

        Log.d("xyz", warnInfo);
    }

我们看下log输出

java 复制代码
com.xxx.xxx.xxx.ImageViewFor{e292c7e VFED..C.. ........ 540,1348-900,1528 #7f0a024e app:id/bt_phone}
2023-08-23 18:28:47.956 12556-12556 xyz                com.xxx.xxx                      D  Bitmap info: 
         real size: (144,144)
         desired size: (360,180)
         call stack trace: 
        java.lang.RuntimeException: log
            at com.xxx.xxx.ui.LoginActivity.checkBitmap(LoginActivity.java:235)
            at com.xxx.xxx.ui.LoginActivity.access$100(LoginActivity.java:79)
            at com.xxx.xxx.ui.LoginActivity$2.run(LoginActivity.java:193)
            at android.os.Handler.handleCallback(Handler.java:900)
            at android.os.Handler.dispatchMessage(Handler.java:103)
            at android.os.Looper.loop(Looper.java:219)
            at android.app.ActivityThread.main(ActivityThread.java:8673)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:513)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1109)

四、 推荐阅读

Java 专栏

SQL 专栏

数据结构与算法

Android学习专栏

相关推荐
boooooooom3 小时前
别再用错 ref/reactive!90%程序员踩过的响应式坑,一文根治
javascript·vue.js·面试
张元清3 小时前
Astro 6.0:被 Cloudflare 收购两个月后,这个"静态框架"要重新定义全栈了
前端·javascript·面试
青青家的小灰灰3 小时前
深入理解 async/await:现代异步编程的终极解决方案
前端·javascript·面试
Kapaseker5 小时前
一杯美式讲完 Sealed Class
android·kotlin
Baihai_IDP5 小时前
为什么 AI 巨头们放弃私有壁垒,争相拥抱 Agent Skills
人工智能·面试·llm
Moment5 小时前
Agent 开发本质上就是高级点的 CRUD
前端·后端·面试
哈里谢顿16 小时前
0305乒乓xx agent运维开发岗面试记录
面试
哈里谢顿16 小时前
0309面试二总结
面试
哈里谢顿16 小时前
0309面试一记录
面试
哈里谢顿16 小时前
0310面试二记录
面试