6

これは私のユースケースです:

実行時に膨張したレイアウトを変更したい。最初にレイアウト a を膨張させ、しばらくしてからレイアウト B を表示し、次にレイアウト C などを表示したいとします。

メインレイアウトにレイアウトを含めてから非表示/非表示にするのではなく、ビュータブを使用して膨張させる必要があることをどこかで読みました。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <ViewStub
        android:id="@+id/layout_stub"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

私の問題は、最初のレイアウトを膨らませると正常に動作しますが、次に2番目のレイアウトを膨らませようとするとスタブがnullになることです。

ViewStub stub = (ViewStub) findViewById(R.id.layout_stub);
        stub.setLayoutResource(layoutId);
        View inflated = stub.inflate();

私の理解では、Viewstub はレイアウトが読み込まれるコンテナーです。もしそうなら、2 番目のレイアウトを読み込もうとしたときに ViewStub を取得できないのはなぜですか? (これは、最初のレイアウト (A) を膨張させたときに、ViewStub が配置されていたレイアウトが完全に削除されたことを意味しますか?)

Viewstub または代替手段を使用してユースケースを実装するための指針を探しています。

4

2 に答える 2

11

ViewStubはプレースホルダーであり、 ViewStub.inflate () が呼び出されるとすぐに、膨張したレイアウトに置き換えられます。ViewStub が階層に存在しなくなるため、inflate を 2 回呼び出すのは意味がありません。代わりに、LinearLayout への参照を取得し、そのビューを削除して、2 番目のレイアウトを子として追加する必要があります。

ViewStub stub = (ViewStub) findViewById(R.id.layout_stub);
LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
stub.setLayoutResource(layoutId);
stub.inflate(); // inflate 1st layout

ll.removeAllViews(); // remove previous view, add 2nd layout
ll.addView(LayoutInflater.from(context).inflate(secondLayoutId, ll, false));
于 2016-05-25T15:57:15.147 に答える
5

はい、簡単に別の ViewStub に置き換えて、新しいレイアウトを次のように遅延膨張させることができると思います。

Java用

 public static ViewStub deflate(View view) {
    ViewParent viewParent = view.getParent();
    if (viewParent != null && viewParent instanceof ViewGroup) {
        int index = ((ViewGroup) viewParent).indexOfChild(view);
        int inflatedId = view.getId();
        ViewGroup.LayoutParams layoutParams = view.getLayoutParams();
        ((ViewGroup) viewParent).removeView(view);
        Context context = ((ViewGroup) viewParent).getContext();
        ViewStub viewStub = new ViewStub(context);
        viewStub.setInflatedId(inflatedId);
        viewStub.setLayoutParams(layoutParams);
        ((ViewGroup) viewParent).addView(viewStub, index);
        return viewStub;
    } else {
        throw new IllegalStateException("Inflated View has not a parent");
    }
}

または拡張機能付きの Kotlin

fun ViewStub.deflate(view: View): ViewStub {
    val viewParent = view.parent

    if (viewParent != null && viewParent is ViewGroup) {
        val index = viewParent.indexOfChild(view)
        viewParent.removeView(view)
        val viewStub = ViewStub(context).apply {
            inflatedId = this@deflate.inflatedId
            layoutParams = this@deflate.layoutParams
        }
        viewParent.addView(viewStub, index)
        return viewStub
    } else {
        throw IllegalStateException("Inflated View has not a parent")
    }
}

あらすじをチェックする

于 2018-06-14T10:03:49.580 に答える