FragmentTabHost、Viewpager、Fragment使用过程中白屏问题及解决
2017-12-12 15:55
701 查看
关于FragmentTabHost的简单使用,我之前博客已经有提及了。这里不做多余介绍了。有需要的请看
说明:
这里我会按照:提出需求-完成功能-出现问题-解决问题。这样的流程来展示和解决问题。请按顺序完。以便更好的理解。
如果想直接看最后的解决方法,请看最后的代码就行。
需求1:启动APP,打开主界面。主界面分3个模块:一、二、三。点击切换。
代码如下:
FragmentDemo\app\src\main\res\values\styles.xml
activity_main.xml
demo_fragment.xml
布局相关已经完成。代码中使用
Fragment_1
Fragment_2和Fragment_3同Fragment_1,引用的布局文件也一样,区别就是tv设置的文字改变一下
MainActivity
OK,需求完成了,运行一下,效果如下:
来回切换,没有任何问题。
需求二:现在,产品要改东西了。第一个界面是主界面,要做的炫一点。改成“动态”、“话题”样式。可以左右滑动切换界面。其他不变。
要切换界面,还是支持滑动。貌似唯一的选择的就是viewpager了。
注:这里有2种方法:把LayoutInflater通过inflate转成的布局放到一个集合中,然后viewpager的adapter中对应切换。第二种方法,就是写2个Fragment,放到集合中,然后viewpager的adapter中对应切换。
我这里用第二种方法,第一种,请自行尝试。我没有试过,不做任何评价。
现在,创建2个Fragment,动态和话题。
dynamic_fragment_layout.xml
topic_fragment_layout.xml
DynamicFragment 动态Fragment
TopicFragment 话题Fragment
接下来,仅仅需要修改第一个Fragment就好了。新的第一个Fragment_1源码如下
这个时候,启动APP,正常,第一个Fragment可以左右滑动,分别展示动态和话题内容,点击其他按钮,也可以跳转,但是,去了其他界面然后再点击底部的“一”按钮,回到第一个Fragment,白屏了。但是在白屏上左右滑动的时候,可以从onPageSelected中的那句打印看出来,界面确实切换了,但是就是不显示任何内容。
经过查资料,终于找到了解决方法
在第一个Fragment中添加一段代码
这样,就可以了。随便滑动,随便切换。回来以后,界面还在。完全没问题了
=========================================
以下内容请认真阅读
以上代码,在一些手机上,还是会出现白屏,复现步骤:
启动APP,打开动态或者话题界面,home键退到后台,尽可能多的打开手机上的应用(不管是系统自带的还是自己后来安装的),然后停一会,后台应该会把APP回收了,通过菜单键重新切换回APP中,发现白屏了。
解决方法:
在第一个Fragment中的viewpager初始化的时候,改成
测试手机:
http://blog.csdn.net/u014620028/article/details/51253031
说明:
这里我会按照:提出需求-完成功能-出现问题-解决问题。这样的流程来展示和解决问题。请按顺序完。以便更好的理解。
如果想直接看最后的解决方法,请看最后的代码就行。
需求1:启动APP,打开主界面。主界面分3个模块:一、二、三。点击切换。
代码如下:
FragmentDemo\app\src\main\res\values\styles.xml
<style name="FragmentTabHost_RadioGroup_Bottom_Style"> <item name="android:layout_width">0dp</item> <item name="android:layout_height">wrap_content</item> <item name="android:layout_weight">1</item> <item name="android:gravity">center</item> <item name="android:textSize">10sp</item> <item name="android:button">@null</item> <item name="android:textColor">#000000</item> <item name="android:drawableTop">@mipmap/ic_launcher</item> </style>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <LinearLayout android:id="@+id/realtabcontent" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:orientation="horizontal"> </LinearLayout> <android.support.v4.app.FragmentTabHost android:id="@android:id/tabhost" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" android:visibility="gone"> <FrameLayout android:id="@android:id/tabcontent" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:id="@+id/fragment_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="10dp"> </LinearLayout> </FrameLayout> </android.support.v4.app.FragmentTabHost> <LinearLayout android:id="@+id/main_bottom_layout" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#00000000" android:gravity="center" android:orientation="vertical"> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#DADADA"/> <RadioGroup android:id="@+id/radioGroup1" android:layout_width="match_parent" android:layout_height="80dp" android:orientation="horizontal" android:paddingLeft="10dp" android:paddingRight="10dp" android:paddingTop="5dp"> <RadioButton android:id="@+id/rb_1" style="@style/FragmentTabHost_RadioGroup_Bottom_Style" android:checked="true" android:drawableTop="@mipmap/ic_launcher" android:text="一" /> <RadioButton android:id="@+id/rb_2" style="@style/FragmentTabHost_RadioGroup_Bottom_Style" android:drawableTop="@mipmap/ic_launcher" android:text="二" /> <RadioButton android:id="@+id/rb_3" style="@style/FragmentTabHost_RadioGroup_Bottom_Style" android:drawableTop="@mipmap/ic_launcher" android:text="三" /> </RadioGroup> </LinearLayout> </LinearLayout>
demo_fragment.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <TextView android:id="@+id/fragment_tv" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:textSize="20sp" /> </LinearLayout>
布局相关已经完成。代码中使用
Fragment_1
import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; public class Fragment_1 extends Fragment { private View view; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.demo_fragment, container, false); TextView tv = view.findViewById(R.id.fragment_tv); tv.setText("第1个Fragment"); return view; } }
Fragment_2和Fragment_3同Fragment_1,引用的布局文件也一样,区别就是tv设置的文字改变一下
MainActivity
package com.chen.demo; import android.os.Bundle; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentTabHost; import android.widget.RadioGroup; import android.widget.TabHost; public class MainActivity extends FragmentActivity implements RadioGroup.OnCheckedChangeListener { private FragmentTabHost mTabHost; private RadioGroup mMainGroup; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost); mTabHost.setup(this, getSupportFragmentManager(), R.id.realtabcontent); // 设置显示的标题 TabHost.TabSpec tabSpecA = mTabHost.newTabSpec("0").setIndicator("A"); TabHost.TabSpec tabSpecB = mTabHost.newTabSpec("1").setIndicator("B"); TabHost.TabSpec tabSpecC = mTabHost.newTabSpec("2").setIndicator("C"); // 添加对象 mTabHost.addTab(tabSpecA, Fragment_1.class, null); mTabHost.addTab(tabSpecB, Fragment_2.class, null); mTabHost.addTab(tabSpecC, Fragment_3.class, null); mMainGroup = (RadioGroup) findViewById(R.id.radioGroup1); mMainGroup.setOnCheckedChangeListener(this); } @Override public void onCheckedChanged(RadioGroup group, int checkedId) { switch (checkedId) { case R.id.rb_1: mTabHost.setCurrentTabByTag("0"); break; case R.id.rb_2: mTabHost.setCurrentTabByTag("1"); break; case R.id.rb_3: mTabHost.setCurrentTabByTag("2"); break; default: break; } } }
OK,需求完成了,运行一下,效果如下:
来回切换,没有任何问题。
需求二:现在,产品要改东西了。第一个界面是主界面,要做的炫一点。改成“动态”、“话题”样式。可以左右滑动切换界面。其他不变。
要切换界面,还是支持滑动。貌似唯一的选择的就是viewpager了。
注:这里有2种方法:把LayoutInflater通过inflate转成的布局放到一个集合中,然后viewpager的adapter中对应切换。第二种方法,就是写2个Fragment,放到集合中,然后viewpager的adapter中对应切换。
我这里用第二种方法,第一种,请自行尝试。我没有试过,不做任何评价。
现在,创建2个Fragment,动态和话题。
dynamic_fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#55ff0000" android:padding="5dp" android:text="动态" android:textSize="30sp"/> </RelativeLayout>
topic_fragment_layout.xml
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerInParent="true" android:background="#5500ff00" android:padding="5dp" android:text="话题" android:textSize="30sp"/> </RelativeLayout>
DynamicFragment 动态Fragment
package com.chen.demo; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class DynamicFragment extends Fragment { private View view; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.dynamic_fragment_layout, container, false); return view; } }
TopicFragment 话题Fragment
package com.chen.demo; import android.os.Bundle; import android.support.v4.app.Fragment; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; public class TopicFragment extends Fragment { private View view; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.topic_fragment_layout, container, false); return view; } }
接下来,仅仅需要修改第一个Fragment就好了。新的第一个Fragment_1源码如下
package com.chen.demo; import android.content.Context; import android.os.Bundle; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.view.ViewPager; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import java.util.ArrayList; public class Fragment_1 extends Fragment implements ViewPager.OnPageChangeListener { private View view; private Context context; private ViewPager dynamic_topic_viewPager; private ArrayList<Fragment> fragmentList; private DynamicFragment dynamicFragment; private TopicFragment topicFragment; private DynamicTopicFragmentPagerAdapter adapter; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { view = inflater.inflate(R.layout.fragment_layout, container, false); context = getActivity(); Log.e("context==", context + ""); dynamic_topic_viewPager = view.findViewById(R.id.dynamic_topic_viewPager); fragmentList = new ArrayList<>(); dynamicFragment = new DynamicFragment(); topicFragment = new TopicFragment(); fragmentList.add(dynamicFragment); fragmentList.add(topicFragment); adapter = new DynamicTopicFragmentPagerAdapter(((FragmentActivity) context).getSupportFragmentManager(), fragmentList); //去掉滑动到边缘处,继续滑动时,出现的阴影 dynamic_topic_viewPager.setOverScrollMode(View.OVER_SCROLL_NEVER); dynamic_topic_viewPager.setAdapter(adapter); dynamic_topic_viewPager.setCurrentItem(0); dynamic_topic_viewPager.addOnPageChangeListener(this); return view; } @Override public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { } @Override public void onPageSelected(int position) { Log.e("position==", position + ""); } @Override public void onPageScrollStateChanged(int state) { } private class DynamicTopicFragmentPagerAdapter extends FragmentStatePagerAdapter { ArrayList<Fragment> list; public DynamicTopicFragmentPagerAdapter(FragmentManager fm, ArrayList<Fragment> list) { super(fm); this.list = list; } @Override public Fragment getItem(int position) { return list.get(position); } @Override public int getCount() { return list.size(); } } }
这个时候,启动APP,正常,第一个Fragment可以左右滑动,分别展示动态和话题内容,点击其他按钮,也可以跳转,但是,去了其他界面然后再点击底部的“一”按钮,回到第一个Fragment,白屏了。但是在白屏上左右滑动的时候,可以从onPageSelected中的那句打印看出来,界面确实切换了,但是就是不显示任何内容。
经过查资料,终于找到了解决方法
在第一个Fragment中添加一段代码
@Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { if (view != null) { ViewGroup parent = (ViewGroup) view.getParent(); if (parent != null) { parent.removeView(view); } return view; } view = inflater.inflate(R.layout.fragment_layout, container, false); ...... ...... return view; }
这样,就可以了。随便滑动,随便切换。回来以后,界面还在。完全没问题了
=========================================
以下内容请认真阅读
以上代码,在一些手机上,还是会出现白屏,复现步骤:
启动APP,打开动态或者话题界面,home键退到后台,尽可能多的打开手机上的应用(不管是系统自带的还是自己后来安装的),然后停一会,后台应该会把APP回收了,通过菜单键重新切换回APP中,发现白屏了。
解决方法:
在第一个Fragment中的viewpager初始化的时候,改成
adapter = new DynamicTopicFragmentPagerAdapter(getChildFragmentManager(), fragmentList);
测试手机:
华为 EVA-AL00 后台开启应用18个 小米 MI 4LTE 后台开启应用22个
相关文章推荐
- 解决android FragmentTabHost + viewpager + fragment 嵌套布局切换出现白屏什么都没有问题
- 安卓中的fragment与viewPager的使用问题的解决
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
- 使用RadioGroup+ViewPager+Fragment实现带滑动的页卡效果TabHost时遇到的问题
- 如何解决Viewpager配合Fragment使用时相邻Fragment出现相同OptionMenu的问题?
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题。
- ViewPager+Fragment使用过程中手动清除及更新Fragment遇到的问题
- Android开发ViewPager的预加载和Fragment的销毁问题,以及tabLayout+ViewPager的使用,tablayout平板适配问题解决
- FragmentViewPagerAdapter中使用FragmentTabhost 重新生成view解决办法
- 解决Fragment中使用ViewPager时,ViewPager里的Fragment错位和空白问题
- 解决 使用FragmentTabHost 和 viewpager时编译器报错 FragmentManager is already executing transactions
- 在Viewpager中的Fragment使用ContextMenu问题
- ViewPager+FragmentTabhost 解决办法
- 有关ViewPager的使用及解决Android下ViewPager和PagerAdapter中调用notifyDataSetChanged失效的问题
- 嵌套Fragment的使用及遇到The specified child already has a parent. You must call removeView()问题的解决
- 在ViewPager+Fragment体系下,使用下拉刷新控件的问题
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android使用Fragment来实现ViewPager的功能(解决切换Fragment状态不保存)以及各个Fragment之间的通信
- Android中使用ViewPager制作广告栏效果 - 解决ViewPager占满全屏页面适配问题