J_yang
J_yang

Reputation: 2812

Android Studio, how to find view width and height. getWidth() returned 0

I followed the thread answered by Gautier Haroun on how to create a touchscreen and allow tapping and displaying the coordinate. But I want to normalize the coordinate by dividing with the text view width and height respectively to get a range between 0~1.

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        final TextView textView = (TextView)findViewById(R.id.textView);
        // this is the view on which you will listen for touch events
        final View touchView = findViewById(R.id.touchView);
        final float touchWidth = touchView.getWidth();
        final float touchHeight = touchView.getHeight();

        touchView.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {    
                textView.setText("Touch coordinates : " +
                        String.valueOf(event.getX()/touchWidth) + " x " + String.valueOf(event.getY()/touchHeight));
                return true;
            }
        });


        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

Then the layout:

<TextView
    android:id="@+id/textView"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Hello World, TestActivity"
    android:layout_alignParentTop="true"
    android:layout_alignParentEnd="true" />

<TextView
    android:id="@+id/touchView"
    android:background="#f00"
    android:layout_weight="1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:alpha="0.5" />

I tried final float touchWidth = touchView.getWidth(); But the result is infinite, so touch Width is 0 instead of around 1500 in my case. Can you tell me how to get the width and height of the View object touch View?

Thanks

Upvotes: 3

Views: 1578

Answers (2)

x0r
x0r

Reputation: 1271

You can use this:

touchView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                touchView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
            else {
                touchView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            final float touchWidth = touchView.getWidth();
            final float touchHeight = touchView.getHeight();
            ...
        }
    });

your code will look like this:

private float touchWidth;
private float touchHeight;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    final TextView textView = (TextView)findViewById(R.id.textView);
    // this is the view on which you will listen for touch events
    final View touchView = findViewById(R.id.touchView);

    touchView.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) { 
            if(touchWidth == 0 || touchHeight == 0)
                return false;

            textView.setText("Touch coordinates : " +
                    String.valueOf(event.getX()/touchWidth) + " x " + String.valueOf(event.getY()/touchHeight));
            return true;
        }
    });

    touchView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                touchView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            }
            else {
                touchView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }

            touchWidth = touchView.getWidth();
            touchHeight = touchView.getHeight();
        }
    });

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });
}

Upvotes: 2

Alex Chengalan
Alex Chengalan

Reputation: 8281

OnGlobalLayoutListener is one method for getting the measurement

ViewTreeObserver viewTreeObserver = view.getViewTreeObserver();
      if (viewTreeObserver.isAlive()) {
      viewTreeObserver.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
          if (Build.VERSION.SDK_INT < 16) {
               view.getViewTreeObserver().removeGlobalOnLayoutListener(this);
          } else {
               view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
          }
          viewWidth = view.getWidth();
          viewHeight = view.getHeight();
        }
      });
    }

The another method is use onWindowFocusChanged

 @Override
 public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);
  viewWidth = view.getWidth();
  viewHeight = view.getHeight();
 }

Upvotes: 0

Related Questions