Android <include /> работает, а ViewStub - нет, почему?
Я использую ViewStub внутри FrameLayout, чтобы я мог раздувать его с помощью учебника, когда приложение открывается в первый раз.
Моя активность.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).
1-й подход - настройка видимости:
if(!previouslyStarted){
((ViewStub) findViewById(R.id.introHolder)).setVisibility(View.VISIBLE);
}
2-й подход - раздувание ViewStub:
ViewStub introStub = (ViewStub) findViewById(R.id.introHolder);
introStub.setLayoutResource(R.layout.intro_landing1);
View inflatedView = introStub.inflate();
При втором подходе я регистрировал возвращенное представление (inflatedView), выполняя inflatedView.getTag, и он возвращал тег RelativeLayout intro_landing1 "RelativeLayoutIntroViewTag", поэтому представление фактически возвращается, но я его не вижу.
Чтобы убедиться, что я правильно разместил ViewStub в иерархии дерева представлений, я использовал <include/>
тег в файле Activity.xml вместо 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 ответа
Поэтому я не смог воспроизвести вашу проблему. Здесь я поделюсь своим голым кодом, как он работает на моей установке.
Я подозреваю, что у вас может быть где-то дополнительный код, который может неправильно взаимодействовать с тем, что вы пытались сделать. (Я попытался установить это как можно ближе к вопросу)
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);
}
}
PS Обычно я делаю ссылки на демонстрационный проект, но в этом случае кода не так много, и в будущем он не будет зависеть от ссылки, если кто-нибудь когда-нибудь увидит ответ. Надеюсь, поможет
Оказывается, моя реализация была правильной, но вот что произошло:
При загрузке мое приложение открыло представление учебника (накачало ViewStub) и записало ранее запущенные в общие предпочтения (SP) и сразу после этого перезапустило действие (снова запустил onCreated), но на этот раз представление учебника не было раздутым, потому что если приговор провалился.
Это происходит только в первый раз, когда приложение открывается, и поэтому было неясно, что это была проблема
Я до сих пор не знаю, почему он запускает работу при первом открытии приложения, но я верю, что это связано с проблемой памяти.
Я решил это, написав флаг инфляции учебника в SP только после того, как пользователи выполнили шаги.
Поскольку ответ @Alex.F был практически правильным, я отмечу его как awnser.
Пусть это поможет вам понять ViewStub
поведение
2. ViewStub
нельзя изменить видимость без настройки макета ресурса и инфляции. поэтому, как только вы установите ресурс макета, вы можете inflate
или же setVisibility(View.VISIBLE);
3. Когда метод inflate()
вызывается ViewStub
удаляется из его родителя и заменяется правым представлением (корневым представлением вашего макета).
Подробнее о том, как использовать View Stub в Android