简体   繁体   中英

How to programmatically get an Image Button's width and height in Android

Im trying to programmatically get an integer variable of an Image Button's width and height in Android. I want to do this because the size of the image will vary depending on the device. How can I Do this? I've already tried.

width = Image.getWidth(); height = image.getHeight();

But it returns zero?? BitMap is deprecated in API 22+. Also getting the size of the actual Image will not work because I slightly distort it to fit my needs. So drawable.getIntrinsicHeight(); is off the table (Yes I know you must declare a drawable befor just saying drawable.getIntrinsicHeight but IDC). I'm so confused. Please Help!

Full code:

package com.example.e99900004533.candycollector;

//imports for android, and Random
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.graphics.Point;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Display;
import android.widget.EditText;
import android.widget.ImageButton;
import android.os.CountDownTimer;
import android.graphics.drawable.Drawable;
import java.util.Random;

public class MainActivity extends ActionBarActivity {

    //Original global variables. Non-static.
    public EditText collectedTextEdit;
    public EditText timerTextEdit;
    public ImageButton candyEdit;
    public int screenWidth;
    public int screenHeight;
    public int candyX;
    public int candyY;
    public int collected = 0;
    public long time;
    public boolean candyBag = false;
    public String currentCandy = "candy";
    public boolean running = true;
    public int candyWidth;
    public int candyHeight;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        collectedTextEdit = (EditText) findViewById(R.id.collectedText);
        timerTextEdit = (EditText) findViewById(R.id.timerText);
        candyEdit = (ImageButton) findViewById(R.id.candy);
        candyEdit.setBackgroundResource(R.drawable.candy);
        collectedTextEdit.setText("Collected: " + collected);
        timerTextEdit.setText("Time: ");

        //Sets timer to 30 seconds. Displays time. Ends game when time runs out.
        new CountDownTimer(30000, 1000) {

            public void onTick(long millisUntilFinished) {
                time = millisUntilFinished / 1000;
                timerTextEdit.setText("Time: " + time);
            }

            public void onFinish() {
                //When game timer is complete.
                timerTextEdit.setText("GAME OVER!!!");
                collectedTextEdit.setText("Score: " + collected);
                timerTextEdit.setX(screenWidth / 2); //Sets to middle of screen. Directly above score.
                timerTextEdit.setY(screenHeight / 2);
                collectedTextEdit.setX(screenWidth / 2); //Sets to middle of screen. Directly below score.
                collectedTextEdit.setY(screenHeight / 3);
                running = false;
                candyEdit.setVisibility(View.INVISIBLE); //Makes candy Image invisible.
            }
        }.start();

        //Gets screen width and height. Sets to two already created variables.
        Display display = getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        screenWidth = size.x;
        screenHeight = size.y;

        candyWidth = candyEdit.getMeasuredWidthAndState(); //PROBLEM HERE!!
        candyHeight = candyEdit.getMeasuredHeightAndState(); //PROBLEM HERE!!

        addListenerOnButton();
    }

    //Onclick for ImageButton candy.
    public void addListenerOnButton() {

        candyEdit.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                if (running) {
                    //Adds to collected and changes text.
                    collected += 1;
                    collectedTextEdit.setText("Collected: " + collected);

                    //Checks if CandyBag. Then resets.
                    if (candyBag) {
                        candyBag = false;
                        if (currentCandy.equals("candy")) {
                            candyEdit.setBackgroundResource(R.drawable.candy);
                        }
                        if (currentCandy.equals("candyTwo")) {
                            candyEdit.setBackgroundResource(R.drawable.candy2);
                        }
                        if (currentCandy.equals("candyThree")) {
                            candyEdit.setBackgroundResource(R.drawable.candy3);
                        }
                    }

                    //Gets new candy images at certain score.
                    if (collected >= 15 && collected < 30) {
                        candyEdit.setBackgroundResource(R.drawable.candy2);
                        currentCandy = "candyTwo";
                    }
                    if (collected >= 30) {
                        candyEdit.setBackgroundResource(R.drawable.candy3);
                        currentCandy = "candyThree";
                    }

                    //sets candy X and Y variables.
                    Random random = new Random();
                    candyX = random.nextInt(screenWidth - candyWidth * 2); //minus height and width of image.
                    candyY = random.nextInt(screenHeight - candyHeight * 2);
                    candyX += candyWidth;
                    candyY += candyHeight; //Plus extra to keep on screen.

                    //Sets candyBag if random = 1. 1 / x chance.
                    int candyRandom = random.nextInt(10);
                    if (candyRandom == 1) {
                        candyEdit.setBackgroundResource(R.drawable.candybag);
                        candyBag = true;
                        collected += 2;
                    }

                    //Makes sure candy is not off screen. Replaces if so.
                    while (candyX >= screenWidth - candyWidth || candyY >= screenHeight - candyHeight) {
                        if (candyX >= screenWidth || candyY >= screenHeight) {
                            candyX = random.nextInt(screenWidth - candyWidth * 2);
                            candyY = random.nextInt(screenHeight - candyHeight * 2);
                            candyX += candyWidth;
                            candyY += candyHeight;
                        }
                    }

                    //Sets candy X and Y.
                    System.out.println(candyX + " : " + candyY);
                    System.out.println((screenWidth - candyWidth * 2) + " : " + (screenHeight - candyHeight * 2));
                    System.out.println(candyWidth + " : " + candyHeight);
                    candyEdit.setX(candyX);
                    candyEdit.setY(candyY);
                }
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

.

<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:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
    android:background="@drawable/background">

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/collectedText"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:inputType="none"
        android:text="@string/collectedText"
        android:textColor="#ffffff"
        android:textSize="25sp"
        android:textStyle="bold"
        android:singleLine="true"
        android:clickable="false"
        android:textIsSelectable="false"
        android:editable="false" />

    <EditText
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/timerText"
        android:layout_alignTop="@+id/collectedText"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:inputType="none"
        android:text="@string/collectedText"
        android:textColor="#ffffff"
        android:textSize="25sp"
        android:textStyle="bold"
        android:singleLine="true"
        android:clickable="false"
        android:textIsSelectable="false"
        android:editable="false" />

    <ImageButton
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:id="@+id/candy"
        android:background="@drawable/candy"
        android:contentDescription="@string/candyImg"
        android:clickable="true" />

</RelativeLayout>

It may be, that you are calling these methods too early. Use imageButton.post(new Runnable..) with the getWidth and getHeight in the overriden run() method.

Had the same problem some time ago. It is caused because of calling the width and height methods too early will cause them to be 0, because the view isn't properly initialized / measured.

You are trying to measure the dimensions before the layout is rendered, which happens on during the onCreate method, so that method needs to complete. The easiest way to fix this is to create a runnable, which will execute the code once the onCreate method is completed:

    myButton = (ImageButton) findViewById(R.id.YourButton);
    myButton.post(new Runnable() {
        @Override
        public void run() {
            int w = myButton.getMeasuredWidthandState();
            int h = myButton.getMeasuredHeightandState();

            ...
        }

});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM