仿qq底部Tab导航

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/gdutxiaoxu/article/details/52826810

本篇博客主要实现以下效果:

  • 使用FragmentTabHost实现qq底部Tab切换
  • 使用RadioGroup和RadioButton实现仿qq底部切换
  • 使用RadioGroup和ViewPager 实现可以滑动切换的仿qq底部Tab切换
  • 解决Fragment多次实例化的几种方案
  • Fragemnt的懒加载(网上很多人称之为Fragemnt的最优加载)

效果图

老规矩,废话 不多说,先看效果图

FragmentTabHost实现qq底部Tab实践的效果图

RadioGroup和ViewPager 实现可以滑动切换的仿qq底部Tab效果图

使用FragmentTabHost实现qq底部Tab切换

第一步先看布局文件

<?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">
    <!--用来填充Fragemnt的FrayLayout-->
    <FrameLayout
        android:id="@+id/main_layout_content"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">
    </FrameLayout>
    <!--FragmentTabHost-->
    <android.support.v4.app.FragmentTabHost
        android:id="@android:id/tabhost"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#F6F6F6"
        android:paddingBottom="5dp"
        android:paddingTop="5dp">

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"/>
    </android.support.v4.app.FragmentTabHost>

</LinearLayout>

其实很简单,没什么好说的 ,就是一个vertical的LinearLayout中放置着一个FrameLayout和FragmentTabHost

接下来我们来看一下代码

public class FirstStyleActivity extends AppCompatActivity {
    FragmentTabHost mTabHost;
    private TabWidget mTabWidget;
    private List<FragmentInfo> mFragmentEntities;
    private static final String TAG = "xujun";
    private static final String tag = "tag";
    public static final String[] mTiltles = new String[]{
            "首页", "课程", "直播", "个人"
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_first_style);
        mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);

        mTabHost.setup(this, getSupportFragmentManager(), R.id.main_layout_content);
        mTabWidget = mTabHost.getTabWidget();
        //  去掉分割线
        mTabWidget.setDividerDrawable(null);
        mFragmentEntities = MainFragmentFactory.getInstance().getList();
        initListener();
        initData();


    }

    private void initData() {
        int size = mFragmentEntities.size();
        for (int i = 0; i < size; i++) {
            Log.i(TAG, "size:=" + size);
            FragmentInfo fragmentInfo = mFragmentEntities.get(i);
            String title = fragmentInfo.getTitle();
            TabHost.TabSpec tabSpec = mTabHost.newTabSpec(title).setIndicator(getTabView
                    (i));
            Bundle bundle = new Bundle();
            bundle.putString(tag, mTiltles[i]);

            mTabHost.addTab(tabSpec, fragmentInfo.getClz(), bundle);
        }
        updateTab(0);
    }

    private void initListener() {
        mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
            @Override
            public void onTabChanged(String tabId) {
                int currentTab = mTabHost.getCurrentTab();
                Log.i(TAG, "onTabChanged:currentTab:=" + currentTab);
                updateTab(currentTab);
            }
        });
    }

    private View getTabView(int i) {
        View view = View.inflate(this, R.layout.tab_layout, null);
        int currentTab = mTabHost.getCurrentTab();
        Log.i(TAG, "currentTab:=" + currentTab);
        setSingleView(view, currentTab, i);
        return view;
    }

    private void setSingleView(View view, int currentTab, int index) {
        FragmentInfo fragmentInfo = mFragmentEntities.get(index);
        int[] imagIds = fragmentInfo.getImagIds();
        int[] colors = fragmentInfo.getColors();
        TextView tv = (TextView) view.findViewById(R.id.tab_tv);
        ImageView iv = (ImageView) view.findViewById(R.id.tab_icon);
        tv.setText(fragmentInfo.getTitle());
        Resources resources = getResources();
        if (index == currentTab) {

            tv.setTextColor(resources.getColor(colors[1]));
            iv.setImageDrawable(resources.getDrawable(imagIds[1]));
        } else {
            tv.setTextColor(getResources().getColor(colors[0]));
            iv.setImageDrawable(resources.getDrawable(imagIds[0]));
        }
    }

    private void updateTab(int currentTab) {

        int childCount = mTabWidget.getChildCount();
        for (int i = 0; i < childCount; i++) {
            View view = mTabWidget.getChildTabViewAt(i);
            setSingleView(view, currentTab, i);

        }


    }
}

