`
dengyin2000
  • 浏览: 1225029 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

使用Fragment实现类似Tab的需求

阅读更多
大家都知道可以使用TabHost来实现, 不过这种实现已经是被deprecated, 其实是可以通过Fragment来实现, 不过如果是Fragment的话好像只能每次new一个fragment,这样感觉不太好, 按常理如果是以前有创建过fragment,下一次应该还是显示那个fragment实例。 通过google得知可以通过FragmentTransaction的attach和detach来实现。 下面贴下代码。

先detach所有可能的fragment,然后add或attach对应的fragment。

package com.kissbb.activity;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import com.androidquery.AQuery;
import com.androidquery.util.AQUtility;
import com.kissbb.R;
import com.kissbb.api.GoodsAPI;
import com.kissbb.fragment.CartFragment;
import com.kissbb.fragment.KuaigouListFragment;
import com.kissbb.fragment.MoreFragment;
import com.kissbb.fragment.MyOrderFragment;
import com.kissbb.model.KuaigouGroup;
import de.greenrobot.event.util.AsyncExecutor;

import java.util.List;

public class MainActivity extends FragmentActivity implements CompoundButton.OnCheckedChangeListener {

    private RadioButton rbMenuIndex;
    private RadioButton rbMenuCart;
    private RadioButton rbMenuMyOrder;
    private RadioButton rbMenuMore;

    private View rlMenuIndex;
    private View rlMenuCart;
    private View rlMenuMyOrder;
    private View rlMenuMore;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        AQuery aq = new AQuery(this);

        rbMenuIndex = (RadioButton) findViewById(R.id.rbMenuIndex);
        rbMenuIndex.setOnCheckedChangeListener(this);
        rbMenuCart = (RadioButton) findViewById(R.id.rbMenuCart);
        rbMenuCart.setOnCheckedChangeListener(this);
        rbMenuMyOrder = (RadioButton) findViewById(R.id.rbMenuMyOrder);
        rbMenuMyOrder.setOnCheckedChangeListener(this);
        rbMenuMore = (RadioButton) findViewById(R.id.rbMenuMore);
        rbMenuMore.setOnCheckedChangeListener(this);

        rlMenuCart = findViewById(R.id.rlMenuCart);
        rlMenuIndex = findViewById(R.id.rlMenuIndex);
        rlMenuMore = findViewById(R.id.rlMenuMore);
        rlMenuMyOrder = findViewById(R.id.rlMenuMyOrder);

        //
        rbMenuIndex.setChecked(true);

//        CheckBox cbIndex = (CheckBox) findViewById(R.id.rbMenuIndex);
//        aq.id(R.id.rbMenuIndex).
//        aQuery.id(R.id.button).clicked(this, "buttonClicked");
    }

    public void buttonClicked(View view) {
        AsyncExecutor.create().execute(new AsyncExecutor.RunnableEx() {
            @Override
            public void run() throws Exception {
                List<KuaigouGroup> kuaigouList = new GoodsAPI(MainActivity.this).getKuaigouList();
                AQUtility.debug("List<KuaigouGroup> is not null: " + kuaigouList.size());
//                UserLoginResult userLoginResult = new GoodsAPI(MainActivity.this).userLogin("deng.yin@gmail.com", "87200795");
//                AQUtility.debug("UserLoginResult is not null: " + (userLoginResult != null));
//                new UserAPI(MainActivity.this).userRegister("deng.yin@gmail.comx", "12345678", 111, 111, 11);
            }
        });
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (isChecked) {
            resetAllRadioButtons();
            buttonView.setChecked(true);
            FragmentManager fragmentManager = getSupportFragmentManager();
            KuaigouListFragment kuaigouListFragment = (KuaigouListFragment) fragmentManager.findFragmentByTag(String.valueOf(R.id.rbMenuIndex));
            CartFragment cartFragment = (CartFragment) fragmentManager.findFragmentByTag(String.valueOf(R.id.rbMenuCart));
            MyOrderFragment myOrderFragment = (MyOrderFragment) fragmentManager.findFragmentByTag(String.valueOf(R.id.rbMenuMyOrder));
            MoreFragment moreFragment = (MoreFragment) fragmentManager.findFragmentByTag(String.valueOf(R.id.rbMenuMore));
            FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
            /** Detaches all fragments if exists */
            if (kuaigouListFragment != null) {
                fragmentTransaction.detach(kuaigouListFragment);
            }
            if (cartFragment != null) {
                fragmentTransaction.detach(cartFragment);
            }
            if (myOrderFragment != null) {
                fragmentTransaction.detach(myOrderFragment);
            }
            if (moreFragment != null) {
                fragmentTransaction.detach(moreFragment);
            }
            int buttonId = buttonView.getId();
            switch (buttonId) {
                case R.id.rbMenuIndex:
                    rlMenuIndex.setBackgroundResource(R.drawable.footover);
                    if (kuaigouListFragment == null) {
                        /** Create AndroidFragment and adding to fragmenttransaction */
                        fragmentTransaction.add(R.id.flContent, new KuaigouListFragment(), String.valueOf(R.id.rbMenuIndex));
                    } else {
                        /** Bring to the front, if already exists in the fragmenttransaction */
                        fragmentTransaction.attach(kuaigouListFragment);
                    }
                    break;
                case R.id.rbMenuCart:
                    rlMenuCart.setBackgroundResource(R.drawable.footover);
                    if (cartFragment == null) {
                        /** Create AndroidFragment and adding to fragmenttransaction */
                        fragmentTransaction.add(R.id.flContent, new CartFragment(), String.valueOf(R.id.rbMenuCart));
                    } else {
                        /** Bring to the front, if already exists in the fragmenttransaction */
                        fragmentTransaction.attach(cartFragment);
                    }
                    break;
                case R.id.rbMenuMore:
                    rlMenuMore.setBackgroundResource(R.drawable.footover);
                    if (moreFragment == null) {
                        /** Create AndroidFragment and adding to fragmenttransaction */
                        fragmentTransaction.add(R.id.flContent, new MoreFragment(), String.valueOf(R.id.rbMenuMore));
                    } else {
                        /** Bring to the front, if already exists in the fragmenttransaction */
                        fragmentTransaction.attach(moreFragment);
                    }
                    break;
                case R.id.rbMenuMyOrder:
                    rlMenuMyOrder.setBackgroundResource(R.drawable.footover);
                    if (myOrderFragment == null) {
                        /** Create AndroidFragment and adding to fragmenttransaction */
                        fragmentTransaction.add(R.id.flContent, new MyOrderFragment(), String.valueOf(R.id.rbMenuMyOrder));
                    } else {
                        /** Bring to the front, if already exists in the fragmenttransaction */
                        fragmentTransaction.attach(myOrderFragment);
                    }
                    break;
            }
            fragmentTransaction.commit();
        }
    }

    private void resetAllRadioButtons() {
        rbMenuCart.setChecked(false);
        rbMenuIndex.setChecked(false);
        rbMenuMore.setChecked(false);
        rbMenuMyOrder.setChecked(false);
        rlMenuMore.setBackgroundResource(R.drawable.footline);
        rlMenuIndex.setBackgroundResource(R.drawable.footline);
        rlMenuMyOrder.setBackgroundResource(R.drawable.footline);
        rlMenuCart.setBackgroundResource(R.drawable.footline);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if(isTaskRoot()){

            //clean the file cache with advance option
            long triggerSize = 3000000; //starts cleaning when cache size is larger than 3M
            long targetSize = 2000000;      //remove the least recently used files until cache size is less than 2M
            AQUtility.cleanCacheAsync(this, triggerSize, targetSize);
        }
    }
}




但是如果attach已经存在的fragment时  还是会调用Fragment的onCreateView方法, 这样的话会让整个fragment重新绘制UI, 如果是里面是个ListView的话,因为需要重新所以ListView滚动那个位置就丢失了,如何能避免这个问题呢? 那就要保存Fragment onCreateView中生成的view, 代码如下。

package com.kissbb.fragment;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.widget.ListView;
import com.androidquery.util.AQUtility;
import com.handmark.pulltorefresh.library.PullToRefreshBase;
import com.handmark.pulltorefresh.library.PullToRefreshListView;
import com.kissbb.R;
import com.kissbb.adapter.KuaigouListAdapter;
import com.kissbb.api.GoodsAPI;
import com.kissbb.model.KuaigouGroup;
import de.greenrobot.event.EventBus;
import de.greenrobot.event.util.AsyncExecutor;

import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Denny
 * Date: 13-7-17
 * Time: 下午11:00
 * To change this template use File | Settings | File Templates.
 */
public class KuaigouListFragment extends Fragment {

    private GoodsAPI goodsAPI;
    private PullToRefreshListView ptrlvKuaigou;
    private int imgHeight;

    private List<KuaigouGroup> kuaigouGroupList;

    private View rootView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        goodsAPI = new GoodsAPI(getActivity());
        DisplayMetrics dm = getResources().getDisplayMetrics();
        int widthPixels = dm.widthPixels;
        imgHeight = (int) (182f/713*widthPixels);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        AQUtility.debug("onCreateView", "KuaigouListFragment");
        if (rootView == null) {
            rootView = inflater.inflate(R.layout.kuaigoulist_fragment, container, false);
            ptrlvKuaigou = (PullToRefreshListView) rootView.findViewById(R.id.ptrlvKuaigou);
            ptrlvKuaigou.setOnRefreshListener(new PullToRefreshBase.OnRefreshListener<ListView>() {
                @Override
                public void onRefresh(PullToRefreshBase<ListView> refreshView) {
                    startToPrepareData();
                }
            });

            if (kuaigouGroupList != null) {
            }else{
                ptrlvKuaigou.setVisibility(View.INVISIBLE);
                startToPrepareData();
            }
        }

        //缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null) {
            parent.removeView(rootView);
        }
        return rootView;
    }

    private void startToPrepareData() {
        AsyncExecutor.create().execute(new AsyncExecutor.RunnableEx() {
            @Override
            public void run() throws Exception {
                getKuaigouListData();
            }
        });
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);    //To change body of overridden methods use File | Settings | File Templates.
        AQUtility.debug("onActivityCreated", "KuaigouListFragment");
    }

    public void onEventMainThread(KuaigouDataEvent event) {
        ptrlvKuaigou.setVisibility(View.VISIBLE);
        kuaigouGroupList = event.kuaigouList;
        ptrlvKuaigou.setAdapter(new KuaigouListAdapter(kuaigouGroupList, getActivity(), imgHeight));
        ptrlvKuaigou.onRefreshComplete();
    }

    private void getKuaigouListData() {
        List<KuaigouGroup> kuaigouList = goodsAPI.getKuaigouList();
        EventBus.getDefault().post(new KuaigouDataEvent(kuaigouList));
    }

    public class KuaigouDataEvent{
        public List<KuaigouGroup> kuaigouList;

        public KuaigouDataEvent(List<KuaigouGroup> kuaigouList) {
            this.kuaigouList = kuaigouList;
        }
    }
}



特别注意这段代码, 需要先把view从parent中删掉 才能加回去。

        //缓存的rootView需要判断是否已经被加过parent, 如果有parent需要从parent删除,要不然会发生这个rootview已经有parent的错误。
        ViewGroup parent = (ViewGroup) rootView.getParent();
        if (parent != null) {
            parent.removeView(rootView);
        }
分享到:
评论
2 楼 yeyutianya 2014-04-26  
按home键退到后台,再返回前台,会重新走已经启动过的所有Fragment的onStart,onResume
1 楼 mnb123jhg 2013-11-15  
谢谢  写的详细

相关推荐

    android viewpager+fragment实现滚动tab页

    在Android开发中,`ViewPager`和`Fragment`是构建可滑动Tab页的常用组件。本文将深入探讨如何结合这两个组件来实现一个可...在实践中,开发者可以根据自己的需求调整和优化代码,以实现更加复杂和定制化的Tab页功能。

    使用GridView和Fragment实现Tab效果

    通过这种方式,虽然没有直接使用TabLayout,但我们可以借助GridView和Fragment创造出类似Tab的效果。这种方法适用于那些希望自定义Tab样式,或者在不支持最新库的旧版本Android系统上实现Tab功能的开发者。通过不断...

    TabFragment 使用Fragment 实现标签功能

    `TabActivity`是早期Android版本中处理标签页的类,但随着Android SDK的发展,现在推荐使用`Fragment`和`ViewPager`来实现类似的功能。 `TabFragment`的实现主要基于以下几个关键知识点: 1. **Fragment**:`...

    使用Fragment实现Tab切换(高仿微信)

    总结,通过`Fragment`、`TabLayout`和`ViewPager`的组合,我们可以轻松地在Android应用中实现类似微信的Tab切换效果。这不仅提高了用户体验,还能帮助我们有效地组织和管理代码,适应不同设备的屏幕尺寸。在实际开发...

    基于Fragment实现Tab的切换,滑出侧边栏

    在Android应用开发中,"基于Fragment实现Tab的切换,滑出侧边栏"是一个常见的功能需求,主要用于构建具有多视图和导航结构的用户界面。这个功能涉及到Android的UI组件和布局管理,尤其是Fragment和ViewPager的使用,...

    安卓FragmentTab选项卡相关-Fragment实现tab实例代码.zip

    FragmentTab选项卡是一种常见的UI设计,它将多个Fragment组织在同一个Activity的不同选项卡中,以实现多视图切换。在本实例中,我们将会探讨如何使用FragmentTabHost来实现这样的功能。 首先,了解FragmentTabHost...

    高仿蘑菇街 主界面,fragment实现首页tab切换

    在Android应用开发中,"高仿蘑菇街 主界面,fragment实现首页tab切换"是一个常见的设计模式,用于构建具有多视图、可切换内容的用户界面。这个设计涉及到的关键技术是`Fragment`和`TabLayout`,它们是Android支持库...

    Android高级应用源码-高仿蘑菇街 主界面,fragment实现首页tab切换.zip

    【标题】中的“Android高级应用源码-高仿蘑菇街 主界面,fragment实现首页tab切换.zip”表明这是一个关于Android应用程序开发的项目,旨在模仿知名电商应用蘑菇街的主界面设计,特别是利用Fragment来实现在主界面上...

    fragment+ViewPager实现Tab功能

    这个场景下,我们通常会用到`Fragment`和`ViewPager`来实现类似微信聊天界面那样的Tab功能。`Fragment`提供了在Activity中管理多个视图组件的能力,而`ViewPager`则用于展示可滑动的页面集合,两者结合可以轻松地...

    Fragment+RadioButton实现底部Tab栏

    本教程将详细讲解如何利用Fragment和RadioGroup来实现这一功能,类似于新浪应用底部的Tab栏设计。 首先,Fragment是Android SDK提供的一种组件,用于在单个Activity中展示可替换或可重用的UI片段。它允许你在不重新...

    FragmentTabHost+Fragment实现底部tab切换(烟台杰瑞教育Android培训部原创)

    本教程将介绍如何使用`FragmentTabHost`和`Fragment`来实现这样的底部tab切换功能,由烟台杰瑞教育科技有限公司的Android开发培训部原创。 首先,我们要理解`FragmentTabHost`和`Fragment`的概念。`FragmentTabHost...

    安卓Android源码——Tab+Viewpage+Fragment实现导航.zip

    在安卓开发中,构建一个可滑动切换的导航界面是常见的需求,这通常涉及到Tab布局、ViewPager和Fragment的结合使用。本压缩包“安卓Android源码——Tab+Viewpage+Fragment实现导航.zip”提供了一个这样的实现示例。...

    android 基于Fragment实现Tab的切换,滑出侧边栏Demo.zip

    这个Demo展示了如何使用Fragment和Android的Support Library来实现这一功能。以下是关于这个主题的关键知识点: 1. **Fragment**: Fragment是Android SDK中的一个重要组件,它允许在同一个Activity中展示多个独立的...

    Android Studio Fragment实现Tab仿微信底部滑动菜单源码

    在Android应用开发中,设计一个类似微信底部滑动菜单的界面是常见的需求,这通常涉及到`Fragment`的使用。`Fragment`是Android SDK提供的一种组件,它可以作为一个活动(Activity)的一部分来显示用户界面,允许...

    Android高级应用源码-基于Fragment实现Tab的切换,滑出侧边栏.zip

    在Android开发中,实现Tab切换和侧滑菜单是常见的需求,尤其在构建复杂且功能丰富的应用程序时。这个压缩包中的源码提供了一个基于Fragment实现的示例,这将帮助我们理解如何优雅地处理这两个功能。 首先,让我们...

    安卓开发-基于Fragment实现Tab的切换,滑出侧边栏.zip.zip

    这个项目"安卓开发-基于Fragment实现Tab的切换,滑出侧边栏.zip"提供了这样的实现方式,主要依赖于Android的Fragment和ViewPager组件来完成Tab的切换,以及使用SlidingMenu库来实现侧边栏的滑动效果。以下将详细讲解...

    kotlin--利用TabLayout、ViewPager、Fragment实现滑动切换页面

    本教程将深入探讨如何使用Kotlin语言,结合TabLayout、ViewPager和Fragment技术来实现这一功能。 首先,TabLayout是Android设计支持库中的一个组件,用于展示多个标签,用户可以通过点击或滑动来切换不同的标签页。...

    Android应用源码之基于Fragment实现Tab的切换,滑出侧边栏.zip

    这个源码示例是关于如何使用`Fragment`和相关组件来实现这一功能的实践教程。下面我们将深入探讨相关知识点。 1. **Fragment**: `Fragment`是Android SDK中的一个关键组件,它代表了应用程序UI的一部分,可以在...

    安卓FragmentTab选项卡相关-Android高仿华为Tab页的滑动导航功能.rar

    这个压缩包“安卓FragmentTab选项卡相关-Android高仿华为Tab页的滑动导航功能.rar”似乎包含了一个示例项目,展示了如何在Android应用中实现类似于华为设备上的滑动导航功能。虽然具体代码可能需要根据实际情况调整...

    Fragment + ViewPager 和 ActivityGroup tab横向滑动实现对比

    下面我们将详细探讨`Fragment + ViewPager`与`ViewPager + ActivityGroup`在实现tab横向滑动时的区别和知识点。 **Fragment + ViewPager** 1. **Fragment的引入**:Fragment是Android 3.0版本引入的概念,它是一个...

Global site tag (gtag.js) - Google Analytics