наилучшая практика для интеграции arFragment (sceneForm) с существующим приложением Fragment - PullRequest
0 голосов
/ 18 мая 2018

Мы работали над добавлением функций AR в наше существующее приложение в течение нескольких месяцев с ограниченным прогрессом.Очень взволнован, чтобы прочитать последние разработки от Google на sceneForm и arFragment.Наше текущее приложение состоит из трех фрагментов, и одному из них потребуются функции AR.

Он выглядит прямо для нас, поэтому мы заменили фрагмент в нашем приложении на arFragment.Сборка прошла успешно и остановлена ​​во время работы с небольшим количеством информации для отладки.Есть ли какие-либо предложения о том, как нам перейти с Fragment на 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>

////// Файл добавлен фрагмент_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);
  }

}

Ответы [ 4 ]

0 голосов
/ 15 августа 2019

Мне очень понравилось решение @kdroider, но он забыл удалить ссылку на активность в onDetach(), что может быть весьма важно.Кроме того, переименуйте код в Kotlin:

import android.content.Context
import com.google.ar.core.Config
import com.google.ar.core.Session
import com.google.ar.sceneform.ux.ArFragment

class AsyncArFragment : ArFragment() {
    private var onArReadyListener: OnArReadyListener? = null

    interface OnArReadyListener {
        fun onArReady()
    }

    override fun getSessionConfiguration(session: Session): Config {
        onArReadyListener?.onArReady()
        return super.getSessionConfiguration(session)
    }


    override fun onAttach(context: Context) {
        super.onAttach(context)
        try {
            onArReadyListener = context as OnArReadyListener
        } catch (e: ClassCastException) {
            throw ClassCastException(context.toString() + " must implement OnArReadyListener")
        }
    }

    override fun onDetach() {
        super.onDetach()
        onArReadyListener = null
    }
}

И не забудьте реализовать интерфейс OnArReadyListener.

WARNING .Замена фрагментов транзакцией

  1. AnotherFragment -> AsyncArFragment работает нормально
  2. AsyncArFragment -> AnotherFragment -> AsyncArFragment по какой-то причине не работает (вызывается onResume (), а затем сразу вызывается onDestroy ()).Если вы знаете, как это исправить, пишите в комментариях.
0 голосов
/ 25 марта 2019

В одном из моих проектов я использовал следующую структуру для интеграции ArFragment. Может быть, это даст вам несколько новых советов.

У меня есть корневой макет с первым элементом FrameLayout, который называется «body».

Это "тело" используется в качестве заполнителя для переключения трех фрагментов, которые существуют в приложении. Один из этих 3 называется «SimulationFragment» и расширяет ArFragment в Sceneform. Соответствующий макет состоит из корневого FrameLayout с некоторыми элементами и другого вложенного FrameLayout с именем "ar_frameLayout".

Во время выполнения я изменил реализацию onCreateView для SimulationFragment с помощью прямого вызова super.onCreateView (), который дает мне базовое представление 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 голосов
/ 14 мая 2019

Я испытал то же самое, когда пытался динамически добавить ArFragment в свою деятельность.Это сбой, потому что я пытался получить доступ к ArSceneView сразу после того, как я зафиксировал фрагмент, который на тот момент казался пустым.

Решение, которое работало для меня, состояло в том, чтобы реализовать прослушиватель завершения, который обеспечит обратный вызов вАктивность, когда фрагмент завершается настройкой ARSession.

Ниже приведена основная идея.

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;
   }

}
0 голосов
/ 24 мая 2018

ItemOneFragment расширяет ArFragment, но переопределяет свой метод onCreateView, чтобы раздуть собственный файл макета.Я думаю, что это проблема.ArFragment не может найти свой ArSceneView и другие элементы кода и просто не будет работать.

...