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
Ответы
Ответ 1
Это может быть не самое приятное решение, но оно может работать.
Используйте обработчик для отправки сообщения с задержкой, чтобы обновить представление во второй раз, как если бы пользователь дважды выбирал одну и ту же опцию после нажатия кнопки обновления.
// 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();
}
}
}
Ответ 2
Попробуйте с этими изменениями
<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"
Ответ 3
Я полагаю, что LinearLayout
использует какой-то механизм кеширования, чтобы каждый раз не мешать измерениям. Или, может быть, я ошибаюсь.
Однако вы можете попытаться использовать RelativeLayout
вместо связки LinearLayout
. Это решит вашу проблему, и это будет намного более эффективно, так как вложенный ViewGroup
не подходит для производительности.
Ответ 4
Вы можете пойти вперед и установить высоту ScrollView в значение "wrap_content", чтобы даже если изменения в представлении дочерних элементов ScrollView можно настроить на новую настройку