FragmentTabHost、Viewpager、Fragment使用过程中白屏问题及解决

来源:互联网 发布:威迅java培训 编辑:程序博客网 时间:2024/05/17 22:07

关于FragmentTabHost的简单使用,我之前博客已经有提及了。这里不做多余介绍了。有需要的请看

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;    }

这样,就可以了。随便滑动,随便切换。回来以后,界面还在。完全没问题了

阅读全文
0 0
原创粉丝点击