如何以编程方式在 Android 中获取图像按钮的宽度和高度

Posted

技术标签:

【中文标题】如何以编程方式在 Android 中获取图像按钮的宽度和高度【英文标题】:How to programmatically get an Image Button's width and height in Android 【发布时间】:2015-06-02 20:34:54 【问题描述】:

我试图在 android 中以编程方式获取图像按钮宽度和高度的整数变量。我想这样做是因为图像的大小会因设备而异。我怎样才能做到这一点? 我已经试过了。

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

但它返回零?? 位图在 API 22+ 中已弃用。获取实际图像的大小也不起作用,因为我稍微扭曲了它以适应我的需要。所以drawable.getIntrinsicHeight(); 不在讨论范围内(是的,我知道你必须声明一个可绘制对象,然后才说drawable.getIntrinsicHeight 但IDC)。我很混乱。请帮忙!

完整代码:

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_
    android:layout_ 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_
        android:layout_
        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_
        android:layout_
        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_
        android:layout_
        android:id="@+id/candy"
        android:background="@drawable/candy"
        android:contentDescription="@string/candyImg"
        android:clickable="true" />

</RelativeLayout>

【问题讨论】:

你能把xml布局贴出来吗,你在那里设置了高度和宽度吗? 是的。我将其设置为 50dp。 检查这个间接post 如果你已经知道尺寸然后使用它 【参考方案1】:

可能是您调用这些方法太早了。在覆盖的run() 方法中使用imageButton.post(new Runnable..) 和getWidth 和getHeight。

前段时间遇到了同样的问题。这是因为过早调用width和height方法会导致它们为0,因为视图没有正确初始化/测量。

【讨论】:

不,似乎不起作用。在我尝试获取它的宽度和高度之前,我还声明了图像按钮“candyEdit”。所以理论上它应该工作。为什么这么说? 按钮中的图片是否显示?仅针对测试用例,我会创建第二个按钮,即所需按钮的宽度和高度,以消除时间问题 candyEdit 是否声明为“wrap_content”、“wrap_content”? 不,它不是 wrap_content。它是 50dp。是的,图像也显示出来了。 我敢打赌这是一个时间问题检查:***.com/questions/4142090/…【参考方案2】:

您正在尝试在呈现布局之前测量尺寸,这发生在 onCreate 方法期间,因此该方法需要完成。解决此问题的最简单方法是创建一个可运行对象,它会在 onCreate 方法完成后执行代码:

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

            ...
        

);

【讨论】:

【参考方案3】:

尝试测量宽度和高度 http://developer.android.com/reference/android/view/View.html#getMeasuredWidth()

http://developer.android.com/reference/android/view/View.html#getMeasuredHeight()

【讨论】:

也返回 (0, 0) 是不是因为别的原因?

以上是关于如何以编程方式在 Android 中获取图像按钮的宽度和高度的主要内容,如果未能解决你的问题,请参考以下文章

如何在iphone中以编程方式实现带有背景图像的按钮

[Android - Kitkat ]以编程方式从 Android 的内置图库应用程序中获取/选择图像

在其线性布局垂直父Android中将以编程方式创建的单选按钮居中

android以编程方式获取按钮背景imageName

如何以编程方式获取 Android 导航栏的高度和宽度?

以编程方式从 Android 的内置图库应用程序中获取/选择图像