android与fragment交互,fragment显示unity3d视图。

这两天刚刚接触Unity3d,之前一直是做android开发,对于Unity3d的开发有专门的人才,我主要涉及在Unity3d与android的交互,经过两天是实验终于完成了下面的效果:

本来想写几篇博客,来详细说明下Unity3d导出android Project然后再进行二次开发的过程,后来发现几篇博客,过程和我的类似,对于重复的过程我就不写了,大家参考他的博客就可以了。而且,包括了Unity3d调用android脚本,这一块我暂时还没有涉及。

Unity3D游戏开发之Unity与Android交互调用研究

Unity3D游戏开发之在Android视图中嵌入Unity视图

Unity3D游戏开发之从Unity3D到Eclipse

在此,道一声博主辛苦,对于上面的三篇博客大家看完之后,肯定已经可以从Unity3d导出android project,然后再倒入Eclipse了。我们可以看到MainActivity不是继承自NativeActivity就是集成自UnityPlayerActivity(或者UnityPlayerNativeActivity),这样就会给新手一个错觉,就是要展示Unity3d的视图,就必须要集成自这几个接口,那么这个想法,是错误的,具体大家可以参考一下这个博客:

http://forum.unity3d.com/threads/using-unity-android-in-a-sub-view.98315/

这个帖子中,就是使用继承自Activity的类来展示的U3d的视图。

这样的话,之前可能存在的一个问题,如果只能继承自那几个类,那么supportV4包中的Fragment岂不是不能用了,我们都知道,android.app.Fragment只支持2.3以上的版本,而V4中可以支持到1.6,所以一般来说都推荐大家使用V4包中的Fragment。

好了,说完这个问题,我们就看上面那个效果,如果在android原生应用的话,这个是很常见也很简单的应用,我们可以不停的切换中间的Fragment。

那么换成Fragment来展示U3d,并且相互切换的话,应该怎么样书写代码呢?大家看看下面两个代码块。

/**
 * 主界面
 * @author gavin
 *
 */
public class MainActivity extends FragmentActivity implements OnClickListener {

	private Button btn1;
	private Button btn2;
	private FragmentManager fm;
	View playerView;
	private Fragment currentFragment;
	private U3dFragment u3dFragment = new U3dFragment();
	private MenuOneFragment menuOneFragment = new MenuOneFragment();
	private MenuTwoFragment menuTwoFragment = new MenuTwoFragment();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		Constants.mUnityPlayer = new UnityPlayer(this);
		int glesMode = Constants.mUnityPlayer.getSettings().getInt("gles_mode", 1);
		boolean trueColor8888 = false;
		Constants.mUnityPlayer.init(glesMode, trueColor8888);

		fm = getSupportFragmentManager();

		setContentView(R.layout.activity_main);
		initView();
		currentFragment = u3dFragment;
		changeFragment(currentFragment);

	}

	/**
	 * 初始化控件
	 */
	private void initView(){
		btn1 = (Button) findViewById(R.id.btn1);
		btn2 = (Button) findViewById(R.id.btn2);
		btn1.setOnClickListener(this);
		btn2.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch(v.getId()){
			case R.id.btn1:
				Toast.makeText(MainActivity.this, "btn1", Toast.LENGTH_SHORT).show();
				if(currentFragment instanceof U3dFragment || currentFragment instanceof MenuTwoFragment){
					currentFragment = menuOneFragment;
					changeFragment(currentFragment);
				}else{
					currentFragment = u3dFragment;
					changeFragment(currentFragment);
				}
				break;
			case R.id.btn2:
				Toast.makeText(MainActivity.this, "btn2", Toast.LENGTH_SHORT).show();
				if(currentFragment instanceof U3dFragment || currentFragment instanceof MenuOneFragment){
					currentFragment = menuTwoFragment;
					changeFragment(currentFragment);
				}else{
					currentFragment = u3dFragment;
					changeFragment(currentFragment);
				}
				break;
		}
	}

	/**
	 * 方法用来改变界面
	 */
	private void changeFragment(Fragment fragment){
		FragmentTransaction ft = fm.beginTransaction();
		ft.replace(R.id.content, fragment);
		ft.commit();
	}

	protected void onDestroy ()
	{
		Constants.mUnityPlayer.quit();
		super.onDestroy();
	}

	// onPause()/onResume() must be sent to UnityPlayer to enable pause and resource recreation on resume.
	protected void onPause()
	{
		super.onPause();
		Constants.mUnityPlayer.pause();
	}
	protected void onResume()
	{
		super.onResume();
		Constants.mUnityPlayer.resume();
	}
	public void onConfigurationChanged(Configuration newConfig)
	{
		super.onConfigurationChanged(newConfig);
		Constants.mUnityPlayer.configurationChanged(newConfig);
	}
	public void onWindowFocusChanged(boolean hasFocus)
	{
		super.onWindowFocusChanged(hasFocus);
		Constants.mUnityPlayer.windowFocusChanged(hasFocus);
	}
	public boolean dispatchKeyEvent(KeyEvent event)
	{
		if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
			return Constants.mUnityPlayer.onKeyMultiple(event.getKeyCode(), event.getRepeatCount(), event);
		return super.dispatchKeyEvent(event);
	}

}

