2011-02-03 21 views
14

Quiero usar getWidth()/getHeight() para obtener el ancho/alto de mi XML-Layout. He leído que tengo que hacerlo en el método onSizeChanged() de lo contrario obtendré 0 (Android: Get the screen resolution/pixels as integer values).Android: Necesito usar onSizeChanged para View.getWidth/Height() en la clase que extiende Activity

Pero quiero hacerlo en una clase que ya se extiende Actividad. Así que creo que no es posible dejar que la misma clase extienda View.

public class MyClass extends Activity { 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     ViewGroup xml_layout = (ViewGroup) findViewById(R.id.layout_id); 
     TextView tv = new TextView(this); 
     tv = (TextView) findViewById(R.id.text_view); 
     int layout_height = xml_layout.getHeight(); 
     int layout_width = xml_layout.getWidth(); 
    } 

    protected void onSizeChanged(int w, int h, int oldw, int oldh) { 
     //Error, because I need to use extends View for class, but I can't do it because I also need extends Activity to use onCreate 
    } 
} 

Si uso MiClase extiende Actividad puedo usar onCreate pero no onSizeChanged.
Si uso MyClass extends View, puedo usar onSizeChangedbut onCreate.

¿Cómo puedo resolver el problema?

Respuesta

1

Simplemente agregue un método a su vista personalizada a la que llama cuando se produce onSizeChanged en la Actividad. Pase los nuevos valores a la vista como parámetros del método llamado. Luego ejecute las operaciones que necesiten tener lugar cuando su vista personalizada cambie de tamaño.

+0

Lo siento, pero realmente no entiendo qué hacer. No puedo llamar a mi vista personalizada cuando se produce onSizeChanged en la Actividad porque mi clase de actividad amplía la Actividad y no la Vista. Pero tengo que ampliar la vista para usar el método onSizeChanged. Sería genial si pudiera dar un pequeño ejemplo de código. – KWT

19

Lo que recomendaría hacer es extender ListView en su propia clase personalizada. Defina una clase llamada MyListView, o algo similar, y asegúrese de definir los tres constructores. Luego, anule el método onSizeChanged para llamar a algo externamente, al igual que OnClickListener o OnTouchListener. Podría definir un método en MyListView para aceptar un oyente, crear instancias de un oyente en su actividad y, luego, cuando se llame a onSizeChanged, pasarlo al oyente. Esto es realmente difícil de explicar en inglés. Aquí hay un código de ejemplo:

personalizada ListView: oyente

public class MyListView extends ListView 
{ 
    public MyListView(Context context) 
    { 
     super(context); 
    } 
    public MyListView(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
    } 
    public MyListView(Context context, AttributeSet attrs, int defStyle) 
    { 
     super(context, attrs, defStyle); 
    } 

    public void SetOnResizeListener(MyOnResizeListener orlExt) 
    { 
     orl = orlExt; 
    } 

    @Override 
    protected void onSizeChanged(int xNew, int yNew, int xOld, int yOld) 
    { 
     super.onSizeChanged(xNew, yNew, xOld, yOld); 

     if(orl != null) 
     { 
      orl.OnResize(this.getId(), xNew, yNew, xOld, yOld); 
     } 
    } 

    MyOnResizeListener orl = null; 
} 

personalizado:

public class MyOnResizeListener 
{ 
    public MyOnResizeListener(){} 

    public void OnResize(int id, int xNew, int yNew, int xOld, int yOld){} 
} 

se ejemplariza el oyente como:

Class MyActivity extends Activity 
{ 
     /***Stuff***/ 

    MyOnResizeListener orlResized = new MyOnResizeListener() 
    { 
      @Override 
      public void OnResize(int id, int xNew, int yNew, int xOld, int yOld) 
      { 
      /***Handle resize event****/ 
      } 
    }; 
} 

Y no se olvide de pasar su oyente a su vista personalizada:

/***Probably in your activity's onCreate***/ 
((MyListView)findViewById(R.id.MyList)).SetOnResizeListener(orlResized); 

Por último, puede agregar su lista personalizada a un diseño XML haciendo algo como:

<com.myapplication.whatever.MyListView> 
     <!-- Attributes --> 
<com.myapplication.whatever.MyListView/> 
+0

¡Gracias, amigo! Sin embargo, noté un error al usar esto con un fragmento. Tuve que pasar al oyente en el método onStart() ya que la actividad en onCreate no manejaba la vista de fragmentos (de ahí para qué es onCreateView). –

34

Usted no tiene que crear un customView para obtener su altura y ancho Se puede añadir una OnLayoutChangedListener (description here) a la vista cuya anchura/altura que desee y, a continuación, obtener esencialmente los valores en el método onLayoutChanged, al igual que

View myView = findViewById(R.id.my_view); 
myView.addOnLayoutChangeListener(new OnLayoutChangeListener() { 

     @Override 
     public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, 
       int oldBottom) { 
      // its possible that the layout is not complete in which case 
      // we will get all zero values for the positions, so ignore the event 
      if (left == 0 && top == 0 && right == 0 && bottom == 0) { 
       return; 
      } 

      // Do what you need to do with the height/width since they are now set 
     } 
    }); 

La razón de esto es porque las opiniones son atraídos sólo después de la el diseño está completo. El sistema luego recorre el árbol jerárquico de vista para medir el ancho/alto de cada vista antes de dibujarlos.

+7

OnLayoutChangeListener supone que su objetivo es API 11+ –

+3

Gracias por señalarlo, @CarlWhalley! Me di cuenta de eso cuando trato de usarlo en API 10 :). De hecho, descubrí que si el alto/ancho de su diseño no depende de que esté determinado por ningún otro diseño (se usa en un diseño relativo o usa pesos de diseño), puede incluso forzar que la Vista se mida de la siguiente manera: view.measure (MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED) y luego usando getMeasuredHeight/Width para obtener los valores – kajham

+0

@kajham ¿Eso funciona en Crear? Estaba tratando de obtener las dimensiones cuando se inicia la actividad, y pensé que la medida contaría la barra de navegación en las medidas de altura/ancho de las pantallas ... – Fallenreaper

4

Tuve un problema similar (es decir.calculando View tamaños en un Activity después de que se terminó de dibujar).

Anulé el método Activity: public void onWindowFocusChanged(boolean hasFocus) y funcionó bien.

+0

Eso funciona bien y no requiere Android 11 ... ¡gracias! – speedplane

+0

'onWindowFocusChanged' no parece funcionar muy bien. Tengo una 'Activity' que extiende' ExpandableListActivity'. Sobreescribí el método 'onWindowFocusChanged' para llamar a' ExpandableListView: mListView.setIndicatorBounds' para alinear el indicador de grupo al lado derecho de la vista en lugar de a la izquierda. Lo que veo que sucede es que todos los niños se crean con el indicador de grupo alineado a la izquierda y luego otro redibujado sucede con el indicador de grupo a la derecha. Puedo ver este realineamiento sucediendo lo que indica que este podría no ser el mejor lugar para ver el diseño. –

Cuestiones relacionadas