Android <include>有效,但ViewStub没有,为什么?

时间:2016-05-19 14:47:17

标签: android xml android-layout viewstub

我在FrameLayout中使用ViewStub,这样我就可以在第一次打开应用程序时通过教程视图对其进行充气。

我的Activity.xml

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">

   ...

   <ViewStub
       android:id="@+id/introHolder"
       android:inflatedId="@+id/introHolder"
       android:layout="@layout/intro_landing1"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />
</FrameLayout>

我正在给它充气的视图称为intro_landing1.xml,它是一个RelativeLayout。

intro_landing1.xml:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="@color/opaqBlack30"
android:id="@+id/introView1"
android:tag="RelativeLayoutIntroViewTag">

<!--...-->

</RelativeLayout>

在我的Activity onCreate中,我使用两种不同的方法来膨胀ViewStub,但它们都不起作用(我看不到intro_landing1视图)。

第一种方法 - 设定可见性:

if(!previouslyStarted){
   ((ViewStub) findViewById(R.id.introHolder)).setVisibility(View.VISIBLE);
}

第二种方法 - 给ViewStub充气:

ViewStub introStub =  (ViewStub) findViewById(R.id.introHolder);
introStub.setLayoutResource(R.layout.intro_landing1);
View inflatedView = introStub.inflate();

使用第二种方法我通过执行inflatedView.getTag记录返回的View(inflatedView),并返回intro_landing1 RelativeLayout的标签“RelativeLayoutIntroViewTag”,以便实际返回视图,但我没有看到它。

为了确保我在视图树层次结构中正确定位ViewStub,我使用Activity.xml中的<include/>标记而不是ViewStub,如下所示:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent">

   ...

   <!-- <ViewStub
       android:id="@+id/introHolder"
       android:inflatedId="@+id/introHolder"
       android:layout="@layout/intro_landing1"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />-->

   <include layout="@layout/intro_landing1"/>

</FrameLayout>

这很有效。

为什么在能见度变化或通胀后没有显示ViewStub?

谢谢!

3 个答案:

答案 0 :(得分:2)

所以我无法重现你的问题。我将在这里分享我的裸代码,因为它适用于我的设置 我怀疑你可能在某个地方有一些额外的代码,可能会与你试图做的事情进行错误的互动。 (我试图尽可能地将其设置为问题)

activity_main.xml中

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:context="com.myexample.helloworld.MainActivity">

    <ViewStub
        android:id="@+id/myViewStub"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:inflatedId="@+id/myInflatedViewStub"
        android:visibility="gone"
        android:layout="@layout/stub"/>
</FrameLayout>

stub.xml

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

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="100dp"
        android:text="Large Text"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"/>
</RelativeLayout>

MainActivity.java

public class MainActivity
        extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ((ViewStub) findViewById(R.id.myViewStub)).setVisibility(View.VISIBLE);
    }
}

P.S。我通常链接到一个演示项目,但在这种情况下代码不多,如果有人看到答案,它将来不会依赖于链接。希望它有所帮助

答案 1 :(得分:0)

这可以帮助您理解ViewStub行为 2. ViewStub无法在不设置布局资源和通胀的情况下更改可见性。因此,一旦设置了布局资源,您就可以inflatesetVisibility(View.VISIBLE);
3.调用方法inflate()时,ViewStub将从其父项中删除,并替换为右视图(布局的根视图)。
更多How to use View Stub in android

答案 2 :(得分:0)

事实证明我的实施是正确的,但这是发生的事情:

在启动我的应用程序时打开了教程视图(膨胀了ViewStub)并将之前启动的内容写入了共享prefrences(SP),并在重新启动活动后立即执行(再次运行onCreated)但这次教程视图没有膨胀因为if sentense失败了。

只有在第一次打开应用程序时才会发生这种情况,因此无法明确表示这是问题

我仍然不知道为什么它会在第一次打开应用程序时重新启动活动,但我相信它是由于内存问题。

只有在用户按照步骤操作后,我才通过将教程通胀标记写入SP来解决它。

由于@ Alex.F答案几乎是正确答案,我会将其标记为芒果。