web-dev-qa-db-fra.com

getWidth et getHeight retournent un zéro

J'essaie de faire un programme de dessin simple pour Android.

J'ai une classe personnalisée View pour gérer le dessin. Lorsque j'appelle ses méthodes getWidth et getHeight, je reçois un zéro.

Mais, le dessin fonctionne bien, je code dur en largeur et en hauteur, donc ça marche. Pourquoi ça fait ça?


Ma classe de vue

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
    }

La classe d'activité

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
}

le fichier 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>
21
Ted pottel

La largeur et la hauteur ne sont pas définies tant que la vue n'est pas rendue à l'écran.

Utilisez abstract abstract vide onLayout (booléen modifié, int, int, int, int b) (que vous remplacez dans votre activité) pour savoir quand les tailles sont prêtes.

19
mah

Complétant la réponse de Mah, j'ai découvert que vous pouvez obtenir les valeurs à partir de paramètres, comme le code ci-dessous:

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);

Le vrai problème ici est l'utilisation des LayoutParams, qui ont des règles non encore traitées par l'élément.

6
Luiz Vianna

Je n'en suis pas certain, mais cela peut avoir un lien avec le code dans le cycle de vie de votre activité. Si vous appelez getWidth() et getHeight() avant que la vue ne soit affichée à l'écran, vous obtenez une valeur de 0. Cela m'est également arrivé.

Je ne suis pas sûr s'il y a un moyen de contourner cela. Je devais compter sur la largeur et la hauteur de l'écran du matériel, plutôt que sur la largeur et la hauteur de la vue. Vous devrez peut-être approximer la largeur et la hauteur de votre vue et la coder en dur.

3
Jack Smartie

Vous devez appeler getWidth () et getHeight () dans la méthode surchargée onLayout .

1
Ginsan

Utilisez simplement le programme d'écoute getViewTreeObserver () et, à l'intérieur de ce paramètre, Calculera la hauteur et la largeur.

Suivez le code:

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

0
KRIPA SHANKAR JHA