2013-03-22 3 views
11

Ich habe ein sehr nerviges Problem mit der Größenanpassung von ScrollView festgestellt, und mir gehen die möglichen Lösungen aus.ScrollView ändert seine Größe nicht direkt, nachdem das Kind gewechselt hat

Ich habe einen FragmentPager, der mehrere verschiedene Fragmente enthält, von denen eines eine ScrollView hat. Das Fragment mit der ScrollView besteht aus einem Spinner und der ScrollView, die ein LinearLayout mit mehreren Zeilen anderer Ansichten (wie SeekBars, Buttons, Edittexte) enthält. Je nachdem, welche Option im Spinner ausgewählt ist, zeigt die ScrollView unterschiedliche Ansichten an. Um dies zu tun, wird die Sichtbarkeit einiger Ansichten auf "Vergehen" geändert, während andere auf "Sichtbar" gesetzt werden. Das funktioniert gut, abgesehen von der Tatsache, dass sich die ScrollView nicht korrekt zu skalieren scheint, wenn man eine andere Option mit dem Spinner auswählt.

Wenn die Bildlaufleiste voll mit Ansichten und daher scrollbar ist, wenn der Benutzer eine Option auswählt, die weniger Ansicht zeigt, als zum Befüllen des Ansichtsfensters erforderlich ist, scrollt die Bildlaufansicht weiterhin. Wenn der Benutzer die alte Option erneut auswählt, kann die ScrollView jetzt nicht mehr scrollen, da sie die für die vorherige Option erforderliche Größe angenommen hat. Wenn der Benutzer die Option SAME erneut auswählt, ist die ScrollView plötzlich scrollbar, da sie jetzt auf die tatsächlich benötigte Größe skaliert wird.

Was geht hier vor? Und noch besser, wie kann ich dieses lästige Problem beheben?

Mein Layout:

<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/control_scroll" 
    android:layout_width="fill_parent" 
    android:layout_height="0dp" 
    android:layout_weight="1" 
    android:background="#99000000" 
    android:fillViewport="true" > 

    <LinearLayout 
     android:layout_width="fill_parent" 
     android:layout_height="wrap_content" 
     android:layout_marginBottom="20dp" 
     android:orientation="vertical" > 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="#DD000000" 
      android:gravity="bottom" 
      android:orientation="vertical" > 

      <TextView 
       android:id="@+id/lamp_choose_tv" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginBottom="2dp" 
       android:paddingLeft="5dp" 
       android:text="@string/choose_lamp_text" 
       android:textColor="#FFFFFF" 
       android:textSize="14sp" /> 
     </LinearLayout> 

     <Spinner 
      android:id="@+id/lamp_select_spinner" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="5dp" 
      android:textColor="#FFFFFF" /> 

     <LinearLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:background="#DD000000" 
      android:gravity="bottom" 
      android:orientation="vertical" > 

      <TextView 
       android:id="@+id/lamp_settings_tv" 
       android:layout_width="match_parent" 
       android:layout_height="wrap_content" 
       android:layout_marginBottom="2dp" 
       android:background="#44000000" 
       android:paddingLeft="5dp" 
       android:text="@string/lamp_settings_text" 
       android:textColor="#FFFFFF" 
       android:textSize="14sp" /> 
     </LinearLayout> 
     <!-- Lamp name --> 

     <LinearLayout 
      android:id="@+id/naam_bar" 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" 
      android:gravity="bottom" 
      android:paddingBottom="3dp" 
      android:paddingLeft="10dp" 
      android:paddingRight="10dp" 
      android:paddingTop="3dp" > 

      <TextView 
       android:id="@+id/bridge_naam" 
       style="@style/ConfigText" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="1" 
       android:text="@string/config_lightname" 
       android:textColor="#FFFFFF" 
       android:textSize="16sp" /> 

      <EditText 
       android:id="@+id/lamp_naam_input" 
       android:layout_width="0dp" 
       android:layout_height="wrap_content" 
       android:layout_weight="2" 
       android:background="@drawable/tasstextfield" 
       android:inputType="textNoSuggestions" 
       android:textColor="#FFFFFF" > 
      </EditText> 
     </LinearLayout> 

     <View 
      android:id="@+id/separator" 
      android:layout_width="fill_parent" 
      android:layout_height="0.5dp" 
      android:background="@android:color/black" 
      android:visibility="visible" /> 