上面是Activity的写法。

/**
 * 展示u3d的界面
 * @author gavin
 *
 */
public class U3dFragment extends Fragment {

	private Activity context;
	View playerView;
	@Override
	public void onAttach(Activity activity) {
		// TODO Auto-generated method stub
		super.onAttach(activity);
		context = activity;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		playerView = Constants.mUnityPlayer.getView();
		LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
		playerView.setLayoutParams(lp);
		if(playerView.getParent() != null){
			((ViewGroup)playerView.getParent()).removeAllViews();
		}
		return playerView;
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
//		Constants.mUnityPlayer.quit();
		super.onDestroy();
	}

	@Override
	public void onPause() {
		// TODO Auto-generated method stub
		super.onPause();
		Constants.mUnityPlayer.pause();
	}

	@Override
	public void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Constants.mUnityPlayer.resume();
	}

}

上面是展示U3d视图的Fragment的写法。

要注意的有以下几点:

1.UnityPlayer这个对象被定义为了静态变量,在MainActivity中进行初始化,在Fragment中进行使用,用来获取Unity3d的view。

2.在U3dFragment中没有在onDestroy中,调用quit()方法。

3.在U3dFragment中的onCreateView()方法中,进行了下面的处理。

((ViewGroup)playerView.getParent()).removeAllViews();

对于上面三个问题,如果不处理会相应的引发下面三个问题。

1.展示U3d视图的Fragment无法显示Unity3d的动画效果。

2.切换页面的时候会报下面的错误:

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeVideoFrameCallback:VILII

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSoftInputClosed:V

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetTouchDeltaY:VF

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetInputString:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetInputCanceled:VZ

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetExtras:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetDefaultDisplay:VI

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeResume:V

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeResize:VIIII

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRequestedAA:I

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRequested32bitDisplayBuffer:Z

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRender:Z

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeRecreateGfxState:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativePause:Z

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeKeysPressed:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeInjectEvent:ZL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeInitWWW:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeFocusChanged:VZ

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeFile:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeDone:V

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeActivityIndicatorStyle:I

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.initJni:VL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.UnitySendMessage:VLLL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetLocationStatus:VI

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeSetLocation:VFFFFDF

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeForwardEventsToDalvik:VZ

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/UnityPlayer;.nativeDeviceOrientation:VI

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodUnblockStreaming:I

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodProcess:IL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodInitJni:I

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodGetInfo:II

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodBlockStreaming:I

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lorg/fmod/FMODAudioDevice;.fmodProcessMicData:ILI

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/ReflectionHelper;.nativeProxyInvoke:LILL

10-16 13:26:44.927: D/dalvikvm(8170): Unregistering JNI method Lcom/unity3d/player/ReflectionHelper;.nativeProxyFinalize:VI

3.会报下面的错误:

Caused by: java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child‘s parent first.

现在来说,功能是实现了,但是还有很多可以改进和不明白的地方,大家可以一起讨论一下。

时间: 2024-12-19 23:48:51

android与fragment交互,fragment显示unity3d视图。的相关文章

Android开发之Fragment的替换显示

一般写程序时我们都是得到FragmentManager,然后开启一个事务,然后进行Fragment的替换,然后提交事务. //1.得到FragmentManger FragmentManager fm = getSupportFragmentManager(); // //2.开启事务 FragmentTransaction transaction = fm.beginTransaction(); // //3.替换 transaction.replace(R.id.fl_content, fr

