Android利用Fragment实现Tab选项卡效果

利用Fragment实现Tab选项卡效果: 

将RadioGroup与Fragment集合,实现tab选项卡效果,这里面最关键的几个文件:

1.FragmentTabAdapter类:

/**
 *@Description:
 *@Author:Nate Robinson
 *@Since:2015-2-12
 */
public class FragmentTabAdapter implements RadioGroup.OnCheckedChangeListener
{
 private List<Fragment> fragments; // 一个tab页面对应一个Fragment

 private RadioGroup rgs; // 用于切换tab

 private Activity activity; // Fragment所属的Activity

 private int fragmentContentId; // Activity中所要被替换的区域的id

 private int currentTab; // 当前Tab页面索引

 private OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener; // 用于让调用者在切换tab时候增加新的功能

 public FragmentTabAdapter(Activity activity, List<Fragment> fragments, int fragmentContentId, RadioGroup rgs)
 {
  this.fragments = fragments;
  this.rgs = rgs;
  this.activity = activity;
  this.fragmentContentId = fragmentContentId;

  // 默认显示第一页
  android.app.FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
  ft.add(fragmentContentId, fragments.get(0));
  ft.commit();

  rgs.setOnCheckedChangeListener(this);

 }

 @Override
 public void onCheckedChanged(RadioGroup radioGroup, int checkedId)
 {
  for(int i = 0; i < rgs.getChildCount(); i++)
  {
   if(rgs.getChildAt(i).getId() == (checkedId))
   {
    Fragment fragment = fragments.get(i);
    FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
    getCurrentFragment().onPause(); // 暂停当前tab
    // getCurrentFragment().onStop(); // 暂停当前tab

    if(fragment.isAdded())
    {
     // fragment.onStart(); // 启动目标tab的onStart()
     fragment.onResume(); // 启动目标tab的onResume()
    }
    else
    {
     ft.add(fragmentContentId, fragment);
    }
    showTab(i); // 显示目标tab
    ft.commit();

    // 如果设置了切换tab额外功能功能接口
    if(null != onRgsExtraCheckedChangedListener)
    {
     onRgsExtraCheckedChangedListener.OnRgsExtraCheckedChanged(radioGroup, checkedId, i);
    }

   }
  }

 }

 /**
  * 切换tab
  * @param idx
  */
 private void showTab(int idx)
 {
  for(int i = 0; i < fragments.size(); i++)
  {
   Fragment fragment = fragments.get(i);
   FragmentTransaction ft = activity.getFragmentManager().beginTransaction();
   if(idx == i)
   {
    ft.show(fragment);
   }
   else
   {
    ft.hide(fragment);
   }
   ft.commit();
  }
  currentTab = idx; // 更新目标tab为当前tab
 }

 public int getCurrentTab()
 {
  return currentTab;
 }

 public Fragment getCurrentFragment()
 {
  return fragments.get(currentTab);
 }

 public OnRgsExtraCheckedChangedListener getOnRgsExtraCheckedChangedListener()
 {
  return onRgsExtraCheckedChangedListener;
 }

 public void setOnRgsExtraCheckedChangedListener(OnRgsExtraCheckedChangedListener onRgsExtraCheckedChangedListener)
 {
  this.onRgsExtraCheckedChangedListener = onRgsExtraCheckedChangedListener;
 }

 /**
  * 切换tab额外功能功能接口
  */
 public interface OnRgsExtraCheckedChangedListener
 {
  void OnRgsExtraCheckedChanged(RadioGroup radioGroup, int checkedId, int index);
 }
}

2.activity_main.xml布局文件:

