5

我正在使用ViewStubs在我的布局中加载显示数据。因为我ButterKnife用来绑定布局组件,所以我有自定义类来保存单独的viewstub 布局的组件,例如一个这样的viewstub 如下。

 <ViewStub
      android:id="@+id/featuredContentStub"
      android:layout_width="match_parent"
      android:layout_height="wrap_content"
      android:inflatedId="@+id/featuredContent"
      android:layout="@layout/featured_content" />

处理@layout/featured_content组件的类如下:

public class FeaturedContentView {
        @BindView(R.id.art)
        ImageView art;
        @BindView(R.id.shade)
        View shade;
        @BindView(R.id.title)
        TextView featuredTitle;
        @BindView(R.id.performer)
        TextView performer;
        @BindView(R.id.featured_title)
        KerningTextView featuredText;
        @BindView(R.id.play_button)
        Button play;
        @BindView(R.id.shareText)
        TextView shareText;
        @BindView(R.id.addToFavorites)
        ImageView addToFavs;

        FeaturedContentView(View view) {
            ButterKnife.bind(this, view);
        }
    }

我像这样膨胀布局:

if (viewstub != null) {
        View view = viewstub.inflate();
        featuredContentView = new FeaturedContentView(view);
}

上述方法在我的片段中的两个不同位置调用。它第一次正确充气,但第二次引用失败java.lang.IllegalStateException: ViewStub must have a non-null ViewGroup viewParent

我该如何处理这种情况。

4

2 回答 2

6

Android 像这样膨胀 ViewStub:

  1. 最初将 ViewStub 添加到 View 层次结构中的方式与任何其他 View 相同
  2. 调用时用指定的布局替换该视图inflate

这意味着,当您的代码被第二次调用时,原始的 ViewStub 对象与 View 层次结构分离很长时间,并且已经被完整的 View 替换。

就个人而言,我认为当前形式的 ViewStub 非常不方便,尤其是在使用 ButerKnife 时。幸运的是这个类本身很简单,你总是可以创建一个自定义的类,它做同样的事情并向它添加任何需要的方法(例如isInflatedaddInflateCallback等等)。顺便说一句,Android 支持库开发人员也做了同样的事情。

于 2016-11-28T13:19:24.813 回答
0

如果查看viewstub.inflate() 函数的源代码,一旦viewstub 引用的视图被膨胀,它就会从viewstub 中删除布局引用。

因此,当第二次调用 viewstub.inflate 时,您总是会收到此错误。以下是如何防止它:

if (mViewStub.getParent() != null) {
   mViewStub.inflate();
} else {
   mViewStub.setVisibility(View.VISIBLE);
}
于 2022-02-08T19:31:50.510 回答