其实说起来也很简单,主要分为以下步骤

  • 第一步,实例化FragmentTabHost并设置相关样式
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);

mTabHost.setup(this, getSupportFragmentManager(), R.id.main_layout_content);
mTabWidget = mTabHost.getTabWidget();
//  去掉分割线
mTabWidget.setDividerDrawable(null);
  • 第二步,添加每一个TabHost
 for (int i = 0; i < size; i++) {
    Log.i(TAG, "size:=" + size);
    FragmentInfo fragmentInfo = mFragmentEntities.get(i);
    String title = fragmentInfo.getTitle();
    TabHost.TabSpec tabSpec = mTabHost.newTabSpec(title).setIndicator(getTabView
            (i));
    Bundle bundle = new Bundle();
    bundle.putString(tag, mTiltles[i]);

    mTabHost.addTab(tabSpec, fragmentInfo.getClz(), bundle);
}
  • 第三步,通过设置 监听器来实现底部tab颜色和图案样式的转换
 mTabHost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
    @Override
    public void onTabChanged(String tabId) {
        int currentTab = mTabHost.getCurrentTab();
        Log.i(TAG, "onTabChanged:currentTab:=" + currentTab);
        updateTab(currentTab);
    }
});

运行上述代码及可以看到如下效果图


使用RadioGroup和RadioButton实现仿qq底部切换

第一步 ,先看布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/activity_second_style"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
>
    <!--用来填充Fragemnt的FrayLayout-->
    <FrameLayout
        android:id="@+id/fl"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    </FrameLayout>
    <!--使用RadioGroup来实现tab的切换-->
    <RadioGroup

        android:id="@+id/rg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
    >
        <RadioButton
            android:id="@+id/rb_home"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_home"
            android:text="首页"/>

        <RadioButton
            android:id="@+id/rb_course"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_course"
            android:text="课程"/>

        <RadioButton
            android:id="@+id/rb_direct_seeding"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_direct_seeding"
            android:text="直播"/>

        <RadioButton
            android:id="@+id/rb_me"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_me"
            android:text="我的"/>

    </RadioGroup>

</LinearLayout>

其实每一个tab的选中时利用RadioGroup中RadioButton的互相排斥的特性,即每一次只能选中一个 RadioButton

至于bottom_tab的style,只不过是将相同的arr提取出来,减少布局的代码量和方便统一修改而已,平时我们在写布局代码 的时候也可以这样

<style name="bottom_tab">
    <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:text" >0dp</item>
    <item name="android:gravity" >center</item>
    <item name="android:textColor" >@drawable/sel_bottom_tab_text</item>
    <item name="android:padding" >8dp</item>
    <item name="android:button" >@null</item>
</style>

第二步,我们来看一下Activity的 代码

public class ThreeActivity extends AppCompatActivity {

    FrameLayout mFl;
    RadioGroup mRg;
    private FragmentManager mFragmentManager;

    private int position = 0;

