快捷搜索:  as  test  1111  test aNd 8=8  test++aNd+8=8  as++aNd+8=8  as aNd 8=8

太阳集团城网2018:Android使用Fragment实现TabHost效果



现在Fragment的利用真的是越来越广泛了,之前Android在3.0版本加入Fragment的时刻,主如果为了办理Android Pad屏幕对照大年夜,空间不能充分使用的问题,但现期近使只是在手机上,也有很多的场景可以运用到Fragment了,本日我们就来进修此中一个分外棒的利用技术。

很多手机利用都邑有一个异常类似的功能,即屏幕的下方显示一行Tab标签选项,点击不合的标签就可以切换到不合的界面,如以下几个利用所示:

上面三个利用从左到右分手是QQ、新浪微博和支付宝钱包,可见,这种底部标签式的结构策略真的非经常见。

那么话说回来,这种效果到底是若何的呢?认识Android的同伙必然都邑知道,很简单嘛,应用TabHost就OK了!然则殊不知,TabHost并非是那么的简单,它的可扩展性异常的差,不能随意地定制Tab项显示的内容,而且运行还要依附于ActivityGroup。ActivityGroup蓝本主如果用于为每一个TabHost的子项治理一个零丁的Activity,但今朝已经被废弃了。为什么呢?当然便是由于Fragment的呈现了!查看Android官方文档中ActivityGroup的描述,如下所示:

可以看到,在API 13的时刻Android就已经将ActivityGroup废弃掉落了,并且官方保举的替代要领便是应用Fragment,由于它应用起来加倍的机动。那么剩下的问题便是若何借助Fragment来完成类似于TabHost一样平常的效果了,是以我们自然要动起手来了。

在开始之前,首先你必须已经懂得Fragment的用法了,假如你对Fragment还对照陌生的话,建议先去涉猎我前面的一篇文章http://www.fengfly.com/plus/view-215089-1.html。

别的,我们还应该筹备好法度榜样所必要的资本,比如说每一个Tab项中所用到的图片。我已经事先从QQ里截好了几张图作为这个项目的资本,稍后会连同源码一路给出。

新建一个项目,起名就叫FragmentDemo,这里我应用的是4.0的API。

下面开始编程事情,这里我们首先必要去编写一个类似于QQ的主界面,当然只会去编写界面最下方的TabHost部分,而不会编写上面的内容界面部分,由于内容界面是应该写在Fragment的结构里的。打开或新建activity_main.xml作为法度榜样的主结构文件,在里面加入如下代码:

LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="match_parent"android:layout_height="match_parent"

android:orientation="vertical" >

FrameLayoutandroid:id="@+id/content"

android:layout_width="match_parent"android:layout_height="0dp"

android:layout_weight="1" >FrameLayout>

LinearLayout

android:layout_width="match_parent"android:layout_height="60dp"

android:background="@drawable/tab_bg" >

RelativeLayoutandroid:id="@+id/message_layout"

android:layout_width="0dp"android:layout_height="match_parent"

android:layout_weight="1" >

LinearLayoutandroid:layout_width="match_parent"

android:layout_height="wrap_content"android:layout_centerVertical="true"

android:orientation="vertical" >

ImageViewandroid:id="@+id/message_image"

android:layout_width="wrap_content"android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"android:src="@drawable/message_unselected" />

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>

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="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:src="@drawable/contacts_unselected" />

TextViewandroid: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>

RelativeLayoutandroid:id="@+id/news_layout"

android:layout_width="0dp"android:layout_height="match_parent"

android:layout_weight="1" >

LinearLayoutandroid:layout_width="match_parent"

android:layout_height="wrap_content"android:layout_centerVertical="true"

android:orientation="vertical" >

ImageViewandroid:id="@+id/news_image"

android:layout_width="wrap_content"android:layout_height="wrap_content"

android:layout_gravity="center_horizontal"android:src="@drawable/news_unselected" />

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>

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="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:src="@drawable/setting_unselected" />

TextViewandroid: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又中分成了四份,每一份中都邑显示一个Im太阳集团城网2018ageView和一个TextView。ImageView用于显示当前Tab的图标,TextView用于显示当前Tab的标题,这个效果就会和QQ异常得类似。

既然是中分成了四分,那接下来我们自然要去分手实现四个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" >

LinearLayoutandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_centerInParent="true"

android:orientation="vertical" >

ImageViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:src="@drawable/message_selected" />

