Android fragment实现多个页面切换效果

现在的APP首页大部分屏幕的下方显示一行Tab标签选项,点击不同的标签就可以切换到不同的界面。如下图:

我们之前都是用TabHost来实现,但是殊不知,TabHost并非是那么的简单,它的可扩展性非常的差,不能随意地定制Tab项显示的内容,而且运行还要依赖于ActivityGroup。ActivityGroup原本主要是用于为每一个TabHost的子项管理一个单独的Activity,但目前已经被废弃了。下面就借助Fragment来完成类似于TabHost一般的效果。

先实现主界面布局main_layout.xml:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" >
</FrameLayout>

<View
android:layout_width="match_parent"
android:layout_height="0.5dp"
android:background="#000000" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:background="#ffffff"
android:orientation="horizontal" >

<RelativeLayout
android:id="@+id/message_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/message_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />

<TextView
android:id="@+id/message_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="消息"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout>

<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="#000000" />

<RelativeLayout
android:id="@+id/contacts_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/contacts_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />

<TextView
android:id="@+id/contacts_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="联系人"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout>

<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="#000000" />

<RelativeLayout
android:id="@+id/news_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/news_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />

<TextView
android:id="@+id/news_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="动态"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout>

<View
android:layout_width="0.5dp"
android:layout_height="match_parent"
android:background="#000000" />

<RelativeLayout
android:id="@+id/setting_layout"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1" >

<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:orientation="vertical" >

<ImageView
android:id="@+id/setting_image"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />

<TextView
android:id="@+id/setting_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:text="设置"
android:textColor="#82858b" />
</LinearLayout>
</RelativeLayout>
</LinearLayout>

</LinearLayout>

这段布局代码虽然有点长,但其实主要就分为两部分。第一个部分就是FrameLayout,这里只是给FrameLayout的id设置成content,并没有在里面添加任何具体的内容,因为具体的内容是要在后面动态进行添加的。第二个部分就是FrameLayout下面的LinearLayout,这个LinearLayout中包含的就是整个类似于TabHost的布局。可以看到,我们将这个LinearLayout又等分成了四份,每一份中都会显示一个ImageView和一个TextView。ImageView用于显示当前Tab的图标,TextView用于显示当前Tab的标题。

既然是等分成了四分,那接下来我们自然要去分别实现四个Fragment和它们的布局了。新建一个message_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" >

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:orientation="vertical" >

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:src="@drawable/ic_launcher" />

<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:padding="10dp"
android:text="这是消息界面"
android:textSize="20sp" />
</LinearLayout>

</RelativeLayout>

其他三个界面类似就不一 一列出。然后要去创建对应这个布局的Fragment。新建MessageFragment继承自Fragment,代码如下所示:

public class MessageFragment extends Fragment{
  private TextView tv;
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
       Bundle savedInstanceState) {
    View messageLayout = inflater.inflate(R.layout.message, container, false);
    tv=(TextView) messageLayout.findViewById(R.id.message);
    tv.setText("哈哈哈哈哈哈");
    return messageLayout;
   }

}

我们也依次创建其他三个布局的Fragment。最后是MainActivity,代码如下:

public class MainActivity extends Activity implements OnClickListener {
/**
* 用于展示消息的Fragment
*/
private MessageFragment messageFragment;

/**
* 用于展示联系人的Fragment
*/
private ContactsFragment contactsFragment;

/**
* 用于展示动态的Fragment
*/
private NewsFragment newsFragment;

/**
* 用于展示设置的Fragment
*/
private SettingFragment settingFragment;

/**
* 消息界面布局
*/
private View messageLayout;

/**
* 联系人界面布局
*/
private View contactsLayout;

/**
* 动态界面布局
*/
private View newsLayout;

/**
* 设置界面布局
*/
private View settingLayout;
/**
* 用于对Fragment进行管理
*/
private FragmentManager fragmentManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   initViews();
   fragmentManager = getFragmentManager();
   // 第一次启动时选中第0个tab
   setTabSelection(0);
}

/**
* 在这里获取到每个需要用到的控件的实例,并给它们设置好必要的点击事件。
*/

private void initViews() {
   messageLayout = findViewById(R.id.message_layout);
   contactsLayout = findViewById(R.id.contacts_layout);
   newsLayout = findViewById(R.id.news_layout);
   settingLayout = findViewById(R.id.setting_layout);
   messageLayout.setOnClickListener(this);
   contactsLayout.setOnClickListener(this);
   newsLayout.setOnClickListener(this);
   settingLayout.setOnClickListener(this);
}