    public static final String[] mTiltles = new String[]{
            "首页", "课程", "直播", "个人"
    };
    private List<Fragment> mFragments;
    private Fragment mCurFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_three);
        mFl = (FrameLayout) findViewById(R.id.fl);
        mRg = (RadioGroup) findViewById(R.id.rg);
        mFragments = new ArrayList<>();
        for (int i = 0; i < mTiltles.length; i++) {
            ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]);
            mFragments.add(itemFragement);
        }
        mCurFragment = mFragments.get(position);
        replaceFragment(mCurFragment);

        ((RadioButton)mRg.getChildAt(position)).setChecked(true);

        initListener();
    }

    private void initListener() {
        mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {

                RadioButton radioButton = (RadioButton) group.findViewById(checkedId);

                if (false == radioButton.isChecked()) {
                    return;
                }


                switch (checkedId) {
                    case R.id.rb_home:
                        position = 0;
                        break;

                    case R.id.rb_course:
                        position = 1;
                        break;

                    case R.id.rb_direct_seeding:
                        position = 2;
                        break;

                    case R.id.rb_me:
                        position = 3;
                        break;
                    default:
                        position = 0;
                        break;

                }
                LUtils.i("position==" + position);

                Fragment to = mFragments.get(position);
                showFragment(mCurFragment, to);
                mCurFragment = to;

            }

        });
    }

    private void showFragment(Fragment from, Fragment to) {
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction transaction = supportFragmentManager.beginTransaction();
        if (!to.isAdded()) {    // 先判断是否被add过
            transaction.hide(from).add(R.id.fl, to).commit(); // 隐藏当前的fragment,add下一个到Activity中
        } else {
            transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
        }

    }

    /**
     * 这个方法用老替换fragment
     * xujun
     * 2016/5/3 17:28.
     */

    private void replaceFragment(Fragment fragmeny) {
        FragmentManager supportFragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
        fragmentTransaction.replace(R.id.fl, fragmeny).commit();
    }

}

思路解析

  • 实例化各个控件,这里代码就不贴出来了
  • 初始化 Fragemnt 和选中各个tab
 mFragments = new ArrayList<>();
for (int i = 0; i < mTiltles.length; i++) {
    ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]);
    mFragments.add(itemFragement);
}
mCurFragment = mFragments.get(position);
replaceFragment(mCurFragment);

((RadioButton)mRg.getChildAt(position)).setChecked(true);

private void replaceFragment(Fragment fragmeny) {
    FragmentManager supportFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.fl, fragmeny).commit();
}
  • 第三步,通过监听RadioGroup的 OnCheckedChangeListener事件,来实现tab和Fragemnt的切换
 mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {

        RadioButton radioButton = (RadioButton) group.findViewById(checkedId);

        if (false == radioButton.isChecked()) {
            return;
        }


        switch (checkedId) {
            case R.id.rb_home:
                position = 0;
                break;

            case R.id.rb_course:
                position = 1;
                break;

            case R.id.rb_direct_seeding:
                position = 2;
                break;

            case R.id.rb_me:
                position = 3;
                break;
            default:
                position = 0;
                break;

        }
        LUtils.i("position==" + position);

        Fragment to = mFragments.get(position);
        showFragment(mCurFragment, to);
        mCurFragment = to;

    }

});

使用RadioGroup和ViewPager 实现可以滑动切换的仿qq底部Tab切换

第一步,我们 同样先看布局代码

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    android:id="@+id/activity_second_style"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
>
    <!--用来填充Fragemnt的ViewPager-->
    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    </android.support.v4.view.ViewPager>
    <!--使用RadioGroup来实现tab的切换-->
    <RadioGroup

        android:id="@+id/rg"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
    >
        <RadioButton
            android:id="@+id/rb_home"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_home"
            android:text="首页"/>

        <RadioButton
            android:id="@+id/rb_course"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_course"
            android:text="课程"/>

        <RadioButton
            android:id="@+id/rb_direct_seeding"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_direct_seeding"
            android:text="直播"/>

        <RadioButton
            android:id="@+id/rb_me"
            style="@style/bottom_tab"
            android:drawableTop="@drawable/sel_me"
            android:text="我的"/>

    </RadioGroup>

</LinearLayout>

第二步,我们一起来看一下Activity代码

public class SecondStyleActivity extends AppCompatActivity {

