2013-03-22 11 views
11

Ho riscontrato un problema molto fastidioso per quanto riguarda il ridimensionamento di ScrollView e sto esaurendo le possibili soluzioni.ScrollView non viene ridimensionato direttamente dopo le modifiche apportate al bambino

Ho un FragmentPager che contiene diversi frammenti, uno dei quali ha una ScrollView. Il frammento con ScrollView è costituito da uno Spinner e da ScrollView contenenti un LinearLayout con diverse righe di altre viste (come SeekBars, Buttons, Edittexts) al suo interno. A seconda dell'opzione selezionata nella casella di selezione, la vista a scorrimento mostra diverse viste. Per fare ciò, alcune viste hanno la loro visibilità su Via, mentre altre sono rivolte a Visibile. Funziona alla grande, tranne per il fatto che ScrollView non sembra ridimensionarsi correttamente quando si sceglie un'opzione diversa con lo Spinner.

Quando ScrollView è pieno di viste, quindi scorrevole, se l'utente seleziona un'opzione che mostra meno Viewsthan necessari per riempire ViewPort, ScrollView continua a scorrere. Quando l'utente sceglie nuovamente l'opzione precedente, ScrollView non è più in grado di scorrere poiché ha assunto la dimensione richiesta per l'opzione precedente. Quando l'utente sceglie di nuovo l'opzione SAME, ScrollView diventa improvvisamente scorrevole, poiché ora viene ridimensionato alla dimensione effettiva richiesta.

Cosa sta succedendo qui? E ancora meglio, come posso risolvere questo fastidioso problema?

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

cose Ho già provato:

  • ForceLayout/requestLayout sul genitore ScrollView
  • invalidare la ScrollView
  • ForceLayout/requestLayout sul contenente LinearLayout
  • Invalidazione del LinearLayout
  • Invalidare tutti i bambini del ScrollView
  • ForceLayout/requestLayout su tutti i bambini della ScrollView
+0

Hai provato a usare un [ 'ListView'] (http://developer.android.com/guide/topics/ui/layout/listview.html) invece di costruire quello che sembra essere il vostro punto di vista lista ? Ignora l'esempio di 'Loader' su quella pagina - puoi semplicemente creare un' String [] 'o' List 'con ogni parte di testo e inviarlo a un [' ArrayAdapter'] (http://developer.android. it/reference/android/widget/ArrayAdapter.html), quindi sovrascrivi 'getView' per controllare l'aspetto. – user113215

+0

Capisco perché lo penseresti. In realtà ho smesso di usare TextViews perché fondamentalmente era solo a scopo di test e ora sto usando visualizzazioni diverse come Buttons, EditTexts e Seekbar. Il problema tuttavia, rimane ancora. –

+0

Credo che il problema è il 'ScrollView' ha bisogno di ridimensionarsi per il nuovo' Views'. Quando si impostano le viste interne sono impostate su 'View.VISIBLE' chiamata' requestLayout() 'o' forceLayout() 'su ScrollView padre per pianificare un passaggio di layout. – DeeV

risposta

4

Questa potrebbe non essere la soluzione più divertente, ma potrebbe funzionare. Utilizzare un gestore per inviare un messaggio in ritardo per aggiornare la vista una seconda volta, come se l'utente sceglierebbe la stessa opzione due volte dopo aver fatto clic sul pulsante di aggiornamento.

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

Piacevole? No. Ma funziona! Grazie mille, spero che questa risposta aiuti anche gli altri. –

+0

Ho appena avuto bisogno della modifica della visibilità nella vista aggiornata. Non ho dovuto fare alcuna invalidazione. – MinceMan

+0

Continuo a pensare che ci sia una soluzione migliore a questo bug. – MinceMan

0

Suppongo che LinearLayout usa un qualche tipo di meccanismo di caching per evitare bambino di misura ogni volta. O forse mi sbaglio.

Tuttavia, è possibile provare a utilizzare RelativeLayout anziché il numero LinearLayout. Questo risolverà il tuo problema e anche questo sarà molto più efficiente, dal momento che nested ViewGroup s non è buono per le prestazioni.

0

Si può andare avanti e impostare l'altezza ScrollView a "wrap_content" in modo che, anche se il punto di vista dei bambini cambiano lo ScrollView può regolare per impostare la nuova

+1

Per prima cosa ho provato, ovviamente. Ma questo non risolve il problema. –

1

Prova con questo cambia

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

Quit il android:layout_weight="1"

+0

Per prima cosa ho provato wrap_content, tuttavia questo non risolve il problema. –

Problemi correlati