@Override
public void onClick(View v) {
   switch (v.getId()) {
   case R.id.message_layout:
     // 当点击了消息tab时,选中第1个tab
     setTabSelection(0);
     break;
   case R.id.contacts_layout:
     // 当点击了联系人tab时,选中第2个tab
     setTabSelection(1);
     break;
   case R.id.news_layout:
      // 当点击了动态tab时,选中第3个tab
      setTabSelection(2);
      break;
   case R.id.setting_layout:
       // 当点击了设置tab时,选中第4个tab
      setTabSelection(3);
       break;
   default:
    break;
}

}

/**
* 根据传入的index参数来设置选中的tab页。
*
* @param index
* 每个tab页对应的下标。0表示消息,1表示联系人,2表示动态,3表示设置。
*/
private void setTabSelection(int index) {
   // 每次选中之前先清楚掉上次的选中状态
   clearSelection();
   // 开启一个Fragment事务
   FragmentTransaction transaction = fragmentManager.beginTransaction();
   // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
   hideFragments(transaction);
   switch (index) {
   case 0:
     messageLayout.setBackgroundColor(0xff0000ff);

     if (messageFragment == null) {
       // 如果MessageFragment为空,则创建一个并添加到界面上
        messageFragment = new MessageFragment();
       transaction.add(R.id.content, messageFragment);
     } else {
       // 如果MessageFragment不为空,则直接将它显示出来
       transaction.show(messageFragment);
     }
     break;
   case 1:
    // 当点击了联系人tab时,改变控件的图片和文字颜色
    contactsLayout.setBackgroundColor(0xff0000ff);
    if (contactsFragment == null) {
     // 如果ContactsFragment为空,则创建一个并添加到界面上
     contactsFragment = new ContactsFragment();
     transaction.add(R.id.content, contactsFragment);
    } else {
     // 如果ContactsFragment不为空,则直接将它显示出来
     transaction.show(contactsFragment);
    }
    break;
   case 2:
    // 当点击了动态tab时,改变控件的图片和文字颜色
     newsLayout.setBackgroundColor(0xff0000ff);
     if (newsFragment == null) {
      // 如果NewsFragment为空,则创建一个并添加到界面上
       newsFragment = new NewsFragment();
       transaction.add(R.id.content, newsFragment);
     } else {
      // 如果NewsFragment不为空,则直接将它显示出来
      transaction.show(newsFragment);
     }
     break;
   case 3:
     default:
     // 当点击了设置tab时,改变控件的图片和文字颜色
     settingLayout.setBackgroundColor(0xff0000ff);
     if (settingFragment == null) {
     // 如果SettingFragment为空,则创建一个并添加到界面上
     settingFragment = new SettingFragment();
     transaction.add(R.id.content, settingFragment);
     } else {
     // 如果SettingFragment不为空,则直接将它显示出来
     transaction.show(settingFragment);
     }
    break;
  }
 transaction.commit();
}

/**
* 将所有的Fragment都置为隐藏状态。
*
* @param transaction
* 用于对Fragment执行操作的事务
*/
private void hideFragments(FragmentTransaction transaction) {
   if (messageFragment != null) {
     transaction.hide(messageFragment);
   }
    if (contactsFragment != null) {
     transaction.hide(contactsFragment);
   }
    if (newsFragment != null) {
      transaction.hide(newsFragment);
   }
   if (settingFragment != null) {
     transaction.hide(settingFragment);
   }
}

/**
* 清除掉所有的选中状态。
*/
private void clearSelection() {
   messageLayout.setBackgroundColor(0xffffffff);
   contactsLayout.setBackgroundColor(0xffffffff);
   newsLayout.setBackgroundColor(0xffffffff);
   settingLayout.setBackgroundColor(0xffffffff);
   }
}

这样就实现了上面图中的效果了。

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

(0)

