View.getWidth() not work in onCreate method?
Asked Answered
E

4

6

Why lColorWheel.getWith() method returns 0? I guess that it have something to do with onMeasure event, but i really cant understand from documentation how it works. Where I have to set dimensions for mDrawable?

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_light);

    ShapeDrawable mDrawable;
    ivColorWheel=(ImageView)findViewById(R.id.ivColorWheel);
    lColorWheel=findViewById(R.id.lColorWheel);
    ld=(LayerDrawable)getResources().getDrawable(R.drawable.colorwheel);  

    mDrawable = new ShapeDrawable(new OvalShape());

    mDrawable.setIntrinsicWidth(lColorWheel.getWidth());
    mDrawable.setIntrinsicHeight(lColorWheel.getHeight());
    Log.d("lColorWheel.getWidth()",Integer.toString(lColorWheel.getWidth())); //returns 0, why?
    Log.d("lColorWheel.getHeight()",Integer.toString(lColorWheel.getHeight())); //returns 0, why ?

and appropiate XML file:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
android:gravity="center_horizontal"
android:addStatesFromChildren="true" >

<RelativeLayout
    android:id="@+id/lColorWheel"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:layout_marginTop="20dp" 
    android:layout_centerHorizontal="true" 
    android:adjustViewBounds="true">

     <ImageView
        android:id="@+id/ivColorWheel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:adjustViewBounds="true"
        android:paddingBottom="0dp"
        android:paddingTop="0dp"
        android:src="@drawable/iconwheel"
        />

      <ImageView
          android:id="@+id/ivCenterButton1"
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:layout_centerHorizontal="true"
          android:layout_centerVertical="true"
          android:maxHeight="5dp"
          android:maxWidth="5dp"
          android:onClick="clc"
          android:paddingBottom="0dp"
          android:paddingLeft="0dp"
          android:paddingRight="0dp"
          android:paddingTop="0dp"
          android:src="@drawable/center3" />

</RelativeLayout>

<SeekBar
     android:id="@+id/sbColorIntensity"
     android:layout_width="match_parent"
     android:layout_height="50dp"
     android:layout_alignParentLeft="true"
      android:layout_below="@id/lColorWheel"
     android:layout_marginLeft="20dp"
     android:layout_marginRight="20dp"
     android:layout_marginTop="20dp"
     android:background="@drawable/colorintensitystrip"
     android:max="255"
     android:maxHeight="-25dp"
     android:thumb="@drawable/thumb"
     android:thumbOffset="0dp"
 />



<SeekBar
    android:id="@+id/sbOrientation"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_below="@id/sbColorIntensity"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:layout_marginTop="20dp"
    android:background="@drawable/orientationstrip"
    android:max="255"
    android:maxHeight="-25dp"
    android:thumb="@drawable/thumb"
    android:thumbOffset="0dp"
     />

<SeekBar
    android:id="@+id/sbWhiteIntensity"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_alignParentLeft="true"
    android:layout_below="@id/sbOrientation"
    android:layout_marginLeft="20dp"
    android:layout_marginRight="20dp"
    android:layout_marginTop="20dp"
    android:background="@drawable/whiteintensitystrip"
    android:max="255"
    android:maxHeight="-25dp"
    android:thumb="@drawable/thumb"
    android:thumbOffset="0dp"
     />
 </RelativeLayout>

thx

Estey answered 11/6, 2013 at 10:17 Comment(0)
O
16

You need to measure view's height and width if you want to use them before rendering finishes.

Following code will help you to measure height and width of any view.

imgView.measure(
    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
imgView.layout(0, 0,
    imgView.getMeasuredWidth(),
    imgView.getMeasuredHeight());

Write this code before use of height and width of view.

Sometimes this approach will not give proper result. There is alternative of it. Below code will calculate height and width before draw on screen.

ViewTreeObserver viewTree = imgView.getViewTreeObserver();
viewTree.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
    public boolean onPreDraw() {
        finalHeight = imgView.getMeasuredHeight();
        finalWidth = imgView.getMeasuredWidth();
        //print or do some code
        return true;
    }
});
Overspread answered 11/6, 2013 at 10:25 Comment(1)
I always get 0,0 when I use the measure approach. why? and how can imgView knows the dimension it wants to be ?Fulvous
S
1

You call getwidth() too early, the UI is not ready to get this value. You need an Observer. I think this value is set just after the first paint of the UI. Try this in your onCreate() method:

    final ViewTreeObserver vto = myView.getViewTreeObserver();
    if (vto.isAlive()) {
       vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

           public void onGlobalLayout() {

              int witdth = lColorWheel.getWith() 
              // remove the listener... or we'll be doing this a lot.
                ViewTreeObserver obs = promotionSub_ly.getViewTreeObserver();
                obs.removeGlobalOnLayoutListener(this);
          }
      });
   }
Spirituel answered 11/6, 2013 at 10:26 Comment(0)
A
1

When your onCreate method is executing, Android has not yet done it's layout pass or measuring pass.

You could measure the size of your view using the measure method but I would strongly advise implementing a callback on ViewTreeObserver instead, especially since you're using RelativeLayout (which does two layout passes along the tree).

Using ViewTreeObserver.OnGlobalLayoutListener (link) you can then make any adjustments to your layout once you know exactly where each item will be placed and their corresponding sizes.

Audiovisual answered 11/6, 2013 at 10:29 Comment(1)
I tried to set initial width and height. This is not good way to do it. Better way is create own object and implement onMeasure event.Estey
D
0

As quoted by CommonsWare here

You are calling getWidth() too early. The UI has not been sized and laid out on the screen yet.

I doubt you want to be doing what you are doing, anyway -- widgets being animated do not change their clickable areas, and so the button will still respond to clicks in the original orientation regardless of how it has rotated.

That being said, you can use a dimension resource to define the button size, then reference that dimension resource from your layout file and your source code, to avoid this problem.

Deluca answered 11/6, 2013 at 10:28 Comment(1)
How is this an answer to the question ?Rollin

© 2022 - 2024 — McMap. All rights reserved.