14

ScrollView のサイズ変更に関して非常に厄介な問題に遭遇し、考えられる解決策が不足しています。

いくつかの異なるフラグメントを含む FragmentPager があり、そのうちの 1 つに ScrollView があります。ScrollView を含む Fragment は、Spinner と、複数行の他のビュー (SeekBars、Buttons、Edittexts など) を含む LinearLayout を含む ScrollView で構成されます。スピナーで選択されているオプションに応じて、ScrollView は異なるビューを表示します。そのために、一部のビューの可視性を [Gone] に変更し、他のビューを [Visible] に変更します。Spinner を使用して別のオプションを選択すると、ScrollView が適切にサイズ変更されないように見えるという事実を除いて、これはうまく機能します。

ScrollView がビューでいっぱいでスクロール可能である場合、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 -->

私がすでに試したこと:

  • 親 ScrollView の ForceLayout/requestLayout
  • ScrollView を無効にする
  • 含まれている LinearLayout の ForceLayout/requestLayout
  • LinearLayout の無効化
  • ScrollView のすべての子を無効にする
  • ScrollView のすべての子に対する ForceLayout/requestLayout
4

4 に答える 4

4

これは最も楽しい解決策ではないかもしれませんが、うまくいくかもしれません。ユーザーが更新ボタンをクリックした後に同じオプションを 2 回選択したかのように、ハンドラーを使用して遅延メッセージを投稿し、ビューを 2 回更新します。

// 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();
    }
  }
}
于 2013-04-02T08:24:38.487 に答える
0

LinearLayout毎回の子の測定を避けるために、ある種のキャッシュメカニズムを使用していると思います。または多分私は間違っています。

RelativeLayoutただし、束の代わりに使用してみることができますLinearLayout。これにより問題が解決され、ネストされたViewGroups はパフォーマンスに適していないため、はるかに効率的になります。

于 2013-03-26T14:53:37.133 に答える