gpt4 book ai didi

android - 如何像 ActivityGroup 管理器 Activity 一样管理 Fragment

转载 作者:搜寻专家 更新时间:2023-11-01 08:04:01 25 4
gpt4 key购买 nike

正如我们所知,ActivityGroup 已被弃用。我正在尝试重新配置我的代码。

此代码使用 ActivityGroup :

public void lauchContentActivity(Intnet intent) {
View view = getLocationActivityManager().startActivity(
intent.getComponent().getShortClassName(),
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP))
.getDecorView();
setContentView(view);
}

所以我可以切换任何可见的 Activity ,并保存隐藏的 Activity 实例状态。

但 FragmentManager 只有一个后退堆栈,不能将 fragment 带到前面,除非按下后退按钮。

如何像ActivityGroup管理Activity一样管理Fragment?

最佳答案

我实现了 fragment 选项卡,在添加和删除 fragment 时实现和理解 fragment 层次结构对我来说是一个挑战。

作为管理 fragment 的问题,这取决于您的要求, this示例详细说明了 fragment 的层次结构以及在 HashMap 的帮助下管理 fragment 的方式。

下面的类(class)将向您解释 fragment 的行为。 (该样本中存在的类)

AppMainTabActivity.java

public class AppMainTabActivity extends FragmentActivity {
/* Your Tab host */
private TabHost mTabHost;

/* A HashMap of stacks, where we use tab identifier as keys.. */
private HashMap<String, Stack<Fragment>> mStacks;

/* Save current tabs identifier in this.. */
private String mCurrentTab;

protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.app_main_tab_fragment_layout);

/*
* Navigation stacks for each tab gets created.. tab identifier is used
* as key to get respective stack for each tab
*/
mStacks = new HashMap<String, Stack<Fragment>>();
mStacks.put(AppConstants.TAB_A, new Stack<Fragment>());
mStacks.put(AppConstants.TAB_B, new Stack<Fragment>());
mStacks.put(AppConstants.TAB_C, new Stack<Fragment>());

mTabHost = (TabHost) findViewById(android.R.id.tabhost);
mTabHost.setOnTabChangedListener(listener);
mTabHost.setup();

initializeTabs();
}

private View createTabView(final int id) {
View view = LayoutInflater.from(this).inflate(R.layout.tabs_icon, null);
ImageView imageView = (ImageView) view.findViewById(R.id.tab_icon);
imageView.setImageDrawable(getResources().getDrawable(id));
return view;
}

public void initializeTabs() {
/* Setup your tab icons and content views.. Nothing special in this.. */
TabHost.TabSpec spec = mTabHost.newTabSpec(AppConstants.TAB_A);
mTabHost.setCurrentTab(-3);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});

spec.setIndicator(createTabView(R.drawable.toolkittabicon));
mTabHost.addTab(spec);

spec = mTabHost.newTabSpec(AppConstants.TAB_B);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator(createTabView(R.drawable.followtabicon));
mTabHost.addTab(spec);

spec = mTabHost.newTabSpec(AppConstants.TAB_C);
spec.setContent(new TabHost.TabContentFactory() {
public View createTabContent(String tag) {
return findViewById(R.id.realtabcontent);
}
});
spec.setIndicator(createTabView(R.drawable.myhuddletabicion));
mTabHost.addTab(spec);
}

/* Comes here when user switch tab, or we do programmatically */
TabHost.OnTabChangeListener listener = new TabHost.OnTabChangeListener() {
public void onTabChanged(String tabId) {
/* Set current tab.. */
mCurrentTab = tabId;

if (mStacks.get(tabId).size() == 0) {
/*
* First time this tab is selected. So add first fragment of
* that tab. Dont need animation, so that argument is false. We
* are adding a new fragment which is not present in stack. So
* add to stack is true.
*/
if (tabId.equals(AppConstants.TAB_A)) {
pushFragments(tabId, new ToolKitFragment(), false, true);
} else if (tabId.equals(AppConstants.TAB_B)) {
pushFragments(tabId, new FollowFragment(), false, true);
} else if (tabId.equals(AppConstants.TAB_C)) {
pushFragments(tabId, new HuddleFragment(), false, true);
}
} else {
/*
* We are switching tabs, and target tab is already has atleast
* one fragment. No need of animation, no need of stack pushing.
* Just show the target fragment
*/
pushFragments(tabId, mStacks.get(tabId).lastElement(), false,
false);
}
}
};

/*
* Might be useful if we want to switch tab programmatically, from inside
* any of the fragment.
*/
public void setCurrentTab(int val) {
mTabHost.setCurrentTab(val);
}

/*
* To add fragment to a tab. tag -> Tab identifier fragment -> Fragment to
* show, in tab identified by tag shouldAnimate -> should animate
* transaction. false when we switch tabs, or adding first fragment to a tab
* true when when we are pushing more fragment into navigation stack.
* shouldAdd -> Should add to fragment navigation stack (mStacks.get(tag)).
* false when we are switching tabs (except for the first time) true in all
* other cases.
*/
public void pushFragments(String tag, Fragment fragment,
boolean shouldAnimate, boolean shouldAdd) {
if (shouldAdd)
mStacks.get(tag).push(fragment);
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
if (shouldAnimate)
ft.setCustomAnimations(R.anim.slide_in_right, R.anim.slide_out_left);
ft.replace(R.id.realtabcontent, fragment);
ft.commit();
}

public void popFragments() {
/*
* Select the second last fragment in current tab's stack.. which will
* be shown after the fragment transaction given below
*/
Fragment fragment = mStacks.get(mCurrentTab).elementAt(
mStacks.get(mCurrentTab).size() - 2);

/* pop current fragment from stack.. */
mStacks.get(mCurrentTab).pop();

/*
* We have the target fragment in hand.. Just show it.. Show a standard
* navigation animation
*/
FragmentManager manager = getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right);
ft.replace(R.id.realtabcontent, fragment);
ft.commit();
}

@Override
public void onBackPressed() {
if (((BaseFragment) mStacks.get(mCurrentTab).lastElement())
.onBackPressed() == false) {
Log.d("######", "on back press");
/*
* top fragment in current tab doesn't handles back press, we can do
* our thing, which is
*
* if current tab has only one fragment in stack, ie first fragment
* is showing for this tab. finish the activity else pop to previous
* fragment in stack for the same tab
*/
if (mStacks.get(mCurrentTab).size() == 1) {
super.onBackPressed(); // or call finish..
} else {
popFragments();
}
} else {
// do nothing.. fragment already handled back button press.
}
}

/*
* Imagine if you wanted to get an image selected using ImagePicker intent
* to the fragment. Ofcourse I could have created a public function in that
* fragment, and called it from the activity. But couldn't resist myself.
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mStacks.get(mCurrentTab).size() == 0) {
return;
}

/* Now current fragment on screen gets onActivityResult callback.. */
mStacks.get(mCurrentTab).lastElement()
.onActivityResult(requestCode, resultCode, data);
}
}

但如果您有子 fragment ,那么它会在返回时产生问题,这在该示例中没有处理,解决方案@您必须重写 onDetach() 方法并管理代码 fragment 下方的子 fragment 检查.

@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);

} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}

另外引用开发者网站并挖掘fragment详细信息。

关于android - 如何像 ActivityGroup 管理器 Activity 一样管理 Fragment,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16889782/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com