先说一下这个问题产生的背景
Activity A中有四个fragment,分别是 a b c d,默认显示的是fragment a。在开发过程中,fragment d中需要和外部Activity进行跳转,将这个外部Activity命名为B吧...
我需要从d中跳转到B中,完成一些设置,然后再从B中的返回按钮回到d。但是使用startActivity()方法的结果是:可以实现从d到B的跳转,但是从B跳到d出现了问题。
网上搜索了一下相关问题的解决方案(博文)
方案一:
要考虑fragment的复用,必须要降低fragment和activity之间的耦合,就是说fragment不应该直接影响到其他的fragment,也不应该直接和其他的外部activity进行联系。fragment所在的activity应当起到一个中间桥梁的作用,负责和外部的activity联系。这位博主给出了两种解决方法。下面是他的代码
FragmentOne
package com.zhy.zhy_fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class FragmentOne extends Fragment implements OnClickListener
{
private Button mBtn;
/**
* 设置按钮点击的回调
* @author zhy
*
*/
public interface FOneBtnClickListener
{
void onFOneBtnClick();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_one, container, false);
mBtn = (Button) view.findViewById(R.id.id_fragment_one_btn);
mBtn.setOnClickListener(this);
return view;
}
/**
* 交给宿主Activity处理,如果它希望处理
*/
@Override
public void onClick(View v)
{
if (getActivity() instanceof FOneBtnClickListener)
{
((FOneBtnClickListener) getActivity()).onFOneBtnClick();
}
}
}
FragmentTwo
package com.zhy.zhy_fragments;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
public class FragmentTwo extends Fragment implements OnClickListener
{
private Button mBtn ;
private FTwoBtnClickListener fTwoBtnClickListener ;
public interface FTwoBtnClickListener
{
void onFTwoBtnClick();
}
//设置回调接口
public void setfTwoBtnClickListener(FTwoBtnClickListener fTwoBtnClickListener)
{
this.fTwoBtnClickListener = fTwoBtnClickListener;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState)
{
View view = inflater.inflate(R.layout.fragment_two, container, false);
mBtn = (Button) view.findViewById(R.id.id_fragment_two_btn);
mBtn.setOnClickListener(this);
return view ;
}
@Override
public void onClick(View v)
{
if(fTwoBtnClickListener != null)
{
fTwoBtnClickListener.onFTwoBtnClick();
}
}
}
下面是Activity的
package com.zhy.zhy_fragments;
import android.app.Activity;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.view.Window;
import com.zhy.zhy_fragments.FragmentOne.FOneBtnClickListener;
import com.zhy.zhy_fragments.FragmentTwo.FTwoBtnClickListener;
public class MainActivity extends Activity implements FOneBtnClickListener,
FTwoBtnClickListener
{
private FragmentOne mFOne;
private FragmentTwo mFTwo;
private FragmentThree mFThree;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
mFOne = new FragmentOne();
FragmentManager fm = getFragmentManager();
FragmentTransaction tx = fm.beginTransaction();
tx.add(R.id.id_content, mFOne, "ONE");
tx.commit();
}
/**
* FragmentOne 按钮点击时的回调
*/
@Override
public void onFOneBtnClick()
{
if (mFTwo == null)
{
mFTwo = new FragmentTwo();
mFTwo.setfTwoBtnClickListener(this);
}
FragmentManager fm = getFragmentManager();
FragmentTransaction tx = fm.beginTransaction();
tx.replace(R.id.id_content, mFTwo, "TWO");
tx.addToBackStack(null);
tx.commit();
}
/**
* FragmentTwo 按钮点击时的回调
*/
@Override
public void onFTwoBtnClick()
{
if (mFThree == null)
{
mFThree = new FragmentThree();
}
FragmentManager fm = getFragmentManager();
FragmentTransaction tx = fm.beginTransaction();
tx.hide(mFTwo);
tx.add(R.id.id_content, mFThree, "THREE");
// tx.replace(R.id.id_content, fThree, "THREE");
tx.addToBackStack(null);
tx.commit();
}
}
附上
原文链接
方案一的做法我觉得是最清晰的,但是不适合我现在做的项目,因为我负责的模块不包括我写的fragment所在的activity,我不能修改那个activity...所以这个方案被pass
方案二:
和方案一类似,利用intent附加参数的方式,在fragment所在的activity中判断一下intent的附加参数,从而设置显示哪个fragment,这个比方案一要简单明了一些。大概思路如下
你可以在你startactivity的地方,对intent加入一个参数,例如,intert.putExtra("fragid",1);然后再你的fragment的主activity中的oncreate或者Onresume函数中获得这个id,例如int id = intert.getIntegerExtra("fragid",-1);然后根据这个id跳转即可
if(id > 0) {
if(id == 目标id) myfragment.setvisible(true);
}
用类似方法即可
比较简单,但是也不适用我的情况,理由同方案一。
方案三:
我查了一下Fragment和Acitvity的生命周期,没啥头绪。突然看到了startActivityForResult()这个方法,结合其他的关键字一搜索,还真找到了相关的东西,下面是原文。
最近在一个项目中,遇到了一种情况,即fragment中在开启一个新的activity的时候调用startactivityResult()。我们都知道在执行完那个新创建的activity后,会回来执行fragment或fragment所在的activity的onResultActivity()函数。但是究竟执行谁的呢?或者先执行谁?
首先应该明确的是在fragment中,也是可以定义onResultActivity()函数。我们先来重新定义一下这个场景。activity A创建了fragment B,在fragment B中用startactivityResult()函数跳转到activity C。
首先,肯定不会执行activity C中的onResultActivity()函数。
其次,首先肯定会去执行activity A中的onResultActivity()函数,不管你在fragment B中是用的getactivity().onResultActivity(),还是直接使用onResultActivity()。
而且,如果你重写了activity A的onActivityResult方法<BR>而没有super.onActiivtyResult(),那么你在fragment B里的onActivityResult不会被调用。因为super.onActiivtyResult()里面会去找当前activity A中的fragment,并去调用fragment 的onActiivtyResult。
这个方案只需要修改我的fragment d和跳转的Activity B,不需要修改Activity A,符合我的需要~~~
记录。