<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:background="@android:color/white"
 android:orientation="vertical" >

 <LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="vertical" >

  <FrameLayout
   android:id="@+id/tab_content"
   android:layout_width="fill_parent"
   android:layout_height="0dp"
   android:layout_weight="1.0"
   android:background="#77557799" />

  <RadioGroup
   android:id="@+id/tabs_rg"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:gravity="center"
   android:orientation="horizontal"
   android:paddingBottom="7dp"
   android:paddingTop="7dp" >

   <RadioButton
    android:id="@+id/tab_rb_a"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1.0"
    android:background="@drawable/selector_tab"
    android:button="@null"
    android:checked="true"
    android:drawableTop="@drawable/tablatestalert"
    android:gravity="center"
    android:singleLine="true"
    android:text="Tab1"
    android:textColor="#000000"
    android:textSize="13sp" />

   <RadioButton
    android:id="@+id/tab_rb_b"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1.0"
    android:background="@drawable/selector_tab"
    android:button="@null"
    android:drawableTop="@drawable/tabsearch"
    android:gravity="center"
    android:singleLine="true"
    android:text="Tab2"
    android:textColor="#000000"
    android:textSize="13sp" />

   <RadioButton
    android:id="@+id/tab_rb_c"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_weight="1.0"
    android:background="@drawable/selector_tab"
    android:button="@null"
    android:drawableTop="@drawable/tabrecommd"
    android:gravity="center"
    android:singleLine="true"
    android:text="Tab3"
    android:textColor="#000000"
    android:textSize="13sp" />
  </RadioGroup>
 </LinearLayout>

</LinearLayout>

3.MainActivity类:

/**
 *@Description:
 *@Author:Nate Robinson
 *@Since:2015-2-12
 */
public class MainActivity extends Activity
{
 private RadioGroup rgs;

 private List<Fragment> fragments = new ArrayList<Fragment>();

 private int index;

 private static Boolean isExit = false;

 private static Boolean hasTask = false;

 private RadioButton button;

 private Timer tExit = new Timer();

 private TimerTask task = new TimerTask()
 {
  @Override
  public void run()
  {
   isExit = false;
   hasTask = true;
  }
 };

 private FragmentTabAdapter tabAdapter;

 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  fragments.add(new FragmentOne());
  fragments.add(new FragmentTwo());
  fragments.add(new FragmentThree());

  rgs = (RadioGroup) findViewById(R.id.tabs_rg);

  button = (RadioButton) findViewById(R.id.tab_rb_a);

  tabAdapter = new FragmentTabAdapter(this, fragments, R.id.tab_content, rgs);
  tabAdapter.setOnRgsExtraCheckedChangedListener(new FragmentTabAdapter.OnRgsExtraCheckedChangedListener()
  {
   @Override
   public void OnRgsExtraCheckedChanged(RadioGroup radioGroup, int checkedId, int index)
   {
    // 利用这个index可以实现,如果不是在主页,按第一遍让它先跳转到第一个Fragment
    System.out.println("Extra---- " + index + " checked!!! ");
    MainActivity.this.index = index;
   }
  });
 }

 @Override
 public boolean onKeyDown(int keyCode, KeyEvent event)
 {
  if(keyCode == KeyEvent.KEYCODE_BACK)
  {
   if(index == 0)
   {
    if(isExit == false)
    {
     isExit = true;
     Toast.makeText(MainActivity.this, "再按一次退出程序", Toast.LENGTH_SHORT).show();
     if(!hasTask)
     {
      tExit.schedule(task, 1000);
     }
    }
    else
    {
     finish();
     System.exit(0);
    }
   }
   else
   {
    // 如果不是在主页,按第一遍让它先跳转到第一个Fragment
    // 利用上面的check方法会导致onCheckedChanged方法被执行多次
    // rgs.check(button.getId());
    button.setChecked(true);
   }

  }
  return false;
 }
}

为了能同时学习Fragment生命周期,我在Fragment每个生命周期方法中加入了log打印,一个有三个这样的Fragment,我只贴出其中一个代码,其余和这个一样:

/**
 *@Description:
 *@Author:Nate Robinson
 *@Since:2015-2-12
 */