TextViewandroid: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 {

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState) {View messageLayout = inflater.inflate(R.layout.message_layout, container, false);

return messageLayout;}

}

后面便是依葫芦画瓢,把其它几个Fragment以及对应的结构创建出来。新建contacts_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" >

LinearLayoutandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_centerInParent="true"

android:orientation="vertical" >

ImageViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:src="@drawable/contacts_selected" />

TextViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:padding="10dp"android:text="这是联系人界面"

android:textSize="20sp" />LinearLayout>

RelativeLayout>

再新建ContactsFragment承袭自Frag太阳集团城网2018ment,代码如下所示:

public class ContactsFragment extends Fragment {

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

View contactsLayout = inflater.inflate(R.layout.contacts_layout,container, false);

return contactsLayout;}

}

然后新建news_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" >

LinearLayoutandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_centerInParent="true"

android:orientation="vertical" >

ImageViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:src="@drawable/news_selected" />

TextViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:padding="10dp"android:text="这是动态界面"

android:textSize="20sp" />LinearLayout>

RelativeLayout>

再新建NewsFragment承袭自Fragment,代码如下所示:

public class NewsFragment extends Fragment {

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

View newsLayout = inflater.inflate(R.layout.news_layout, container,false);

return newsLayout;}

}

着末新建setting_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" >

LinearLayoutandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_centerInParent="true"

android:orientation="vertical" >

ImageViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="ce太阳集团城网2018nter_horizontal"

android:src="@drawable/setting_selected" />

TextViewandroid:layout_width="wrap_content"

android:layout_height="wrap_content"android:layout_gravity="center_horizontal"

android:padding="10dp"android:text="这是设置界面"

android:textSize="20sp" />LinearLayout>

RelativeLayout>

再新建SettingFragment承袭自Fragment,代码如下所示:

public class SettingFragment extends Fragment {

@Override

public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {

View settingLayout = inflater.inflate(R.layout.setting_layout,container, false);

return settingLayout;}

}

这样我们就把每一个Fragment,以及它们所对应的结构文件都创建好了。接下来也便是最关键的步骤了,打开或新建MainActivity作为主Activity,代码如下所示:

/**

* 项目的主Activity,所有的Fragment都嵌入在这里。*

* @author guolin*/

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;

/奸淫 在Tab结构上显示消息图标的控件

*/private ImageView messageImage;

/**

* 在Tab结构上显示联系人图标的控件*/

private ImageView contactsImage;

/奸淫 在Tab结构上显示动态图标的控件

*/private ImageView newsImage;

/**

* 在Tab结构上显示设置图标的控件*/

private ImageView settingImage;

/奸淫 在Tab结构上显示消息标题的控件

*/private TextView messageText;

/**

* 在Tab结构上显示联系人标题的控件*/

private TextView contactsText;

/奸淫 在Tab结构上显示动态标题的控件

*/private TextView newsText;

/**

* 在Tab结构上显示设置标题的控件*/

private TextView settingText;

/奸淫 用于对Fragment进行治理

*/private FragmentManager fragmentManager;

@Override

protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);

requestWindowFeature(Window.FEATURE_NO_TITLE);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);messageImage = (ImageView) findViewById(R.id.message_image);

contactsImage = (ImageView) findViewById(R.id.contacts_image);newsImage = (ImageView) findViewById(R.id.news_image);

settingImage = (ImageView) findViewById(R.id.setting_image);messageText = (TextView) findViewById(R.id.message_text);

contactsText = (TextView) findViewById(R.id.contacts_text);newsText = (TextView) findViewById(R.id.news_text);

settingText = (TextView) findViewById(R.id.setti太阳集团城网2018ng_text);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:

// 当点击了消息tab时,改变控件的图片和翰墨颜色messageImage.setImageResource(R.drawable.message_selected);

messageText.setTextColor(Color.WHITE);if (messageFragment == null) {

// 假如MessageFragment为空,则创建一个并添加到界面上messageFragment = new MessageFragment();

transaction.add(R.id.content, messageFragment);} else {

// 假如MessageFragment不为空,则直接将它显示出来transaction.show(messageFragment);

}break;

case 1:// 当点击了联系人tab时,改变控件的图片和翰墨颜色

contactsImage.setImageResource(R.drawable.contacts_selected);contactsText.setTextColor(Color.WHITE);