    public static final String[] mTiltles = new String[]{
            "首页", "课程", "直播", "个人"
    };
    private List<Fragment> mFragments;
    ViewPager mViewPager;
    RadioGroup mRg;
    private int position = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second_style);
        mViewPager = (ViewPager) findViewById(R.id.viewPager);
        mRg = (RadioGroup) findViewById(R.id.rg);
        initListener();
        initData();


    }

    private void initData() {
        mFragments = new ArrayList<>();
        for (int i = 0; i < mTiltles.length; i++) {
            ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]);
            mFragments.add(itemFragement);
        }
        BaseFragmentAdapter fragmentAdapter = new BaseFragmentAdapter
                (getSupportFragmentManager(), mFragments, mTiltles);
        mViewPager.setAdapter(fragmentAdapter);
        mViewPager.setCurrentItem(position);
        ((RadioButton) mRg.getChildAt(position)).setChecked(true);
    }

    private void initListener() {
        mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
            @Override
            public void onPageSelected(int position) {
                RadioButton radioButton = (RadioButton) mRg.getChildAt(position);
                radioButton.setChecked(true);
            }
        });

        mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

            @Override
            public void onCheckedChanged(RadioGroup group, int checkedId) {
                RadioButton rb = (RadioButton) group.findViewById(checkedId);
                if (!rb.isChecked()) {
                    return;
                }
                switch (checkedId) {
                    case R.id.rb_home:
                        position = 0;
                        break;

                    case R.id.rb_course:
                        position = 1;
                        break;

                    case R.id.rb_direct_seeding:
                        position = 2;
                        break;

                    case R.id.rb_me:
                        position = 3;
                        break;
                    default:
                        position = 0;
                        break;

                }
                mViewPager.setCurrentItem(position);
            }
        });
    }
}

思路解析如下

  • 实例化ViewPager和RadioGroup
 mViewPager = (ViewPager) findViewById(R.id.viewPager);
 mRg = (RadioGroup) findViewById(R.id.rg);
  • 第二步,初始化ViewPager的适配器和选中 那个tab
 mFragments = new ArrayList<>();
for (int i = 0; i < mTiltles.length; i++) {
    ItemFragement itemFragement = ItemFragement.newInstance(mTiltles[i]);
    mFragments.add(itemFragement);
}
BaseFragmentAdapter fragmentAdapter = new BaseFragmentAdapter
        (getSupportFragmentManager(), mFragments, mTiltles);
mViewPager.setAdapter(fragmentAdapter);
mViewPager.setCurrentItem(position);
((RadioButton) mRg.getChildAt(position)).setChecked(true);
  • 第三步,监听ViewPager 的滑动事件和RadioGroup的OnCheckedChangeListener事件,分别切换到相应的 Fragemnt 和同步ViewPager中 position 与RadioGroup之间的联系
 mViewPager.addOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
    @Override
    public void onPageSelected(int position) {
        RadioButton radioButton = (RadioButton) mRg.getChildAt(position);
        radioButton.setChecked(true);
    }
});

mRg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {

    @Override
    public void onCheckedChanged(RadioGroup group, int checkedId) {
        RadioButton rb = (RadioButton) group.findViewById(checkedId);
        if (!rb.isChecked()) {
            return;
        }
        switch (checkedId) {
            case R.id.rb_home:
                position = 0;
                break;

            case R.id.rb_course:
                position = 1;
                break;

            case R.id.rb_direct_seeding:
                position = 2;
                break;

            case R.id.rb_me:
                position = 3;
                break;
            default:
                position = 0;
                break;

        }
        mViewPager.setCurrentItem(position);
    }
});

注意事项

我们可以通过以下方法设置ViewPager左右页面 能缓存的fragment 数量

//  设置左右页面 能缓存的fragment 数量
mViewPager.setOffscreenPageLimit(fragmentAdapter.getCount() - 1);

到此仿qq底部tab切换的集中方法已经讲解完毕,之所以讲解了 三种方法,是想让大家了解多种实现方式,因为每一个人的习惯都不一样,有些人习惯使用与第一种方式,有人习惯使用第二种方式 。。。。。。了解多种 实现方式以后,我们要读懂别人的代码也容易得多了,其实我们还可以使用自定义控件来实现,方法也比较简单,这里就不讲解了,有兴趣的话,可以自行搜索

下面我将为大家讲解Fragment的 一些优化


解决Fragment多次实例化的几种方案

目前本人了解到的解决方案 ,无非是利用一下两种思想

第一种解决方法

