Fragment是一种可以嵌入在活动当中的UI 片段,它能让程序更加合理和充分地利用大屏幕的空间,因而在平板上应用的非常广泛。拥有自己的生命周期和接收、处理用户的事件。你可以动态的添加、替换和移除某个Fragment。
Fragment使用非常广泛,在此不介绍Fragment的生命周期,本例子将使用Fragment实现如下效果:
Message Friend Setting
图一
Message Friend Setting
图二
Message Friend Setting
图三
底部的三个按钮分别控制三个Fragment的展示,为方便说明,底部三个按钮从左至右命名为Message、Friend、Setting,如上面三张图所示。
图三的上部是展现使用ViewPager的效果,加了一条蓝色的指示器。
bottombar的布局文件
<?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="horizontal" >
<RelativeLayout
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1" >
<Button
android:id="@+id/btn_messaage"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/message1_normal"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1" >
<Button
android:id="@+id/btn_friend"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/friend_normal" />
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1" >
<Button
android:id="@+id/btn_setting"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/setting_normal"/>
</RelativeLayout>
</LinearLayout>
topbar的布局文件
<?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="horizontal" >
<RelativeLayout
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1" >
<Button
android:id="@+id/btn_insect"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/insect" />
</RelativeLayout>
<RelativeLayout
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_weight="1" >
<Button
android:id="@+id/btn_menu"
android:layout_width="40dp"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:background="@drawable/menu" />
</RelativeLayout>
</LinearLayout>
MainActivity的布局文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.jam.fragmentdemo.MainActivity" >
<include
android:id="@+id/bottombar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
layout="@layout/bottombar" />
<FrameLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/bottombar" />
</RelativeLayout>
由于message和friend两个fragment的布局文件简单,所以在此就不贴上来了。
SettingFragment的布局文件
<?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" >
<include
android:layout_width="match_parent"
android:layout_height="wrap_content"
layout="@layout/topbar" />
<ImageView
android:id="@+id/iv_tabline"
android:layout_width="match_parent"
android:layout_height="3dp"
android:layout_marginLeft="0dp"
android:background="@drawable/tabline" />
<android.support.v4.view.ViewPager
android:id="@+id/setting_fragment_viewpager"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1.0"
android:flipInterval="30"
android:persistentDrawingCache="animation" />
</LinearLayout>
MainActivity代码:
package com.jam.fragmentdemo;
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.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
/**
* 由于这个工程还需要用到ViewPager,所以在此继承FragmentActivity
* @author Jam
*
*/
public class MainActivity extends FragmentActivity implements OnClickListener {
// 三个按钮
private Button messageButton;
private Button friendButton;
private Button settingButton;
// 三个fragment
private MessageFragment messgeFragment;
private FriendFragment friendFragment;
private SettingFragment settingFragment;
private int fragmentIndex = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_main);
messageButton = (Button) findViewById(R.id.btn_messaage);
friendButton = (Button) findViewById(R.id.btn_friend);
settingButton = (Button) findViewById(R.id.btn_setting);
setDefaultFragment();
// 为三个按钮绑定监听器
messageButton.setOnClickListener(this);
friendButton.setOnClickListener(this);
settingButton.setOnClickListener(this);
}
/**
* 设置初始化默认的Fragment为MessageFragment
*/
private void setDefaultFragment() {
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
messgeFragment = new MessageFragment();
transaction.replace(R.id.content, messgeFragment);
transaction.commit();
}
/**
* 在下面的onClick内, 用了两个switch语句来处理页面的更换第一层判断按下了哪一个按钮
* 第二层判断当前页是哪一页,在决定隐藏哪一页
* 这里的实现方法可能会不太灵活
*/
@Override
public void onClick(View v) {
// FragmentTransaction每一次都需要拿到,否则程序会报错
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
switch (v.getId()) {
case R.id.btn_messaage:
if (messgeFragment == null) {
messgeFragment = new MessageFragment();
transaction.add(R.id.content, messgeFragment);
}
switch (fragmentIndex) {
case 0:
if (messgeFragment != null) {
transaction.hide(messgeFragment);
}
break;
case 1:
if (friendFragment != null) {
transaction.hide(friendFragment);
}
break;
case 2:
if (settingFragment != null) {
transaction.hide(settingFragment);
}
break;
}
transaction.show(messgeFragment);
fragmentIndex = 0;
break;
case R.id.btn_friend:
if (friendFragment == null) {
friendFragment = new FriendFragment();
transaction.add(R.id.content, friendFragment);
}
switch (fragmentIndex) {
case 0:
if (messgeFragment != null) {
transaction.hide(messgeFragment);
}
break;
case 1:
if (friendFragment != null) {
transaction.hide(friendFragment);
}
break;
case 2:
if (settingFragment != null) {
transaction.hide(settingFragment);
}
break;
}
transaction.show(friendFragment);
fragmentIndex = 1;
break;
case R.id.btn_setting:
if (settingFragment == null) {
settingFragment = new SettingFragment();
transaction.add(R.id.content, settingFragment);
}
switch (fragmentIndex) {
case 0:
if (messgeFragment != null) {
transaction.hide(messgeFragment);
}
break;
case 1:
if (friendFragment != null) {
transaction.hide(friendFragment);
}
break;
case 2:
if (settingFragment != null) {
transaction.hide(settingFragment);
}
break;
}
transaction.show(settingFragment);
fragmentIndex = 2;
break;
}
transaction.commit();
}
}
这段代码中要注意,在做事务操作时FragmentTransaction每次都要拿到,即
FragmentTransaction transaction = getSupportFragmentManager()
.beginTransaction();
否则程序会报错,完成操作记得transaction.commit();
另外在使用流程大致如下
首先
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
(注意上面getSupportFragmentManager是V4包的用法)
transaction.add()
transaction.remove()
transaction.replace()
transaction.hide()
transaction.show()
detach()
会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。
attach()
重建view视图,附加到UI上并显示。
transatcion.commit()//提交一个事务
以上是大致流程,具体使用哪种方法依照自己的工程需要。
MessageFragment的代码和FriendFragment的代码简单,没有在其中添加什么东西,只需要让他们继承Fragment
在此只贴出其中MessageFragment的代码
package com.jam.fragmentdemo;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class MessageFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
// TODO Auto-generated method stub
return inflater.inflate(R.layout.activity_messagefragment, container, false);
}
}
SettingFragment由于用到了ViewPager,所以代码比前面两个Fragment多
SettingFragment的代码:
package com.jam.fragmentdemo;
import java.util.ArrayList;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import com.jam.fragmentdemo.settingcontent.InsectFragment;
import com.jam.fragmentdemo.settingcontent.MenuFragment;
public class SettingFragment extends Fragment implements OnClickListener{
//TopBar所含有的页数
private final static int pagerNum = 2;
//TopBar当前所指向的页下标
private int currentIndex = 0;
//initTabLineWith方法中计算得到的平均值用avg记录
//这里的平均值指的是:屏幕宽度/所含的页数(pagerNum)
private int avg;
private ArrayList<Fragment> list = new ArrayList<Fragment>();
private ViewPager viewPager;
private ImageView tabLine;
private InsectFragment insectFragment;
private MenuFragment menuFragment;
private Button insectButton;
private Button menuButton;
@Override
public View onCreateView(LayoutInflater inflater,
@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_settingfragment, null);
initTabLineWith(view);
//初始化部件
viewPager = (ViewPager) view.findViewById(R.id.setting_fragment_viewpager);
viewPager.setCurrentItem(0);
insectButton = (Button) view.findViewById(R.id.btn_insect);
menuButton = (Button) view.findViewById(R.id.btn_menu);
insectFragment = new InsectFragment();
menuFragment = new MenuFragment();
list.add(insectFragment);
list.add(menuFragment);
insectButton.setOnClickListener(this);
menuButton.setOnClickListener(this);
viewPager.setAdapter(new MyViewPagerAdapter(getChildFragmentManager(), list));
viewPager.setOnPageChangeListener(new OnPageChangeListener() {
/**
* tabLine指示器使用Animation的方法移动
*/
@Override
public void onPageSelected(int position) {
Animation animation = null;
switch (position) {
case 0:
animation = new TranslateAnimation(currentIndex * avg,
0 * avg, 0, 0);
break;
case 1:
animation = new TranslateAnimation(currentIndex * avg,
1 * avg, 0, 0);
break;
}
currentIndex = position;
animation.setFillAfter(true);
animation.setDuration(300);
tabLine.startAnimation(animation);
}
@Override
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
@Override
public void onPageScrollStateChanged(int arg0) {
}
});
return view;
}
/**
* 根据屏幕宽度的大小,初始化TabLine的长度
* @param view
*/
private void initTabLineWith(View view) {
tabLine = (ImageView) view.findViewById(R.id.iv_tabline);
LayoutParams lp = (LayoutParams) tabLine.getLayoutParams();
//拿到屏幕宽度的操作
DisplayMetrics dm = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(dm);
int screenWith = dm.widthPixels;
avg =screenWith / pagerNum;
lp.width = avg;
//设置tabLine指示器的长度
tabLine.setLayoutParams(lp);
}
/**
* 点击改动当前页面
*/
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_insect:
viewPager.setCurrentItem(0);
currentIndex = 0;
break;
case R.id.btn_menu:
viewPager.setCurrentItem(1);
currentIndex = 1;
break;
}
}
public class MyViewPagerAdapter extends FragmentPagerAdapter {
private ArrayList<Fragment> fragmentsList;
public MyViewPagerAdapter(FragmentManager fm) {
super(fm);
}
public MyViewPagerAdapter(FragmentManager fm,
ArrayList<Fragment> list) {
super(fm);
this.fragmentsList = list;
}
@Override
public int getCount() {
return fragmentsList.size();
}
@Override
public Fragment getItem(int arg0) {
return fragmentsList.get(arg0);
}
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
}
}
SettingFragment中又包含两个Fragment,这两个Fragment没什么内容,在此就不贴布局文件和代码了。
单纯使用Fragment,不能实现滑动的效果,只能点击切换,要实现滑动的效果可考虑使用ViewPager。
使用Fragment实现这种类似TabHost,好处在于文件方便管理,每一个Fragment都是独立的,单纯的使用ViewPager的话,代码会比较长,在修改是比较麻烦。
本次工程中的代码只实现了展示了基本的效果,另外有篇写的非常好的博文
Android项目Tab类型主界面大总结 Fragment+TabPageIndicator+ViewPager
介绍了各种Tab实现的效果和对比。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。