Android Fragment 隐藏或显示时调用的生命周期方法

Fragment使用方式大体分两种: 大家要注意不同的Fragment使用方法,Fragment隐藏和显示调用的生命周期方法是不同的,以下是Fragment显示隐藏调用的方法: //判断是否展示—与ViewPager连用,进行左右切换@Overridepublic void setUserVisibleHint(boolean isVisibleToUser) {super.setUserVisibleHint(isVisibleToUser);if (isVisibleToUser)//展示}

【Android】11.4 Fragment及其生命周期

分类:C#.Android.VS2015: 创建日期:2016-02-22 一.简介 Android从3.0开始引入了fragment的概念,主要是为了支持在大屏幕上实现更为动态和灵活的UI设计,比如平板电脑等.由于平板电脑的屏幕要比手机屏幕大许多,这样就有更多的空间去组合和交换UI组件. 也许这样比喻你能更快地理解它:和WPF相比,如果将Activity的作用看作类似于WPF的Window或者Page:那么Fragments的作用就类似于WPF在Window或者Page中包含的一个或多个Fra

Android Api Component---翻译Fragment组件(一)

Fragment代表了在Activity中的一种或者一部分行为,你可以在单个的activity中连接多个fragment来构建一个多面板的UI,并且在多个activity中重复使用一个fragment,你可以把fragment想象成为activity的一个模块化片段,它有它自己的生命周期,接收它自己的输入事件,还有就是当activity运行的时候,你也能添加或者移除fragment. 一个frgment必须被嵌入在一个activit中,并且这个fragment的生命周期直接被它的主activit

Android实习札记(4)---Fragment(碎片)基本概念解析

Android实习札记(4)---Fragment(碎片)基本概念解析 转载请注明出处:coder-pig Fragment相信大家都不会陌生吧,侧滑啦,抽屉效果啦,DialogFragment啊等等,一堆地方都会 用到Fragment,对于Fragment的基本概念在前面的文章中其实已经给出的了,这里回顾一遍, 温故而知新嘛,同时结合Google官方的api进行复习! 1)什么是Fragment以及它的生命周期: 核心要点: 1)3.0版本后引入,即minSdk要大于11 2)Fragment

【Android开发】之Fragment开发1

一.Fragment简介 1.Fragment作为Activity界面的一部分组成出现: 2.可以在一个Activity中同时出现多个Fragment,并且,一个Fragment亦可在多个Activity中使用: 3.在Activity运行过程中,可以添加.移除或者替换Fragment(add().remove().replace()): 4.Fragment可以响应自己的输入事件,并且有自己的生命周期,当然,它们的生命周期直接被其所属的activity的生命周期影响. 那我们为什么要用Frag

Android Api Component---翻译Fragment组件(二)

我们接着上一篇翻译吧Android Api Component---翻译Fragment组件(一) 与activity通信 尽管一个Fragment独立于一个Activity作为一个对象被实现并且在多个activity中被使用,给定的fragment实例绑定到了包含它的那个activity中. 特别的是,这个fragment使用getActivity()可以访问activity实例并且容易的执行像在activity布局中查找一个视图的任务: View listView = getActivity

Android UI开发——使用Fragment构建灵活的桌面

当我们设计应用程序时,希望能够尽最大限度的适配各种设备,包括4寸屏.7寸屏.10寸屏等等,Android开发文档给了我们参考,而且Google  IO的app(如图二)也实现了这种思想,他们都是使用layout.layout-large里面不同的布局文件实现的.当设计应用程序,你可以在不同的布局结构中重复使用Fragment,以支持众多的屏幕尺寸,,在可用的屏幕空间上优化用户体验.例如在手持设备(如Nexus 4)上,一个屏显示一个Fragment,在更大屏(如Nexus 7)上可以使用多个Fr

Android UI编程(7)——Fragment

Fragment是Activity的界面中的一部分或一种行为.你可以把多个Fragment们组合到一个Activity中来创建一个多面界面并且可以在多个Activity中重用一个Fragment.也可以把Fragment认为模块化的一段Activity,它具有自己的生命周期,接收它自己的事件,并可以在Activity运行时被添加或删除. Fragment不能独立存在,它必须嵌入到activity中,而且Fragment的生命周期直接受所在的Activity的影响.例如:当Activity暂停时,