public class FragmentOne extends BaseFragment
{

 private View view;

 @Override
 public void onAttach(Activity activity)
 {
  super.onAttach(activity);
  Log.d(TAG, "1==>FragmentOne=>onAttach");
 }

 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  Log.d(TAG, "2==>FragmentOne==>onCreate");
  super.onCreate(savedInstanceState);
 }

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
 {
  Log.d(TAG, "3==>FragmentOne==>onCreateView");
  view = inflater.inflate(R.layout.fragment1, container, false);
  TextView tv = (TextView) view.findViewById(R.id.tv);
  tv.setText("FragmentOne");
  return view;
 }

 @Override
 public void onActivityCreated(Bundle savedInstanceState)
 {
  Log.d(TAG, "4==>FragmentOne==>onActivityCreated");
  super.onActivityCreated(savedInstanceState);
 }

 @Override
 public void onStart()
 {
  Log.d(TAG, "5==>FragmentOne==>onStart");
  super.onStart();
 }

 @Override
 public void onResume()
 {
  Log.d(TAG, "6==>FragmentOne==>onResume");
  super.onResume();
 }

 @Override
 public void onPause()
 {
  Log.d(TAG, "7==>FragmentOne==>onPause");
  super.onPause();
 }

 @Override
 public void onStop()
 {
  Log.d(TAG, "8==>FragmentOne==>onStop");
  super.onStop();
 }

 @Override
 public void onDestroyView()
 {
  Log.d(TAG, "9==>FragmentOne==>onDestroyView");
  super.onDestroyView();
 }

 @Override
 public void onDestroy()
 {
  Log.d(TAG, "10==>FragmentOne==>onDestroy");
  super.onDestroy();
 }

 @Override
 public void onDetach()
 {
  Log.d(TAG, "11==>FragmentOne==>onDetach");
  super.onDetach();
 }

 @Override
 public void onViewCreated(View view, Bundle savedInstanceState)
 {

  Log.d(TAG, "FragmentOne==>onViewCreated");
  super.onViewCreated(view, savedInstanceState);
 }
}

