【问题标题】:Android Fragment onCreateView with AsyncLayoutInflater带有 AsyncLayoutInflater 的 Android 片段 onCreateView
【发布时间】:2021-04-27 17:17:23
【问题描述】:

在发现我的onCreateView 花了将近一秒钟的时间执行inflater.inflate(...) 方法后,我搜索了一下,发现了一个新的类,AsyncLayoutInflater

我试图在我的片段中实现这个构造函数,但我不知道如何正确实现它,因为它总是导致一个空的空白视图。

我认为我的问题是如何膨胀我的片段,并从onCreateView 返回一个空视图(super 结果)。

这是有效的“正常”版本:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_intervento_luogo, container, false);
    //do my stuffs
    return view;
}

这不会显示一个空视图:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    AsyncLayoutInflater asyncLayoutInflater = new AsyncLayoutInflater(getContext());
    asyncLayoutInflater.inflate(R.layout.fragment_intervento_luogo, container, new AsyncLayoutInflater.OnInflateFinishedListener() {
        @Override
        public void onInflateFinished(@NonNull View view, int resid, @Nullable ViewGroup parent) {
            // do my stuffs
        }
    });
    return super.onCreateView(inflater, container, savedInstanceState);
}

我也尝试将这个异步充气器放在 onResume、onViewCreated 和 onCreate 中,但没有人工作。

我应该如何正确地实现它?我不敢相信没有办法跳过 onCreateView 内部的通货膨胀,异步进行。

谢谢大家

【问题讨论】:

    标签: android android-fragments


    【解决方案1】:

    您可以做的是创建一个带有 FrameLayout 和 ProgressBar 的 loading_view.xml,以便在加载其他布局时显示它:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <ProgressBar
            android:id="@+id/progressBar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
    </FrameLayout>
    

    现在您要异步加载另一个布局并将其附加到 loading_view。您还希望在加载布局后隐藏 ProgressBar。

       override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                                  savedInstanceState: Bundle?): View? {
            super.onCreateView(inflater, container, savedInstanceState)
    
            // inflate loading view
            val final_view = inflater.inflate(R.layout.loading_view, container, false)
            // get progressbar
            var progressBar = final_view.findViewById<ProgressBar>(R.id.progressBar)
            // initialize async layout inflater
            val asyncLayoutInflater = context?.let { AsyncLayoutInflater(it) }
            // inflate other layout
            asyncLayoutInflater?.inflate(R.layout.fragment_layout, null) { view, resid, parent ->
                // when layout loaded show...
                (final_view as? ViewGroup)?.addView(view) // add view to already inflated view
            }
    
            return final_view
        }
    

    【讨论】:

      【解决方案2】:

      在 onCreateView(...) 中创建并返回片段的布局。目前您返回 super.onCreateView(inflater, container, savedInstanceState);所以它是空白的,当你的 AsyncLayoutInflater 完成时,它不会影响你的片段布局。

      当您的布局膨胀时 - 将其添加到您的 ViewGroup 中:

      @Override
      public View onCreateView(LayoutInflater inflater, ViewGroup container,
                               Bundle savedInstanceState) {
          AsyncLayoutInflater asyncLayoutInflater = new AsyncLayoutInflater(getContext());
          asyncLayoutInflater.inflate(R.layout.fragment_intervento_luogo, container, new AsyncLayoutInflater.OnInflateFinishedListener() {
              @Override
              public void onInflateFinished(@NonNull View view, int resid, @Nullable ViewGroup parent) {
                  parent.addView(view);
                  onViewCreated(view, savedInstanceState)
              }
          });
          return super.onCreateView(inflater, container, savedInstanceState);
      }
      

      并添加 onViewCreated 以通知系统创建了什么布局。

      这样的代码对我有用:

      override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
          val asyncLayoutInflater = AsyncLayoutInflater(context!!)
          asyncLayoutInflater.inflate(R.layout.fragment_characters, container) { view, resid, parent ->
              binding = FragmentCharactersBinding.bind(view)
              binding.vm = vm
              container?.addView(binding.root)
              onViewCreated(binding.root, savedInstanceState)
          }
      
          return super.onCreateView(inflater, container, savedInstanceState)
      }
      

      【讨论】:

      • 感谢您的回复!我试过了,但不幸的是它仍然显示空白页
      • 今天我尝试在我的测试项目中重现您的问题,并面临与您相同的问题。我找到了创建的视图,添加到容器中,但未调用 onViewCreated,因此没有初始化与片段相关的数据。我在 asyncLayoutInflater 的末尾添加了 onViewCreated 以通知系统有关创建的视图。我添加上面的代码。请检查
      • 得说,如果你的上下文为空,这将抛出一个空指针。考虑使用 context?.let { val al = AsyncLayoutInflater(it) }
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      • 2016-06-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多