"你不能替换静态定义的布局文件中的一个片段。您仅可替换你动态地添加通过 FragmentTransaction 的片段"
请参阅
Android: 不能替换另一个的一个片段
如何显示一个选项卡内的一个新片段?
这里是解决方案。
在 home_activity.xml,你应该离开空你 tabcontent。
<FrameLayout
android:id="@+id/tabcontent"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
您的 Home_Activity
private FragmentTabHost mHost
public void changeFragment() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction()
EntertainmentFragment enFragment = new EntertainmentFragment()
ft.replace(R.id.tabcontent, enFragment)
ft.commit()
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
mHost = (FragmentTabHost) findViewById(android.R.id.tabhost)
mHost.setup(this, getSupportFragmentManager(), R.id.tabcontent)
mHost.addTab(mHost.newTabSpec("School")
.setIndicator("School"), SchoolFragment.class, null)
mHost.addTab(mHost.newTabSpec("Sport")
.setIndicator("Sport"), SportsFragment.class, null)
}
在您的 onIemClick (Sports_Fragment),添加这
MainActivity mainAct = (MainActivity)getActivity()
mainAct.changeFragment()
我充分的项目,基于您的代码,是在这里。
我还没有机会真的检查 TabHost 为什么不工作时我测试您的代码。但FragmentTabHost的作品对我很好。
编辑: 若要修复重叠问题,您可以设置 OnTabChangeListener:
mHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
@Override
public void onTabChanged(String tabId) {
// TODO Auto-generated method stub
if (tabId.equalsIgnoreCase("School")) {
Log.v(TAG, "school")
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction()
schoolFrag = new SchoolFragment()
ft.replace(R.id.tabcontent, schoolFrag)
ft.commit()
}
if (tabId.equalsIgnoreCase("Sport")) {
Log.v(TAG, "Sport")
FragmentTransaction ft = getSupportFragmentManager()
.beginTransaction()
SportsFragment sportFrag = new SportsFragment()
ft.replace(R.id.tabcontent, sportFrag)
ft.commit()
}
}
})
关于 backpress,您可以尝试
ft.addToBackStack(null)
做了一个关于viewPager动态添加fragmeng以及删除fragment的功能,但是奇怪的是,移除fragment的时候,调用了notifyDataSetChanged()方法,但是fragment并没有更新成新的,后来打印日志发现根本没有调用适配器中的instantiateItem()方法,而这个问题就需要你重写getItemPosition()方法,并且返回值POSITION_NONE,之后发现虽然调用了instaniateItem()方法,可是仍然没有展示新的fragment,在于adapter回去缓存的fragment,所以你需要重写getItemId()这个方法。其实还有一种省事的方法就是使用FragmentPagerStateAdapter来适配,但是我就是不写。http://www.jianshu.com/p/d36a1e5bf246
本文出自zhh_happig的博客http://www.jianshu.com/u/d82bd37b1d29,谢谢
Android support v4这个包是为Android 1.6(API版本为4)及以上的版本设计的(从android-support-v4-24.2.0开始,V4包支持的最低版本是Android 2.3即API Level 9),该支持库可以让在旧版本 Android 平台上运行的应用,支持新版本平台推出的功能。
举个Fragment的例子说明一下,假设我们某个应用支持的最低版本是:minSdkVersion=8,但是应用中用到了android.app.Fragment类,而Fragment类是在Android 11的时候才开始加入的,那么当我们的应用运行在Android 11以下的手机就会出现问题,那么如何能让Fragment在低于11的手机上也能正常使用呢?我们需要引入android.support.v4包中android.support.v4.app.Fragment来替换掉原来用到的android.app.Fragment类,android.support.v4.app.Fragment和android.app.Fragment有一样的效果,但是它能在低于11的手机上正常使用,这就是support支持库提供的功能,能兼容低版本的Android平台。
android.support.v4包支持的最低版本是Android 4,v4的意思是就是支持最低版本是4,如果你要使用Fragment,最低版本只兼容到4了。
拿上面的例子来说:应用中的minSdkVersion=8,为了兼容低版本的手机,引入了android.support.v4包中android.support.v4.app.Fragment。当应用在不同版本手机运行,android.support.v4是怎样工作的呢?
a.当运行在Android版本是4-10手机上,手机Android框架没有提供Fragmeng提供的功能:则android.support.v4支持库会调用自身android.support.v4.app.Fragment;
b.当运行在Android版本是11及以上的手机上,手机Android框架提供了Fragmeng提供的功能:则android.support.v4支持库会调用手机Android框架android.app.Fragment。
也就是说,如果应用调用其中一个支持类的方法,则支持库的行为将取决于运行应用的手机的Android 版本。如果手机Android框架提供必要的功能,则支持库将通过调用手机Android框架执行任务。如果应用在旧版本的 Android 上运行,且手机Android框架未提供所需的功能,则支持库自身可能会尝试提供相应的功能或什么都不做。无论是哪一种情形,应用通常都不需要检查其在哪一版本的 Android 上运行,而是通过支持库执行检查并选择适当的行为。
还有一些android.support.v4中类,比如ViewPager等,不管在Android那个版本,都没有这个类,所以要用到ViewPager,就必须引用android.support.v4包了。
注:随着系统的迭代Android 1.6的设备已经很少了,官方在Support Library 24.2.0版本的时候移除了对Android 2.2(API Level 8)及以下版本的支持,所以从Android Support v4 24.2.0开始,V4包支持的最低版本是Android 2.3即API Level 9
我们可以发现android-support-v4后面都跟着版本号:比如android-support-v4-23.0.0 (对应Android Api Level 23),如果不清楚这个版本号,在开发中也会带来很多问题。
最常见的问题就是已经引入了android-support-v4包,但是某个类或者某个方法却找不到,这个原因应该就是版本号不对了。
比如我们在targetSdkVersion <23的时,用到android.support.v4.content.PermissionChecker这个类来检查权限 ,但是引入了android-support-v4-22.2.1.jar后,却找不到PermissionChecker类,原因就是PermissionChecker是23.0.0版本才加入的,所以引入android-support-v4-23.0.0.jar就行了。
遇到这种问题,可以去 Android官方中文网站 找到对应的类或方法,看看它们加入的版本:added in version,然后在引入对应的support包
注:在android-support-v4-24.2.0及之后的版本中,为了增强效率和减小APK的大小起见,Android将android-support-v4包从一个独立的依赖包拆分成v4 compat library、v4 core-utils library、v4 core-ui library、v4 media-compat library和v4 fragment library这5个包,考虑到V4的向后兼容,你在工程中依赖V4这个依赖包时默认是包含拆分后的5个包的,但为了节省APK大小,建议在开发过程中根据实际情况依赖对应的V4包,移除不必要的V4包。
v4 compat library
兼容一些 Framework API,如 Context.getDrawable() 和 View.performAccessibilityAction()等,在AS中的依赖方式如下:
compile 'com.android.support:support-compat:24.2.1'
v4 core-utils library
提供一系列核心的工具类,如 AsyncTaskLoader 和 PermissionChecker,在AS中的依赖方式如下,按自己需求选择合适版本:
compile 'com.android.support:support-core-utils:24.2.1'
core-ui library
提供一系列核心的 UI,如 ViewPager、 NestedScrollView,在AS中的依赖方式如下:
compile 'com.android.support:support-core-ui:24.2.1'
v4 media-compat library
android.media 兼容库,包括 MediaBrowser 和 MediaSession,在AS中的依赖方式如下:
compile 'com.android.support:support-media-compat:24.2.1'
v4 fragment library
跟fragment相关部分,v4 fragment library这个子库依赖了其他4个子库,所以我们一旦依赖这个库就会自动导入其他4个子库,这跟直接依赖整个support-v4效果类似,在AS中的依赖方式如下:
compile 'com.android.support:support-fragment:24.2.1'
拆包并不一定代表能够真的解决效率和减小APK的大小问题,V4包拆分后的5个子包有依赖关系。即拆包之后,要用到某个子包的API时,可能还得依赖其它的子包,这也是有坑的地方。当我们编译没有问题,运行出现Do not find class之类的错误时,一定要看看是不是子包之间的依赖关系造成的,如果是引入相应的子包。出现这个依赖问题,再加上版本可能出现问题,对于新手来说,比较棘手,建议新手全部导入。
以上文章内容,是本人工作中的总结,供大家参考,有误的地方还请指正。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)