在编写过程中,我为了实现如果不是在主页,按第一遍让它先跳转到第一个Fragment这个效果,一开始使用了rgs.check(button.getId());这个方法,结果发现,这样的话onCheckedChanged监听事件会执行两次,后来改为button.setChecked(true);这个方法之后,成功解决了这个问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Android TabLayout(选项卡布局)简单用法实例分析

    本文实例讲述了Android TabLayout(选项卡布局)简单用法.分享给大家供大家参考,具体如下: 我们在应用viewpager的时候,经常会使用TabPageIndicator来与其配合.达到很漂亮的效果.但是TabPageIndicator是第三方的,而且比较老了,当然了现在很多大神都已经开始自己写TabPageIndicator来满足自己的需求,在2015年的google大会上,google发布了新的Android Support Design库,里面包含了几个新的控件,其中就有一个

  • Android仿微信底部实现Tab选项卡切换效果

    在网上看了比较多的关于Tab的教程,发现都很杂乱.比较多的用法是用TitlePagerTabStrip和ViewPaper.不过TitlePagerTabStrip有个很大的缺陷,Tab里面的内容刚进去是没有的,要滑一次才能加载出来.而且滑动的时候,Tab里面的内容位置不是固定的,滑倒最后会出现一片空白,非常不美观.虽然有其他的补救方法,但是非常的麻烦,所以我就按照自己的方法实现了一个,功能不错而且非常简单. 直接点击或者是滑动界面,都可以转到相应的页面. 效果图: 原理是用了三个按钮和View

  • Android组件TabHost实现页面中多个选项卡切换效果

    TabHost组件可以在界面中存放多个选项卡, 很多软件都使用了改组件进行设计. 一.基础知识 TabWidget : 该组件就是TabHost标签页中上部 或者 下部的按钮, 可以点击按钮切换选项卡; TabSpec : 代表了选项卡界面, 添加一个TabSpec即可添加到TabHost中; -- 创建选项卡 : newTabSpec(String tag), 创建一个选项卡; -- 添加选项卡 : addTab(tabSpec); 二.实例讲解 TabHost的基本使用,主要是layout的

  • Android多个TAB选项卡切换效果

    在前一期中,我们做了悬浮头部的两个tab切换和下拉刷新效果,后来项目中要求改成三个tab,当时就能估量了一下,如果从之前的改,也不是不可以,但是要互相记住的状态就太多了,很容易出现错误.就决定重新实现一下这个效果,为此先写了一个demo,这期间项目都已经又更新了两个版本了.demo还木有变成文章. 之前的版本中是采用了一个可以下拉刷新的listview,之后在listview中添加了两个头部,并且在该布局上的上面用了一个一模一样的切换tab,如果没有看过前面版本的,可以看看前一个版本,Listv

  • Android ViewPager实现选项卡切换

    本文实例介绍了ViewPager实现选项卡切换,效果图如下: 步骤一:这里使用兼容低版本的v4包进行布局,这里eclipse没有输入提示,所以要手动输入,文件名称"activity_main.xml" <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"

  • Android实现底部导航栏功能(选项卡)

    现在很多android的应用都采用底部导航栏的功能,这样可以使得用户在使用过程中随意切换不同的页面,现在我采用TabHost组件来自定义一个底部的导航栏的功能. 我们先看下该demo实例的框架图: 其中各个类的作用以及资源文件就不详细解释了,还有资源图片(在该Demo中借用了其它应用程序的资源图片)也不提供了,大家可以自行更换自己需要的资源图片.直接上各个布局文件或各个类的代码: 1. res/layout目录下的 maintabs.xml 源码: <?xml version="1.0&q

  • Android编程实现自定义Tab选项卡功能示例

    本文实例讲述了Android编程实现自定义Tab选项卡功能.分享给大家供大家参考,具体如下: import android.app.TabActivity; import android.content.Intent; import android.os.Bundle; import android.widget.*; import android.widget.TabHost.OnTabChangeListener; import android.os.Build; import androi

  • android TabHost(选项卡)的使用方法

    首先,定义TabHost的布局文件: 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@android:id/tabhost" android:layout_width="fill_p

  • Android开发之选项卡功能的实现方法示例

    本文实例讲述了Android选项卡功能的实现方法.分享给大家供大家参考,具体如下: 选项卡(TabHost)方便的在窗口上设置多个标签页,每个标签页相当于获得一个与外部容器相同大小的组件摆放区域 通过这种方式,可以在一个容器中放置多组件. 创建4个java文件并对应layout 创建主java ,代码 package lianxi; import com.example.jichu_lianxi.R; import android.app.TabActivity; import android.

  • android 选项卡(TabHost)如何放置在屏幕的底部

    今天写Tab的时候由于TAB的跳转问题去查资料,倒反而发现更有趣的问题,就是如何将TAB放置在屏幕的底端. 复制代码 代码如下: <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:android="http://schemas.android.com/apk/res/android" android:id="@android:id/tabhost" a

  • Android用Fragment创建选项卡

    本文结合之前的动态创建fragment来进行一个实践,来实现用Fragment创建一个选项卡 项目布局 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout

  • Android编程之TabWidget选项卡用法实例分析

    本文实例讲述了Android编程之TabWidget选项卡用法.分享给大家供大家参考,具体如下: 1 概览 TabWidget与TabHost.tab组件一般包括TabHost和TabWidget.FrameLayout,且TabWidget.FrameLayout属于TabHost. 是否继承TabActivity的问题 实现步骤.两种实现方式,一种是将每个Tab的布局嵌在TabHost中的FrameLayout中,每个Tab的内容布局与显示都在FrameLayout中进行,缺点是布局会显得很

随机推荐