在onCreateView中避免多次实例化View,可通过判断View是否为空,来实现相应的 逻辑操作,核心代码如下

   public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
            Bundle savedInstanceState) {
        LUtils.i(getClass().getSimpleName()+">>>>>>>>>>>  onCreateView");
        if(mView==null){
            mContext = getContext();
            mView=View.inflate(mContext,getLayoutId(),null);
            initView(mView);
            LUtils.i(getClass().getSimpleName()+">>>>>>>>>>>  initView");
        }else{
            // 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除,
            // 要不然会发生这个rootview已经有parent的错误。
            ViewGroup parent =(ViewGroup) mView.getParent();
            if(parent!=null){
                parent.removeView(mView);
            }
            LUtils.i(getClass().getSimpleName()+">>>>>>>>>>>  removeView");
        }
        return mView;
    }

第二种解决方案

在项目中需要进行Fragment的切换,用hide()和show()方法结合起来来替代replace()方法来实现Fragment的切换:

private void showFragment(Fragment from, Fragment to) {
    FragmentManager supportFragmentManager = getSupportFragmentManager();
    FragmentTransaction transaction = supportFragmentManager.beginTransaction();
    if (!to.isAdded()) {    // 先判断是否被add过
        transaction.hide(from).add(R.id.fl, to).commit(); // 隐藏当前的fragment,add下一个到Activity中
    } else {
        transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
    }

}

/**
 * 这个方法用老替换fragment
 * xujun
 * 2016/5/3 17:28.
 */

private void replaceFragment(Fragment fragmeny) {
    FragmentManager supportFragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
    fragmentTransaction.replace(R.id.fl, fragmeny).commit();
}

关于 避免Fragment的多次实例化的分析与优化到此为止,下面我们一起来看一下 则那样实现Fragemnt 的 懒加载


Fragemnt的懒加载(网上很多人称之为Fragemnt的最优加载)

关于懒加载的这部分,代码是参考这篇 博客的 ViewPager+Fragment LazyLoad最优解

我们知道 ViewPager通常 会有预加载机制,默认情况下会先加载左右一页的数据,有时候我们想等待页面可见的时候在去加载网络 数据 ,解决方案如下

下面 先贴出代码

public abstract class BasePageFragment extends Fragment {

    protected View mView;

    /**
     * 表示View是否被初始化
     */
    protected boolean isViewInitiated;
    /**
     * 表示对用户是否可见
     */
    protected boolean isVisibleToUser;
    /**
     * 表示数据是否初始化
     */
    protected boolean isDataInitiated;
    private Context mContext;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        LUtils.i(getClass().getSimpleName() + ">>>>>>>>>>>  onCreate");
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable
            Bundle savedInstanceState) {
        LUtils.i(getClass().getSimpleName() + ">>>>>>>>>>>  onCreateView");
        if (mView == null) {
            mContext = getContext();
            mView = View.inflate(mContext, getLayoutId(), null);
            initView(mView);
            LUtils.i(getClass().getSimpleName() + ">>>>>>>>>>>  initView");
        } else {
            // 缓存的rootView需要判断是否已经被加过parent,如果有parent需要从parent删除,
            // 要不然会发生这个rootview已经有parent的错误。
            ViewGroup parent = (ViewGroup) mView.getParent();
            if (parent != null) {
                parent.removeView(mView);
            }
            LUtils.i(getClass().getSimpleName() + ">>>>>>>>>>>  removeView");
        }
        return mView;
    }

    protected abstract void initView(View view);

    protected abstract int getLayoutId();

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        LUtils.i(getClass().getSimpleName() + ">>>>>>>>>>>  onActivityCreated");
        isViewInitiated = true;
        initData();
        prepareFetchData();
    }

    @Override
    public void setUserVisibleHint(boolean isVisibleToUser) {
        super.setUserVisibleHint(isVisibleToUser);
        this.isVisibleToUser = isVisibleToUser;
        prepareFetchData();
    }

    public abstract void fetchData();

    public boolean prepareFetchData() {
        return prepareFetchData(false);
    }

    /***
     * 
     * @param forceUpdate 表示是否在界面可见的时候是否强制刷新数据
     * @return
     */
    public boolean prepareFetchData(boolean forceUpdate) {
        if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
            //  界面可见的时候再去加载数据
            fetchData();
            isDataInitiated = true;
            return true;
        }
        return false;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        LUtils.i(getClass().getSimpleName() + ">>>>>>>>>>>  onDestroyView");
    }

    protected void initData() {
    }

}

