Android从零单排之获取ImageView的宽高为0?

本文探讨了在Android开发中,如何在onCreate方法后获取ImageView的实际尺寸,并提供了多种解决方案,包括使用BitmapFactory、MeasureSpec.makeMeasureSpec、ViewTreeObserver.addOnPreDrawListener和addOnGlobalLayoutListener方法。

问题描述

    说起来我也够菜的!⊙﹏⊙b汗

    今天搞了一个关于图片的demo,想动态的改变一张图片的大小和margin值。但是在activity中获取imageview的宽度和高度的时候,总是0。哎,我tm就是搞不懂了,怎么能是0呢?

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <span style="white-space:pre">    </span>imageView1 = (ImageView) findViewById(R.id.id_img1);  
  2.     int width = imageView1.getWidth();  
  3.     int height = imageView1.getHeight();  

分析原因

    起初怀疑是我代码写的有问题,可能写错了,可是反复检查和实验了几次,还TM是0。蛋疼!后来上网一查,发现了新大陆了。

    在onCreate方法中,控件其实还没有画好,也就是说当onCreate方法执行完了之后,才开始绘制控件,所以在onCreate方法中获取width和height返回的值是0。但是我又想onResume方法是不是可以呢?后来发现还是不行!我自定义了ImageView,然后打印量log日志,发现果然是这样,onCreate和onResume方法执行完了之后,才开始执行控件的测量(onMeasure)和绘制(onDraw)方法。

    MyImageView.java---自定义ImageView类:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class MyImageView extends ImageView {  
  2.   
  3.     public MyImageView(Context context) {  
  4.         super(context);  
  5.     }  
  6.   
  7.     public MyImageView(Context context, AttributeSet attrs) {  
  8.         super(context, attrs);  
  9.     }  
  10.   
  11.     @Override  
  12.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  13.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  14.         Log.i("imageview""onMeasure...");  
  15.     }  
  16.   
  17.     @Override  
  18.     protected void onDraw(Canvas canvas) {  
  19.         super.onDraw(canvas);  
  20.         Log.i("imageview""onDraw...");  
  21.     }  
  22. }  
    activity类:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. @Override  
  2. protected void onCreate(Bundle savedInstanceState) {  
  3.     super.onCreate(savedInstanceState);  
  4.     setContentView(R.layout.activity_demo3);  
  5.     Log.i("imageview""onCreate.....");  
  6. }  
  7.   
  8. @Override  
  9. protected void onResume() {  
  10.     super.onResume();  
  11.     Log.i("imageview""onResume.....");  
  12. }  
    打印出来的LOG日志如下:



解决办法

    既然onCreate方法中不行,应该有其他的方法了!于是从网上找到了如下几种方法!

    第一种方法:使用BitmapFactory。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.songjiang);  
  2.         Log.i("imageview""width: " + bitmap.getWidth());  
  3.         Log.i("imageview""height: " + bitmap.getHeight());  

第二种方法: 使用MeasureSpec.makeMeasureSpec方法。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. int w = View.MeasureSpec.makeMeasureSpec(0,  
  2.                 View.MeasureSpec.UNSPECIFIED);  
  3.         int h = View.MeasureSpec.makeMeasureSpec(0,  
  4.                 View.MeasureSpec.UNSPECIFIED);  
  5.         img.measure(w, h);  
  6.         Log.i("imageview2""width: " + img.getMeasuredWidth());  
  7.         Log.i("imageview2""height: " + img.getMeasuredHeight());  
第三种方法:使用ViewTreeObserver.addOnPreDrawListener方法。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ViewTreeObserver vto = img.getViewTreeObserver();  
  2.         vto.addOnPreDrawListener(new OnPreDrawListener() {  
  3.             @Override  
  4.             public boolean onPreDraw() {  
  5.                 int height = img.getMeasuredHeight();  
  6.                 int width = img.getMeasuredWidth();  
  7.                 Log.i("imageview3""width: " + width);  
  8.                 Log.i("imageview3""height: " + height);  
  9.                 return true;  
  10.             }  
  11.         });  

第四种方法:使用ViewTreeObserver.addOnGlobalLayoutListener方法。

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. ViewTreeObserver vto = img.getViewTreeObserver();  
  2.         vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {  
  3.             @Override  
  4.             public void onGlobalLayout() {  
  5.                 img.getViewTreeObserver().removeGlobalOnLayoutListener(this);  
  6.                 Log.i("imageview4""width: " + img.getWidth());  
  7.                 Log.i("imageview4""height: " + img.getHeight());  
  8.             }  
  9.         });  

    注意:方法三会调用3次。


    在代码中动态改变ImageView的宽高就很简单了!

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. DisplayMetrics metrics = new DisplayMetrics();  
  2.         getWindowManager().getDefaultDisplay().getMetrics(metrics);  
  3.         int desityDpi = metrics.densityDpi;  
  4.         Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.hi);  
  5.         int width = bitmap.getWidth() * 160 / desityDpi;  
  6.         int height = bitmap.getHeight() * 160 / desityDpi;  
  7.         LayoutParams params = imageView1.getLayoutParams();  
  8.         params.width = width;  
  9.         params.height = height;  
  10.         imageView1.setLayoutParams(params);  
【直流微电网】径向直流微电网的状态空间建模与线性化:一种耦合DC-DC变换器状态空间平均模型的方法 (Matlab代码实现)内容概要:本文介绍了径向直流微电网的状态空间建模与线性化方法,重点提出了一种基于耦合DC-DC变换器状态空间平均模型的建模策略。该方法通过对系统中多个相互耦合的DC-DC变换器进行统一建模,构建出整个微电网的集中状态空间模型,并在此基础上实施线性化处理,便于后续的小信号分析与稳定性研究。文中详细阐述了建模过程中的关键步骤,包括电路拓扑分析、状态变量选取、平均化处理以及雅可比矩阵的推导,最终通过Matlab代码实现模型仿真验证,展示了该方法在动态响应分析和控制器设计中的有效性。; 适合人群:具备电力电子、自动控制理论基础,熟悉Matlab/Simulink仿真工具,从事微电网、新能源系统建模与控制研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握直流微电网中多变换器系统的统一建模方法;②理解状态空间平均法在非线性电力电子系统中的应用;③实现系统线性化并用于稳定性分析与控制器设计;④通过Matlab代码复现和扩展模型,服务于科研仿真与教学实践。; 阅读建议:建议读者结合Matlab代码逐步理解建模流程,重点关注状态变量的选择与平均化处理的数学推导,同时可尝试修改系统参数或拓扑结构以加深对模型通用性和适应性的理解。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值