ScrollView не изменяет размер сразу после изменений ребенка

Я столкнулся с очень неприятной проблемой изменения размера ScrollView, и у меня заканчиваются возможные решения.

У меня есть FragmentPager, содержащий несколько разных фрагментов, один из которых имеет ScrollView. Фрагмент с ScrollView состоит из Spinner и ScrollView, содержащих LinearLayout, с несколькими строками других представлений (таких как SeekBars, Buttons, Edittexts). В зависимости от того, какой параметр выбран в Spinner, ScrollView показывает разные виды. Для этого некоторые виды имеют свою видимость, повернутую к Gone, а другие – к Visible. Это отлично работает, за исключением того факта, что ScrollView, по-видимому, не изменяет свое качество при выборе другого варианта с помощью Spinner.

Когда ScrollView полон представлений и, следовательно, прокручивается, если пользователь выбирает параметр, который показывает меньше Viewsthan, необходимый для заполнения ViewPort, ScrollView все еще прокручивает. Когда пользователь снова выбирает старый параметр, ScrollView теперь не может прокручиваться, так как он принимает размер, необходимый для предыдущей опции. Когда пользователь снова выбирает параметр SAME, ScrollView внезапно прокручивается, так как теперь он изменяется на нужный размер.

Что здесь происходит? И еще лучше, как я могу исправить эту неприятную проблему?

Мой макет:

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

Вещи, которые я уже пробовал:

  • ForceLayout / requestLayout для родительского ScrollView
  • Недействительность ScrollView
  • ForceLayout / requestLayout в содержащем LinearLayout
  • Недействительность LinearLayout
  • Недействительность всех дочерних элементов ScrollView
  • ForceLayout / requestLayout для всех дочерних элементов ScrollView

Solutions Collecting From Web of "ScrollView не изменяет размер сразу после изменений ребенка"

Это может быть не самое приятное решение, но это может сработать. Используйте обработчик для отправки сообщения с задержкой, чтобы обновить представление во второй раз, как если бы пользователь дважды выбирал одну и ту же опцию после нажатия кнопки обновления.

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

Попробуйте с этими изменениями

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

Выйти из android:layout_weight="1"

Я полагаю, что LinearLayout использует какой-то механизм кеширования, чтобы каждый раз не LinearLayout . Или, может быть, я ошибаюсь.

Однако вы можете попытаться использовать RelativeLayout вместо группы LinearLayout . Это решит вашу проблему, и это будет намного более эффективно, так как вложенные ViewGroup s не подходят для производительности.

Вы можете пойти вперед и установить высоту ScrollView в значение «wrap_content», чтобы даже если изменения вида child изменяются, ScrollView может настроить новую настройку