思路解析: 其实核心思想主要在setUserVisibleHint(boolean isVisibleToUser)方法中,这个方法在Fragemnt界面切换到可见或者 不可见的时候调用,isVisibleToUser表示当前界面可见 或者不可见

setUserVisibleHint(boolean isVisibleToUser) Set a hint to the system about whether this fragment’s UI is currently visible to the user.

于是我们在prepareFetchData进行判断只有当界面可见的情况下才会尝试判断是否调用fetchData() 方法,于是我们就可以实现等到界面可见的 时候才加载网络数据,将我们加载网络数据的 逻辑的实现放在fetchData() 里面即可

/***
 *
 * @param forceUpdate 表示是否在界面可见的时候是否强制刷新数据
 * @return
 */
public boolean prepareFetchData(boolean forceUpdate) {
    if (isVisibleToUser && isViewInitiated && (!isDataInitiated || forceUpdate)) {
        //  界面可见的时候再去加载数据
        fetchData();
        isDataInitiated = true;
        return true;
    }
    return false;
}

题外话

转眼间校招季已经过去了一个多月了,虽然没能进入到bat,网易之类的公司,不过也找到了相对比较喜欢的公司,接下来的日子就专心做毕业设计了,计划在十一月的时候出省旅游一次,明年春节回来的时候再去公司实习,悄悄地告诉你一件事哦,本人 还没有 出过广东省 ,哈哈,是不是很low呢?

转载请注明博客地址:http://blog.csdn.net/gdutxiaoxu/article/details/52826810

源码下载地址:https://github.com/gdutxiaoxu/QQBottomTab.git

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android干货

安卓开发_浅谈ListView之分页列表

41590
来自专栏7号代码

Android应用界面开发——Fragment(实现图书详情界面)

Fragment代表了Activity的子模块,因此可以把Fragment理解成Activity片段。

37820
来自专栏学海无涯

Android开发之奇怪的Fragment

说起Android中的Fragment,在使用的时候稍加注意,就会发现存在以下两种: v4包中的兼容Fragment,android.support.v4.ap...

34350
来自专栏移动开发

图片库的封装

关于图片库的封装相关的文章早已经看到过.图片库的封装可以使得调用者不知道,底层的具体实现,即使我们换了图片加载库,上层处的代码感知不到无需修改.

18020
来自专栏腾讯Bugly的专栏

《Android基础:Fragment,看这篇就够了》

| 导语 Fragment作为Android最基本,最重要的基础概念之一,在开发中经常会和他打交道。本文从为什么出现Fragment开始,介绍了Fragment...

1.6K60
来自专栏分享达人秀

Activity数据回传

上一节学习了将简单的数据从MainActivity传递到SecondActivity,本节一起来学习数据如何从SecondActivity回传到Main...

43550
来自专栏用户2442861的专栏

公司(视频 社交)项目分享

http://blog.csdn.net/u011733020/article/details/46786471

16360
来自专栏写写代码吃吃瓜

Android简易“吹一吹实现”以及录音和播放示例

27840
来自专栏james大数据架构

列表视图(ListView和ListActivity)

在ListView中显示网络图片  ImageView 类虽然有一个 setImageUri 方法,但不能直接接受一个由网络地址生成的uri作为参数从而显示图片...

33770
来自专栏CodingBlock

Android学习笔记(六)Fragment的生命周期

  在上一篇博文中对Fragment做了简单的介绍,现在再来探讨一下Fragment的生命周期。 一、Fragment的几种状态:   与Activity类...

244100

扫码关注云+社区

领取腾讯云代金券