动态的获取和设置控件的长和宽

      

 源码下载:http://download.csdn.net/detail/forwardyzk/7271971

  转载请注明原文地址:http://blog.csdn.net/forwardyzk/article/details/24730733

一般情况下,我们都是在文件中设置好长和宽,使用match_parent,warp_content,fill_parent和设置固定的长和宽,倘若有这样的一种情况,使用代码设置控件的长和宽,那么这样就会根据动态获取控件的大小,按比例的设置其他控件的常何况,这样也可以达到屏幕适配的效果。

      这只是一种情况,还有其他的情况用到动态的获取或者设置控件的长和宽。

 

 获取控件的长和宽

 

 

     我们一般情况下,会在onCreate()中用到这种办法获取控件的长和宽。

        int w=findViewById(R.id.ll).getWidth(); 我们发现这样获得的宽度是0,原因是:在onCreate()方法获得的控件对象还没有开始测量,所以获得的宽度是0,当执行了onMeasure()方法,才可以获得真正的宽,然后执行onDraw()方法,展示出来。

       main.xml

        

<LinearLayout
        android:id="@+id/ll"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/tv_01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ff0000"
            android:text="this is 01" />

        <TextView
            android:id="@+id/tv_02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="#ff00ff"
            android:text="this is 02" />
    </LinearLayout>

 

 

 

      那么怎样在onCreate()方法中获得长和宽呢。有以下三种方法:

   方法1:

    

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ll = (LinearLayout)findViewById(R.id.ll);
		tv_01 = (TextView)findViewById(R.id.tv_01);
		tv_02 = (TextView)findViewById(R.id.tv_02);
		
		int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
		int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
		ll.measure(w, h);
		int width = ll.getMeasuredWidth();
		int height = ll.getMeasuredHeight();
		Log.i(TAG, "方法1:"+String.valueOf(width)+":"+height);
	}

 

介绍:

    在main.xml中,LinearLayout是填充的父窗体,但是使用此方法获取的宽度却不是屏幕的宽度。而是两个TextView实际长度的和。Log.i(TAG, "屏幕的宽度:"+getWindowManager().getDefaultDisplay().getWidth());

 

方法2:

     

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ll = (LinearLayout)findViewById(R.id.ll);
		tv_01 = (TextView)findViewById(R.id.tv_01);
		tv_02 = (TextView)findViewById(R.id.tv_02);
		
		ViewTreeObserver vto = ll.getViewTreeObserver(); 
		vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
		    public boolean onPreDraw() { 
		        int height = ll.getMeasuredHeight(); 
		        int width = ll.getMeasuredWidth(); 
		        Log.i(TAG, "方法2:"+String.valueOf(width)+":"+height);
		        //w = width;
		        //setWidth_01(ll.getMeasuredWidth());
		        return true; 
		    } 
		}); 
		Log.i(TAG, "屏幕的宽度:"+getWindowManager().getDefaultDisplay().getWidth());
	}

介绍:

 

  使用此方法获得的宽度是设置的长度

  如果你设置的是填充父窗体,那么获得的宽度是屏幕的宽度

  如果你设置的是一个具体的宽度(200),那么获得的宽度是设置的那个值(200)

 

方法3:

   

@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);
		ll = (LinearLayout)findViewById(R.id.ll);
		tv_01 = (TextView)findViewById(R.id.tv_01);
		tv_02 = (TextView)findViewById(R.id.tv_02);
		
		ViewTreeObserver vto2 = ll.getViewTreeObserver();   
		vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
		    @Override   
		    public void onGlobalLayout() { 
		        ll.getViewTreeObserver().removeGlobalOnLayoutListener(this);   
		        Log.i(TAG, "方法3:"+String.valueOf(ll.getWidth())+":"+ll.getHeight());
		    }   
		});   
		Log.i(TAG, "屏幕的宽度:"+getWindowManager().getDefaultDisplay().getWidth());
	}


介绍:

 

  此方法和方法二获得的值是一样的。

 

动态的设置控件的长和宽

   方法1:

       

/**
	 * 第一种方法:动态的设置View的宽和高
	 */
	public void setWidth_01(int w) {
		LinearLayout.LayoutParams llp = new LayoutParams(w, 50);
		tv_01.setLayoutParams(llp);
	}


方法2:

 

     

/**
	 * 第二种方法:动态的设置View的宽和高
	 */
	public void setWidth_02(int w) {
		// 第二种设置控件的宽度
		LinearLayout.LayoutParams llp = null;
		llp = (LayoutParams)tv_02.getLayoutParams();
		llp.width = w;
		tv_02.setLayoutParams(llp);
		
	}

 

 

 

这两种方法动态的设置控件的长和宽效果是一样的。

 

注意点:
   1.如果是使用第一种方法获得的宽度,然后动态的设置长和宽,此时的长和宽是控件中实际内容所占的常何况
   2.如果使用第二种方法获得长和宽
      直接设置的话,那么会出现死循环,虽然效果出来了,可以通过查看打印的log就明白是死循环。

    

public void getWidth_02() {
		ViewTreeObserver vto = ll.getViewTreeObserver(); 
		vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
		    public boolean onPreDraw() { 
		        int height = ll.getMeasuredHeight(); 
		        int width = ll.getMeasuredWidth(); 
		        Log.i(TAG, "方法2:"+String.valueOf(width)+":"+height);
		        setWidth_01(ll.getMeasuredWidth());
		        return true; 
		    } 
		}); 
	}

 

 

 

如果是把获得的长和宽设置为成员变量,那么在设置的话,获取的长和宽是0

 

 

 public void getWidth_02() {
		ViewTreeObserver vto = ll.getViewTreeObserver(); 
		vto.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() { 
		    public boolean onPreDraw() { 
		        int height = ll.getMeasuredHeight(); 
		        int width = ll.getMeasuredWidth(); 
		        Log.i(TAG, "方法2:"+String.valueOf(width)+":"+height);
		        w=width;
		        return true; 
		    } 
		}); 
		setWidth_01(w);
	}


    3.如果是第三种方法获取长和宽,是没有异常状况的。

 

 

 

     

public void getWidth_03() {
		ViewTreeObserver vto2 = ll.getViewTreeObserver();   
		vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() { 
		    @Override   
		    public void onGlobalLayout() { 
		        ll.getViewTreeObserver().removeGlobalOnLayoutListener(this);   
		        Log.i(TAG, "方法3:"+String.valueOf(ll.getWidth())+":"+ll.getHeight());
		        setWidth_01(ll.getWidth());
		    }   
		});   
	}

也可以把长和宽提取为成员变量,然后给其他控件设置长和宽也可以。

 

 

综上所述:
    如果只是获得长和宽,那么获取长和宽的方法1和方法2都可以,根据需要选取。
    如果即获取还要设置,那么推荐使用方法3

 

 

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值