相关推荐

  • Android App中使用ViewPager+Fragment实现滑动切换效果

    在android应用中,多屏滑动是一种很常见的风格,没有采用viewpager的代码实现会很长,如果采用ViewPager,代码就会短很多,但是使用ViewPager也有弊端:需要导入android-support-v4.jar.细节无法控制.不过现在情况已经不一样了,android-support-v4中提供了很多实用的功能,以至于现在新建一个android工程默认都会导入这个jar包.那我们就也采用viewpager来做滑动吧.另外一个概念就是Fragment和FragmentActivit

  • 一个Activity中多个Fragment的切换

    经常会遇到在一个activity界面上布局多个fragment,但是如何从一个fragment跳转到另一个fragment呢?今天在做项目中恰好遇到这样的问题,点击首页fragment的更多店铺,会切换到店铺的fragment,处理的步骤如下: 1.在一个fragment1中定义一个接口: /** * 定义地接口,用于fragment和activity之间的数据传递 */ public interface onClickShopListner{ public void setOnClickSho

  • Android中使用TabHost 与 Fragment 制作页面切换效果

    三个标签页置于顶端 效果图: 在文件BoardTabHost.java中定义页面切换的效果:切换页面时,当前页面滑出,目标页面滑入.这是2个不同的动画设定动画时要区分对待 import android.content.Context; import android.util.AttributeSet; import android.view.animation.Animation; import android.view.animation.TranslateAnimation; import

  • fragment实现隐藏及界面切换效果

    在前文中的效果中(Android如何创建自定义ActionBar),点击屏幕下方的 TextView 以此来实现 5 种 fragment 界面的切换. 由于网络数据的加载存在于不同的界面之中,当快速的切换界面时,就会出现程序的出错.因为快速的切换时,当前界面的数据还在读取,就切换到下一个界面,下一个界面也开始加载数据,每次界面的切换都会加载数据.这样就会出错(在本文中,fragment 是使用 replace() 方法来加载界面的,).所以可以使每个 fragment 只加载一次来减少数据的加

  • Android中Fragment相互切换间不被回收的实现方法

    前言 Android运行在各种各样的设备中,有小屏幕的手机,超大屏的平板甚至电视.针对屏幕尺寸的差距,很多情况下,都是先针对手机开发一套App,然后拷贝一份,修改布局以适应平板神马超级大屏的.难道无法做到一个App可以同时适应手机和平板么,当然了,必须有啊.Fragment的出现就是为了解决这样的问题. 如今市面上的应用基本上都是单Activity+多Fragment实现的了,而这类APP都有在相互切换时不被回收,即切换回原来的Fragment时还是原先的状态,这就是这里要实现的了. 这里使用F

  • Android开发使用Activity嵌套多个Fragment实现横竖屏切换功能的方法

    本文实例讲述了Android开发使用Activity嵌套多个Fragment实现横竖屏切换功能的方法.分享给大家供大家参考,具体如下: 一.上图 二.需求 近期项目遇到个横竖屏切换的问题,较为复杂,在此记之. 1.Activity中竖屏嵌套3个Fragment,本文简称竖屏FP1,FP2,FP3. 2.其中竖屏FP1与FP2可以切换为横屏的FL1,FL2,即竖屏FP1切换到对应的横屏FL1,竖屏FP2对应切换到横屏FL2. 3.FP3不允许横竖屏切换. 4.竖屏FP1,FP2,FP3用ViewP

  • Android使用TabLayou+fragment+viewpager实现滑动切换页面效果

    TabLayou 主要实现的是标题头的 滑动 这个 控件 类似于 ScrollView XML中的布局 <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <android.support.design.widget.TabLayout a

  • Android使用Fragment打造万能页面切换框架

    首先我们来回忆一下传统用Activity进行的页面切换,activity之间切换,首先需要新建intent对象,给该对象设置一些必须的参数,然后调用startActivity方法进行页面跳转.如果需要activity返回结果,则调用startActivityForResult方法,在onActivityResult方法中获得返回结果.此外,每一个要展示的activity需要在AndroidManifest.xml文件中注册.而且,如果在某些特定的情况下(比如65536方法数爆炸)要动态加载dex

  • Android Fragment中使用SurfaceView切换时闪一下黑屏的解决办法

    重构了下之前自己的一个新闻客户端,全部使用了Fragment来进行页面切换,只有一个入口Activity作为程序的启动Activity,其中有一个界面需要调用摄像头识别二维码,于是就会用到SurfaceView进行预览,那么问题来了,当切换到对应的Fragment时,屏幕会黑一下,黑了1秒左右就显示出正常的界面,而且这种现象只有第一次进入该Fragment才会出现,之后进入都不会出现,解决方法是无意在github上看到了,试了一下,可以行的通,下面贴出解决方法. 方法一.在Activity的on

  • Android基础之使用Fragment控制切换多个页面

    今天讲解一下Fragment的控制,主要是切换View和页面替换等操作.还有就是如何获取Fragment的管理对象,以及与Activity的通信方式.1.管理Fragment要在activity中管理fragment,需要使用FragmentManager. 通过调用activity的getFragmentManager()取得它的实例. •可以通过FragmentManager做一些事情, 包括: 使用findFragmentById()(用于在activity layout中提供一个UI的f

随机推荐