getWidth и getHeight возвращают ноль

Я пытаюсь сделать простую программу для рисования для Android.

У меня есть обычай View класс для обработки рисунка. Когда я звоню getWidth а также getHeight Метеды, я получаю ноль.

Но рисунок работает отлично, я жестко кодирую по ширине и высоте, чтобы он работал. Почему он это делает?


Класс My View

public class cDrawing extends View{

    char BitMap[];
    static final short WIDTH=160;
    static final short HEIGHT=440;
    static final char EMPTY=' ';
    int mWidthSize;
    int mHeightSize;

    static final char RED ='R';
    int y;

    public cDrawing(Context context) {
        super(context);

        y=3;
        // set up our bitmap
        BitMap=new char[WIDTH*HEIGHT];
        for(int i=0; i<WIDTH*HEIGHT; i++)
                BitMap[i]=EMPTY;


        // returns zero why???????
        int h=getHeight();
        h=400;
        int w=getWidth();
        w=320;
        mWidthSize=w/WIDTH;
        mHeightSize=h/HEIGHT;


        // TODO Auto-generated constructor stub
    }

Класс деятельности

public class cCanves extends Activity  implements OnClickListener {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.canves);
        cDrawing board=new cDrawing(this);


        LinearLayout layout = (LinearLayout)findViewById(R.id.parent2);
        layout.addView(board);


        // set up buttons
        View mEraser = findViewById(R.id.buteraser);
        mEraser.setOnClickListener(this);

        View mBlack = findViewById(R.id.butblack);
        mBlack.setOnClickListener(this);

        View mWhite = findViewById(R.id.butwhite);
        mWhite.setOnClickListener(this);

        View mRed = findViewById(R.id.butred);
        mRed.setOnClickListener(this);

    } // end function

    public void onClick(View v) {
        Intent i;
        switch(v.getId())
        {
        case R.id.buteraser:
            break;
        case R.id.butblack:
            break;
        case R.id.butwhite:
            break;
        case R.id.butred:
            break;
        } // end switch

    }   // function
}

XML-файл

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/parent"
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:orientation="vertical"
  android:layout_height="fill_parent">

    <LinearLayout
      xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="wrap_content"
      android:orientation="horizontal"
      android:layout_height="wrap_content">

    <ImageButton android:id="@+id/buteraser"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <ImageButton android:id="@+id/butblack"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <ImageButton android:id="@+id/butwhite"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>

    <ImageButton android:id="@+id/butred"
      android:src="@drawable/icon"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"/>
    </LinearLayout>

    <LinearLayout android:id="@+id/parent2"
      android:layout_width="fill_parent"
      android:orientation="vertical"
      android:layout_height="fill_parent">
    </LinearLayout>


</LinearLayout>

6 ответов

Решение

Ширина и высота не определяются до тех пор, пока вид фактически не отобразится на экране.

Используйте защищенный абстрактный void onLayout (логическое значение изменено, int l, int t, int r, int b) (которое вы переопределяете в своей деятельности), чтобы узнать, когда размеры готовы.

Дополняя ответ Маха, я обнаружил, что вы можете получить значения из параметров, как показано ниже:

ImageView imageProcess = (ImageView) li.inflate(
    R.layout.andamento_sinistro_imageprocess, centerLayout, false);
imageProcess.setBackgroundResource(
    (isActive)?(R.drawable.shape_processon):(R.drawable.shape_processoff));
RelativeLayout.LayoutParams imageProcessParams = 
    (RelativeLayout.LayoutParams)imageProcess.getLayoutParams();
imageProcessParams.leftMargin = 
    (int) (centerPosition - 0.5*imageProcessParams.width);
imageProcessParams.addRule(RelativeLayout.CENTER_VERTICAL);
centerLayout.addView(imageProcess);

Реальная выгода здесь - использование LayoutParams, у которых есть правила, еще не обработанные элементом.

Я не уверен, но это может иметь какое-то отношение к тому, где находится код в жизненном цикле вашей деятельности. Если ты звонишь getWidth() а также getHeight() до того, как представление отобразится на экране, вы получите значение 0. У меня это тоже случалось.

Я не уверен, есть ли способ обойти это. Я должен был полагаться на получение ширины и высоты аппаратного экрана, а не ширины и высоты вида. Возможно, вам придется приблизиться к ширине и высоте вашего вида и жестко его кодировать.

Вы должны вызвать getWidth() и getHeight() в переопределенном методе onLayout.

Просто используйте прослушиватель getViewTreeObserver(), и внутри него просто рассчитайте высоту и ширину.

Следуйте коду:

getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { //Do your Stuff calculation , like view.getWidth() ... });

Представление имеет размеры только после первого отображения.

Другая вещь:

int h=getHeight();
h=400;

Бесполезно нет? Это только для тестирования?

Другие вопросы по тегам