• Android 遍历界面所有的View


    关于作者:CSDN内容合伙人、技术专家, 从零开始做日活千万级APP。
    专注于分享各领域原创系列文章 ,擅长java后端、移动开发、商业变现、人工智能等,希望大家多多支持。

    在这里插入图片描述

    一、导读

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

    二、概览

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

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

    三、实践

    在Android开发中,有时我们需要遍历界面上的所有View,以便进行某些操作。例如,我们可能需要查找特定类型的View,或者对所有的View进行某种操作。这里是一个简单的示例,展示如何遍历界面上的所有View。
    首先,假设你有一个Activity或Fragment,里面有一个布局文件,里面包含各种各样的View,例如Button、TextView、ImageView等。

    然后,你可以在Activity或Fragment的代码中,通过递归的方式遍历所有的View。

    不多说,直接上代码,

    图片大小检测思路。

        fun checkBitmapFromView(){
            //1、遍历activity中的各个View控件
            //2、获取View控件加载的Bitmap
            //3、对比Bitmap宽高与View宽高
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例代码:
    遍历获取所有的view,并输出相应的信息

    
        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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    
        //获取所有的子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;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    这个示例代码会遍历界面上的所有View,并将image view和textview加入到list中。注意,这里使用了递归方法来遍历ViewGroup中的所有子View。如果View是一个ViewGroup(例如RelativeLayout、LinearLayout等),那么我们就递归遍历它的所有子View。如果View是一个叶子视图(例如Button、TextView等),那么我们就执行想要的操作。

    当我们获取到页面上的imageview后,就可以做一些操作,如
    ImageView大小检测

    
        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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    我们看下log输出

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    四、 推荐阅读

    Java 专栏

    SQL 专栏

    数据结构与算法

    Android学习专栏

    ddd

  • 相关阅读:
    在家中访问一个网站的思考
    python列表list的index方法的用法和实例
    VA05/VF05不好用,加N试试
    3个密码学相关的问题
    Python 元类详解
    运行jupyter lab时遇到代码变蓝并且无法运行的问题
    Python教程:with语句的用法
    52、图论-腐烂的橘子
    多项分布模拟及 Seaborn 可视化教程
    JavaScript从入门到精通|函数表达式
  • 原文地址:https://blog.csdn.net/fumeidonga/article/details/133070036