如何保持应用程序片段的状态 [英] How to maintain fragment's state in the application
问题描述
如何保持片段的状态时,它显示在FragmentTabHost?
由于该<一href="http://www.betteropts.com/fragmenttabhost-tutorial-using-fragment-as-tab-content-and-keep-navigation-history-for-each-tab/"相对=nofollow>教程,我能够实施 FragmentTabHost
在我的应用程序。
我的目的是创建一个应用程序,其主要活动包含了某些选项卡(其中粘在上面整个应用程序)。点击每个选项卡打开选项卡下面的一个新片段。
问题是,当我点击选项卡上做一些事情,然后去将打开一个新的片段花药选项卡,然后回来到第一个标签 - 我的变化在这里是不能维持
流量:
我真的需要实现这个逻辑。如果我的做法是错误的,请建议替代。
感谢
code:
主要活动
公共类FagTabHostMain扩展FragmentActivity {
FragmentTabHost mTabHost;
@覆盖
保护无效的onCreate(包savedInstanceState){
super.onCreate(savedInstanceState);
的setContentView(R.layout.activity_fag_tab_host_main);
mTabHost =(FragmentTabHost)findViewById(android.R.id.tabhost);
mTabHost.setup(这一点,getSupportFragmentManager(),R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec(音频)。setIndicator(音频),
AudioContainerFragmentClass.class,NULL);
mTabHost.addTab(mTabHost.newTabSpec(视频)。setIndicator(视频),
VideoContainerFragmentClass.class,NULL);
}
@覆盖
公共无效onBack pressed(){
布尔isPopFragment = FALSE;
串currentTabTag = mTabHost.getCurrentTabTag();
如果(currentTabTag.equals(声音)){
isPopFragment =((AudioContainerFragmentClass)getSupportFragmentManager()
.findFragmentByTag(音频))popFragment()。
}否则,如果(currentTabTag.equals(视频)){
isPopFragment =((VideoContainerFragmentClass)getSupportFragmentManager()
.findFragmentByTag(视频))popFragment()。
}
//完成时,没有更多的碎片在后面堆栈显示
完();
}
}
主要业务布局
&LT; LinearLayout中的xmlns:机器人=http://schemas.android.com/apk/res/android
机器人:layout_width =match_parent
机器人:layout_height =match_parent
机器人:方向=垂直&GT;
&LT; android.support.v4.app.FragmentTabHost
机器人:ID =@机器人:ID / tabhost
机器人:layout_width =match_parent
机器人:layout_height =match_parent&GT;
&LT; - !不使用本之一,现在 - &GT;
&LT;的FrameLayout
机器人:ID =@机器人:ID / tabcontent
机器人:layout_width =0dip
机器人:layout_height =0dip
机器人:layout_weight =0/&GT;
&LT; /android.support.v4.app.FragmentTabHost>
&LT;的FrameLayout
机器人:ID =@ + ID / realtabcontent
机器人:layout_width =match_parent
机器人:layout_height =0dip
机器人:layout_weight =1/&GT;
&LT; / LinearLayout中&GT;
AudioContainerFragmentClass
公共类AudioContainerFragmentClass扩展片段工具
OnClickListener {
最终的字符串变量=AudioContainerFragmentClass;
私人布尔mIsViewInitiated = FALSE;
私人布尔addToBackStack = TRUE;
私人按钮bNextFragment;
私人的LinearLayout LinearLayout中;
@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
捆绑savedInstanceState){
尝试 {
Log.e(AudioContainerFragmentClass,onCreateView称为);
的LinearLayout =(的LinearLayout)inflater.inflate(
R.layout.audio_fragment_container,集装箱,假);
}赶上(例外五){
printException(e.toString());
}
返回的LinearLayout;
}
@覆盖
公共无效onActivityCreated(包savedInstanceState){
尝试 {
super.onActivityCreated(savedInstanceState);
Log.e(AudioContainerFragmentClass,onActivityCreated称为);
如果(!mIsViewInitiated){
mIsViewInitiated = TRUE;
initView();
}
}赶上(例外五){
printException(e.toString());
}
}
私人无效initView(){
尝试 {
Log.e(AudioContainerFragmentClass,initView称为);
bNextFragment =(按钮)的LinearLayout
.findViewById(R.id.bNextFragment);
bNextFragment.setOnClickListener(本);
replaceFragment(新AudioFragment(),FALSE);
}赶上(例外五){
printException(e.toString());
}
}
私人无效replaceFragment(AudioFragment audioFragment,布尔B){
尝试 {
FragmentTransaction英尺= getChildFragmentManager()
.beginTransaction();
如果(addToBackStack){
ft.addToBackStack(空);
}
ft.replace(R.id.audio_sub_fragment,audioFragment);
ft.commit();
getChildFragmentManager()executePendingTransactions()。
}赶上(例外五){
printException(e.toString());
}
}
//从FagTabHostMain活动调用
公共布尔popFragment(){
布尔isPop = FALSE;
尝试 {
Log.e(AudioContainerFragmentClass,popFragment称为);
如果(getChildFragmentManager()getBackStackEntryCount()&GT; 0){
isPop = TRUE;
getChildFragmentManager()popBackStack()。
}
}赶上(例外五){
printException(e.toString());
}
返回isPop;
}
@覆盖
公共无效的onClick(查看为arg0){
TextView的电视=(TextView中)getActivity()findViewById(R.id.tvaudioTitle)。
tv.setText(文本改变);
}
私人无效printException(字符串字符串){
Log.e(__ ERRORR__,字符串);
}
}
AudioFragment
公共类AudioFragment扩展片段{
@覆盖
公共查看onCreateView(LayoutInflater充气,容器的ViewGroup,
捆绑savedInstanceState){
查看查看= inflater.inflate(R.layout.audio_sub_fragment,集装箱,
假);
返回查看;
}
}
有同样的事情在我的应用程序。
您将需要复制<一href="http://grep$c$c.com/file/repository.grep$c$c.com/java/ext/com.google.android/android/4.2.2_r1/android/support/v4/app/FragmentTabHost.java">FragmentTabHost您的项目,请将code使用新的自定义 FragmentTabHost
键,然后更改 doTabChanged $ C $的code c>来实现如下:
私人FragmentTransaction doTabChanged(字符串tabId,FragmentTransaction英尺){
TabInfo newTab = NULL;
的for(int i = 0; I&LT; mTabs.size();我++){
TabInfo标签= mTabs.get(我);
如果(tab.tag.equals(tabId)){
newTab =标签;
}
}
如果(newTab == NULL){
抛出新IllegalStateException异常(无标签闻名的标记+ tabId);
}
如果(mLastTab!= newTab){
如果(英尺== NULL){
英尺= mFragmentManager.beginTransaction();
}
如果(mLastTab!= NULL){
如果(mLastTab.fragment!= NULL){
ft.hide(mLastTab.fragment);
}
}
如果(newTab!= NULL){
如果(newTab.fragment == NULL){
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(),newTab.args);
ft.add(mContainerId,newTab.fragment,newTab.tag);
findViewById(mContainerId).setContentDescription(DEBUG片段添加到这个容器中。);
} 其他 {
如果(newTab.fragment.isHidden()){
ft.show(newTab.fragment);
}
其他{
ft.attach(newTab.fragment);
}
}
}
米previousTab = mLastTab;
mLastTab = newTab;
}
返回英尺;
}
有人认为,这种变化是不是 deattach /附加
片段,我们正在做的隐藏/显示
How to maintain fragment's state when it is shown within FragmentTabHost?
Thanks to this tutorial, I'm able to implement FragmentTabHost
in my application.
My intention is to create an app whose main activity contains some tabs (which sticks on the top throughout the app). Clicking each tab opens a new fragment below the tabs.
Issue is when I click on a tab do something, then go to anther tab which opens a new fragment, then comes back to first tab - my changes here are not maintained.
Flow:
I really need to implement this logic. If my approach is wrong, please suggest alternative.
Thanks
Code:
Main Activity
public class FagTabHostMain extends FragmentActivity {
FragmentTabHost mTabHost;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_fag_tab_host_main);
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
mTabHost.addTab(mTabHost.newTabSpec("audio").setIndicator("Audio"),
AudioContainerFragmentClass.class, null);
mTabHost.addTab(mTabHost.newTabSpec("video").setIndicator("Video"),
VideoContainerFragmentClass.class, null);
}
@Override
public void onBackPressed() {
boolean isPopFragment = false;
String currentTabTag = mTabHost.getCurrentTabTag();
if (currentTabTag.equals("audio")) {
isPopFragment = ((AudioContainerFragmentClass) getSupportFragmentManager()
.findFragmentByTag("audio")).popFragment();
} else if (currentTabTag.equals("video")) {
isPopFragment = ((VideoContainerFragmentClass) getSupportFragmentManager()
.findFragmentByTag("video")).popFragment();
}
// Finish when no more fragments to show in back stack
finish();
}
}
Main activity layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<android.support.v4.app.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Not Using this one right now -->
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dip"
android:layout_height="0dip"
android:layout_weight="0" />
</android.support.v4.app.FragmentTabHost>
<FrameLayout
android:id="@+id/realtabcontent"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" />
</LinearLayout>
AudioContainerFragmentClass
public class AudioContainerFragmentClass extends Fragment implements
OnClickListener {
final String TAG = "AudioContainerFragmentClass";
private Boolean mIsViewInitiated = false;
private boolean addToBackStack = true;
private Button bNextFragment;
private LinearLayout linearLayout;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
try {
Log.e("AudioContainerFragmentClass", "onCreateView called");
linearLayout = (LinearLayout) inflater.inflate(
R.layout.audio_fragment_container, container, false);
} catch (Exception e) {
printException(e.toString());
}
return linearLayout;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
try {
super.onActivityCreated(savedInstanceState);
Log.e("AudioContainerFragmentClass", "onActivityCreated called");
if (!mIsViewInitiated) {
mIsViewInitiated = true;
initView();
}
} catch (Exception e) {
printException(e.toString());
}
}
private void initView() {
try {
Log.e("AudioContainerFragmentClass", "initView called");
bNextFragment = (Button) linearLayout
.findViewById(R.id.bNextFragment);
bNextFragment.setOnClickListener(this);
replaceFragment(new AudioFragment(), false);
} catch (Exception e) {
printException(e.toString());
}
}
private void replaceFragment(AudioFragment audioFragment, boolean b) {
try {
FragmentTransaction ft = getChildFragmentManager()
.beginTransaction();
if (addToBackStack) {
ft.addToBackStack(null);
}
ft.replace(R.id.audio_sub_fragment, audioFragment);
ft.commit();
getChildFragmentManager().executePendingTransactions();
} catch (Exception e) {
printException(e.toString());
}
}
// Called from FagTabHostMain Activity
public boolean popFragment() {
boolean isPop = false;
try {
Log.e("AudioContainerFragmentClass", "popFragment called");
if (getChildFragmentManager().getBackStackEntryCount() > 0) {
isPop = true;
getChildFragmentManager().popBackStack();
}
} catch (Exception e) {
printException(e.toString());
}
return isPop;
}
@Override
public void onClick(View arg0) {
TextView tv = (TextView)getActivity().findViewById(R.id.tvaudioTitle);
tv.setText("Text changed");
}
private void printException(String string) {
Log.e("__ERRORR__", string);
}
}
AudioFragment
public class AudioFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.audio_sub_fragment, container,
false);
return view;
}
}
Had the same thing in my app.
You will need to copy the FragmentTabHost to your project, point your code to use the new custom FragmentTabHost
and then change the code of doTabChanged
to following implementation:
private FragmentTransaction doTabChanged(String tabId, FragmentTransaction ft) {
TabInfo newTab = null;
for (int i=0; i<mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
if (tab.tag.equals(tabId)) {
newTab = tab;
}
}
if (newTab == null) {
throw new IllegalStateException("No tab known for tag " + tabId);
}
if (mLastTab != newTab) {
if (ft == null) {
ft = mFragmentManager.beginTransaction();
}
if (mLastTab != null) {
if (mLastTab.fragment != null) {
ft.hide(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
findViewById(mContainerId).setContentDescription("DEBUG. add fragment to this container");
} else {
if (newTab.fragment.isHidden()){
ft.show(newTab.fragment);
}
else{
ft.attach(newTab.fragment);
}
}
}
mPreviousTab = mLastTab;
mLastTab = newTab;
}
return ft;
}
The change that was made is that instead of deattach/attach
the fragment, we are doing hide/show
这篇关于如何保持应用程序片段的状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!