if (contactsFragment == null) {// 假如ContactsFragment为空,则创建一个并添加到界面上

contactsFragment = new ContactsFragment();transaction.add(R.id.content, contactsFragment);

} else {// 假如ContactsFragment不为空,则直接将它显示出来

transaction.show(contactsFragment);}

break;case 2:

// 当点击了动态tab时,改变控件的图片和翰墨颜色newsImage.setImageResource(R.drawable.news_selected);

newsText.setTextColor(Color.WHITE);if (newsFragment == null) {

// 假如NewsFragment为空,则创建一个并添加到界面上newsFragment = new NewsFragment();

transaction.add(R.id.content, newsFragment);} else {

// 假如NewsFragment不为空,则直接将它显示出来transaction.show(newsFragment);

}break;

case 3:default:

// 当点击了设置tab时,改变控件的图片和翰墨颜色settingImage.setImageResource(R.drawable.setting_selected);

settingText.setTextColor(Color.WHITE);if (settingFragment == null) {

// 假如SettingFragment为空,则创建一个并添加到界面上settingFragment = new SettingFragment();

transaction.add(R.id.content, settingFragment);} else {

// 假如SettingFragment不为空,则直接将它显示出来transaction.show(settingFragment);

}break;

}transaction.commit();

}

/奸淫 清除掉落所有的选中状态。

*/private void clearSelection() {

messageImage.setImageResource(R.drawable.message_unselected);messageText.setTextColor(Color.parseColor("#82858b"));

contactsImage.setImageResource(R.drawable.contacts_unselected);contactsText.setTextColor(Color.parseColor("#8285太阳集团城网20188b"));

newsImage.setImageResource(R.drawable.news_unselected);newsText.setTextColor(Color.parseColor("#82858b"));

settingImage.setImageResource(R.drawable.setting_unselected);settingText.setTextColor(Color.parseColor("#82858b"));

}

/奸淫 将所有的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);

}}

}

这个类中的注释已经写得异常具体了,下面我再带大年夜家简单梳理一遍。在onCreate()措施中先是调用了initViews()来获取每个控件的实例,并给响应的控件设置好点击事故,然后调用setTabSelection()措施设置默认的选中项,这里传入的0阐明默认选中第1个Tab项。

那么setTabSelection()措施中又是若何处置惩罚的呢?可以看到,首先第一步是调用clearSelection()措施来清理掉落之前的选中状态,然后开启一个Fragment事务,并暗藏掉落所有的Fragment,以防止有多个Fragment显示在界面上。接下来根据传入的index参数判断出选中的是哪一个Tab项,并改变该Tab项的图标和翰墨颜色,然后将响应的Fragment添加到界面上。这里留意一个细节,我们添加Fragment的时刻并没有应用replace()措施,而是会先判断一下该Fragment是否为空,假如是空的则调用add()措施添加一个进来,假如不是空的则直接调用show()措施显示出来即可。那么为什么没有应用replace()措施呢?这是由于replace()措施会将被调换掉落的那个Fragment彻底地移除掉落,该Fragment的生命周期就停止了。当再次点击刚才那个Tab项的时刻,就会让该Fragment的生命周期从新开始,onCreate()、onCreateView()等措施都邑从新履行一遍。这显然不是我们想要的,也和ActivityGroup的事情道理不符,是以最好的办理规划便是应用hide()和show()措施来暗藏和显示Fragment,这就不会让Fragment的生命周期重走一遍了。

设置完默认选中项后,我们当然还可以经由过程点击Tab项来自由地切换界面,这就会进入到onClick()措施中。onClick()措施中的逻辑判断异常简单,当点击了消息标签时就会选中第1个tab项,点击联系人标签时就会选中第2个tab项,点击动态标签时就会选中第3个tab项,点击设置标签时就会选中第4个tab项。都是经由过程调用setTabSelection()措施来完成的,只是传入了不合的参数。

好了,这样我们就将整个的代码都编写完成了,下面就来运行一下吧。全部Tab的界面有点类似于QQ的感到,并且可以经由过程点击不合的Tab来切换界面,如下图所示:

别的,这个Tab界面纵然在横屏的环境下也有不错的适用性哦,如下图所示:

这样,我们就成功应用Fragment编写出了和TabHost一样的效果。每个界面的详细逻辑就可以写在响应的Fragment里,效果和之前写在Activity里是差不多的。如斯一来,我们终于可以和那个被废弃的ActivityGroup说再会了!

源码下载,请点击这里

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

您可能还会对下面的文章感兴趣: