2011-02-03 2 views
14

Chcę użyć getWidth()/getHeight(), aby uzyskać szerokość/wysokość mojego układu XML. Przeczytałem, że muszę to zrobić w metodzie onSizeChanged() inaczej otrzymam 0 (Android: Get the screen resolution/pixels as integer values).Android: Potrzebuję użyć onSizeChanged dla View.getWidth/Height() w klasie rozszerzającej działanie

Ale chcę to zrobić w klasie już rozszerzającej działanie. Więc myślę, że nie jest możliwe, aby ta sama klasa rozszerzyła widok.

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 
    } 
} 

Jeśli używam MojaKlasa rozciąga Aktywny mogę używać onCreate ale nie onSizeChanged.
Jeśli używam MyClass rozszerza Widok Mogę użyć onSizeChangedbut nie naCreate.

Jak mogę rozwiązać problem?

Odpowiedz

1

Po prostu dodaj metodę do niestandardowego widoku, który wywołujesz, gdy funkcja onSizeChanged ma miejsce w działaniu. Przekaż nowe wartości do widoku jako parametry wywoływanej metody. Następnie wykonaj wszystkie operacje, które trzeba wykonać, gdy niestandardowy widok zmieni rozmiar.

+0

Przepraszam, ale nie rozumiem, co naprawdę należy zrobić. Nie mogę wywołać mojego widoku niestandardowego, gdy parametr onSizeChanged ma miejsce w działaniu, ponieważ moja klasa aktywności rozszerza działanie, a nie widok. Ale muszę rozszerzyć widok, aby użyć metody onSizeChanged. Byłoby wspaniale, gdybyś dał przykład małego kodu. – KWT

19

Co zalecam zrobić, to rozszerzenie ListView w swojej własnej klasy niestandardowej. Zdefiniuj klasę o nazwie MyListView lub coś podobnego i upewnij się, że zdefiniowano wszystkie trzy konstruktory. Następnie nadpisaj metodę onSizeChanged, aby wywołać coś zewnętrznie - podobnie jak OnClickListener lub OnTouchListener. Możesz zdefiniować metodę w MyListView, aby zaakceptować detektor, utworzyć instancję detektora w swojej aktywności, a następnie, gdy zostanie wywołana funkcja onSizeChanged, przekazać ją do odbiornika. Trudno to wyjaśnić po angielsku. Oto przykładowy kod:

klienta ListView:

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

klienta słuchacz:

public class MyOnResizeListener 
{ 
    public MyOnResizeListener(){} 

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

możliwość wystąpienia słuchacz jak:

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****/ 
      } 
    }; 
} 

I nie zapomnij, aby przejść Twój słuchacz do widoku niestandardowego:

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

Wreszcie można dodać niestandardową listę do układu XML robiąc coś takiego:

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

Dziękuję człowieku! Jednak zauważyłem wadę podczas korzystania z tego fragmentu. Musiałem przekazać obiekt nasłuchujący w metodzie onStart(), ponieważ widok fragmentów nie był obsługiwany przez działanie w trybie onCreate (stąd to jest funkcja onCreateView). –

34

nie musisz stworzyć customView aby uzyskać jego wysokość i szerokość. Możesz dodać OnLayoutChangedListener (description here) do widoku, którego szerokość/wysokość chcesz, a następnie w zasadzie uzyskać wartości w metodzie onLayoutChanged, tak jak

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

Powodem tego jest, bo widoki są rysowane tylko po Układ jest kompletny. System następnie schodzi w dół drzewa widoku hierarchii, aby zmierzyć szerokość/wysokość każdego widoku przed ich narysowaniem.

+7

OnLayoutChangeListener zakłada, że ​​Twoim celem jest API 11+ –

+3

Dzięki za wskazanie tego, @CarlWhalley! Zdałem sobie z tego sprawę, próbując użyć go w API 10 :). W rzeczywistości stwierdziłem, że jeśli wysokość/szerokość twojego układu nie zależy od tego, czy jest on określony przez inny układ (używany w układzie względnym lub przy użyciu grubości układu), możesz wymusić odmierzanie widoku w następujący sposób: view.measure (MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED), a następnie za pomocą getMeasuredHeight/Width, aby uzyskać wartości – kajham

+0

@kajham Czy to działa naCreate? Próbowałem uzyskać wymiary podczas uruchamiania aktywności i pomyślałem, że .measure będzie liczyć pasek nawigacji w ekranach pomiarów wysokości/szerokości ... – Fallenreaper

4

Miałem podobny problem (np.obliczanie rozmiarów View w Activity po zakończeniu rysowania).

Przeanalizowałem metodę Activity: public void onWindowFocusChanged(boolean hasFocus) i wszystko działało bez zarzutu.

+0

To działa dobrze i nie wymaga Androida 11 ... dzięki! – speedplane

+0

'onWindowFocusChanged' nie wydaje się działać dobrze. Mam 'Activity', która rozszerza' ExpandableListActivity'. Przeanalizowałem metodę 'onWindowFocusChanged', aby wywołać' ExpandableListView: mListView.setIndicatorBounds' w celu wyrównania wskaźnika grupy do prawej strony widoku zamiast lewej. To, co widzę, to to, że wszystkie dzieci są tworzone z wyrównanym po lewej stronie wskaźnikiem grupy, a następnie następuje ponowne przerysowanie ze wskaźnikiem grupy po prawej stronie. Widzę, że to ponowne ustalenie się dzieje, co wskazuje, że nie jest to najlepsze miejsce do zrobienia układu widoku. –

Powiązane problemy