<!-- Rest of the views --> 

Dinge, die ich schon versucht:

  • ForceLayout/requestLayout auf der übergeordneten Scroll
  • Invalidate die Scroll
  • ForceLayout/requestLayout auf dem enthaltenden Linearlayout
  • LinearLayout ungültig machen
  • alle
  • ForceLayout/requestLayout auf alle Kinder der Scroll Kinder des Scroll Invalidierung
+0

Haben Sie versucht, mit einem [ 'ListView'] (http://developer.android.com/guide/topics/ui/layout/listview.html) anstelle des Aufbaus, was scheint, eine eigene Liste Ansicht zu sein, ? Ignoriere das 'Loader'-Beispiel auf dieser Seite - du kannst einfach eine' String [] 'oder' List 'mit jedem Textstück erstellen und diese an ein [' ArrayAdapter'] (http://developer.android.org) übergeben. com/reference/android/widget/ArrayAdapter.html), überschreiben Sie dann 'getView', um die Darstellung zu steuern. – user113215

+0

Ich kann sehen, warum Sie das denken würden. In Wirklichkeit habe ich aufgehört, TextViews zu verwenden, da dies im Grunde nur zu Testzwecken war, und verwende jetzt verschiedene Ansichten wie Buttons, EditTexts und Seekbars. Das Problem bleibt jedoch bestehen. –

+0

Ich glaube, das Problem ist die 'ScrollView' muss sich für die neuen' Views' anpassen. Wenn Sie die inneren Ansichten auf "View.VISIBLE" einstellen, rufen Sie 'requestLayout()' oder 'forceLayout()' auf der übergeordneten ScrollView auf, um einen Layout-Durchlauf zu planen. – DeeV

Antwort

4

Dies ist vielleicht nicht die angenehmste Lösung, aber es könnte funktionieren. Verwenden Sie einen Handler, um eine verzögerte Nachricht zu posten, um die Ansicht ein zweites Mal zu aktualisieren, als ob der Benutzer dieselbe Option zweimal auswählen würde, nachdem er auf die Schaltfläche zum Aktualisieren geklickt hat.

// The code when the user wants to update the views 
myButton.setOnClickListener(new OnClickListener{ 
    @Override 
    public void onClick(View view) { 
    updateView(); 
    Message m = Message.obtain(); 
    m.what = UPDATE_TAG; 
    mHandler.sendMessageDelayed(msg, 200); 
    } 
}) 

... 

final int UPDATE_TAG = 1; 

public void updateView() { 
    // Code where View.GONE and View.VISIBLE + invalidate is used. 
} 

Handler mHandler = new Handler { 
    @Override 
    public void handleMessage(Message input_msg) { 
    if(msg.what == UPDATE_TAG) { 
     updateView(); 
    } 
    } 
} 
+0

Angenehm? Nein, aber es funktioniert! Vielen Dank, hoffe diese Antwort wird auch anderen Menschen helfen. –

+0

Ich brauchte nur die Änderung der Sichtbarkeit in der aktualisierten Ansicht. Ich musste keine Entwertung vornehmen. – MinceMan

+0

Ich denke immer noch, dass es eine bessere Lösung für diesen Fehler geben muss. – MinceMan

0

Ich nehme an, dass LinearLayout eine Art von Caching-Mechanismus verwendet jedes Mal messen Childs zu vermeiden. Oder vielleicht liege ich falsch.

Sie können jedoch versuchen, RelativeLayout statt Bündel LinearLayout zu verwenden. Dies wird Ihr Problem lösen und auch dies wird viel effizienter sein, da verschachtelte ViewGroup s nicht gut für die Leistung ist.

0

können Sie voran gehen und legen Sie die Scrollhöhe „wrap_content“, so dass selbst wenn das Kind Ansichten der Scroll ändern

auf die neue Einstellung anpassen
+1

Als erstes habe ich es offensichtlich versucht. Aber das behebt das Problem nicht. –

1

Versuchen mit diesem ändert

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/control_scroll" 
android:layout_width="fill_parent" 
android:layout_height="wrap_content" 

android:background="#99000000" 
android:fillViewport="true" > 

die Quit android:layout_weight="1"

+0

Das erste, was ich ausprobiert habe, war wrap_content, aber das behebt das Problem nicht. –

Verwandte Themen