将arFragment(sceneForm)与现有Fragment APP集成的最佳实践

问题描述 投票:0回答:3

我们一直在努力为我们现有的APP添加AR功能几个月,但进展有限。非常高兴能从google在sceneForm和arFragment上阅读最近的开发。我们当前的APP包含三个片段,其中一个需要AR功能。

它看起来很直接,所以我们用arFragment替换了APP中的Fragment。构建成功并在运行期间停止,几乎没有调试信息。关于我们从Fragment升级到arFragment的正确步骤的任何建议?或者我在这里错过了arFragment的观点?

为了显示问题而不通过我们的长度代码(对我们有价值),我们基于Google的示例项目构建了一个虚拟项目:HelloSceneform。基本上,我们将静态片段更改为动态片段。只更改了两个文件,并添加了两个文件,这些文件随后附加。修改后的项目可以成功构建,但在开始运行时会停止。

谢谢

彼得

///////文件已修改,HelloSceneformActivity.java:

import android.support.v4.app.FragmentTransaction;

// private ArFragment arFragment;
private ItemOneFragment arFragment;
//arFragment = (ArFragment) getSupportFragmentManager().findFragmentById(R.id.ux_fragment);
arFragment =  ItemOneFragment.newInstance();

//Manually displaying the first fragment - one time only
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.frame_layout, arFragment);
transaction.commit();

///////文件已修改,activity_ux.xml:

<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"
  tools:context=".HelloSceneformActivity">

</FrameLayout>

//////文件添加了fragment_item_one.xml:

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

///////文件已添加,ItemOneragment.java:

package com.google.ar.sceneform.samples.hellosceneform;

import android.os.Bundle;    
import android.view.LayoutInflater;
import android.view.View; 
import android.view.ViewGroup;
import com.google.ar.sceneform.ux.ArFragment;

public class ItemOneFragment extends ArFragment {

  public static ItemOneFragment newInstance() {
    ItemOneFragment fragment = new ItemOneFragment();
    return fragment;
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
  }

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_item_one, container, false);
  }

}

arcore sceneform
3个回答
1
投票

在我的一个项目中,我使用了以下结构来完成ArFragment的集成。也许这会给你一些新的提示。

我有一个根布局,第一个元素是一个名为“body”的FrameLayout。

这个“body”用作占位符来切换存在于应用程序中的3 Fragment。其中一个称为“SimulationFragment”,并扩展了Sceneform的ArFragment。相应的布局由根FrameLayout和一些元素以及另一个名为“ar_frameLayout”的嵌套FrameLayout组成。

在运行时我通过直接调用super.onCreateView()改变了onCreateView for SimulationFragment的实现,它给了我ArFragment的基本视图(这个调用也从getArSceneView()。getScene()开始初始化场景。之后我将这个视图添加到我之前膨胀的模拟片段的容器视图中,然后返回它。像这样的东西:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {

    View containerView = inflater.inflate(R.layout.fragment_simulation, container, false);
    FrameLayout arCoreFrameLayout = containerView.findViewById(R.id.ar_core_frame_layout);
    // Inflate the layout for this fragment
    View view = super.onCreateView(inflater, container, savedInstanceState);


    arCoreFrameLayout.addView(view);
    return containerView;
}

0
投票

ItemOneFragment扩展了ArFragment,但重写了它的onCreateView方法以扩展自己的布局文件。我认为这就是问题所在。 ArFragment找不到它的ArSceneView和其他代码元素,只是不起作用。


0
投票

当我尝试将ArFragment动态添加到我的活动时,我也遇到了同样的问题。它正在崩溃,因为我在提交片段后立即尝试访问ArSceneView,该片段在该点似乎为null。

对我有用的解决方案是实现一个完成侦听器,当片段完成配置ARSession时,它将在Activity中提供回调。

以下是基本想法。

public class MyActivity implements MyArFragment.OnCompletionListener{

     @Override
     protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);                  
      getSupportFragmentManager().beginTransaction().add(R.id.fragment_holder,  new 
        MyArFragment(), "my_arfragment").commit();
     }

     @Override
     public void onComplete() {
       ArFragment arFragment = (ArFragment) getSupportFragmentManager().findFragmentByTag("my_arfragment");
       ArSceneView view = arFragment.getArSceneView();
       Scene scene = view.getScene();
       scene.addOnUpdateListener(this::onUpdateFrame);
     }
}

片段:

public class MyFragment extends ArFragment{
  public static interface OnCompleteListener {
        public abstract void onComplete();
  }

  private OnCompleteListener mListener;

   @Override
   public void onAttach(Context context) {
      super.onAttach(context);
      try {
         this.mListener = (OnCompleteListener)context;
      }
      catch (final ClassCastException e) {
         throw new ClassCastException(context.toString() + " must implement 
          OnCompleteListener");
      }
   }


   @Override
   protected Config getSessionConfiguration(Session session) {
      //Update session config...
      mListener.onComplete();
      return config;
   }

}
© www.soinside.com 2019 - 2024. All rights reserved.