Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment
来源:互联网 发布:中国联通ims网络快吗 编辑:程序博客网 时间:2024/06/06 02:56
前几天,项目中要实现这么一个功能。就配置了下。其实很简单,首先 需要阅读下我转载的前两篇文章,都是转载的郭神的,写的非常好。我的项目中逢者必用,其实就相当于一个很好的框架来使用,非常方便。
前两篇的项目地址Android Fragment应用实战,使用碎片向ActivityGroup说再见和Android ActionBar应用实战,高仿微信主界面的设计,认真阅读,你会感觉到受益颇深。(当然,如果你不是大神)
其实和前两篇都重复了,都不想粘贴代码了,为了便于学习,还是粘贴上吧。
首先,写了一个BaseActivity,便于封装一些方法继承
- public class BaseActivity extends FragmentActivity {
- protected Context mContext;
- @Override
- protected void onCreate(Bundle arg0) {
- // TODO Auto-generated method stub
- super.onCreate(arg0);
- ActionBar actionBar = getActionBar();
- actionBar.hide();//隐藏标题栏
- mContext = this;
- }
- protected void Toasters(String message) {
- Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
- }
- }
public class BaseActivity extends FragmentActivity {protected Context mContext;@Overrideprotected void onCreate(Bundle arg0) {// TODO Auto-generated method stubsuper.onCreate(arg0);ActionBar actionBar = getActionBar();actionBar.hide();//隐藏标题栏mContext = this;}protected void Toasters(String message) {Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();}}首先,应用启动后会进入MainActivity,此Activity会加载三个Fragment,随便定义三个(首页,消息,我的)
效果图如下:
首页,消息,我的,三个fragment大同小异,布局在fragment类中加载出来就行,这里就不粘贴代码了。
最终要的是MainActivity,加载了三个fragment,点击效果,显示效果。其实是首次点击的时候首次加载了fragment,后来点击就隐藏了其他的fragment,显示了当前的fragment,这里需要处理隐藏其他的fragment,避免了多个fragment显示到界面上。
- public class MainActivity extends BaseActivity implements OnClickListener {
- /**
- * 首页
- **/
- private LinearLayout main_linear_home;
- private ImageView main_imageview_home;
- private TextView main_txtview_home;
- /**
- * 消息
- **/
- private LinearLayout main_linear_msg;
- private ImageView main_imageview_msg;
- private TextView main_txtview_msg;
- /**
- * 我的
- **/
- private LinearLayout main_linear_user;
- private ImageView main_imageview_user;
- private TextView main_txtview_user;
- /**
- * 用于对Fragment进行管理
- */
- private FragmentManager fragmentManager;
- /**
- * 选中的颜色值
- */
- private int main_txtColor_sel = 0;
- /**
- * 正常颜色值
- */
- private int main_txtColor_nol = 0;
- /**
- * FrameLayout
- */
- private FrameLayout main_new_frame;
- private HomeFragment homeFragment;
- private MessageFragment messageFragment;
- private MyFragment myFragment;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- initView();
- setOnClickEvent();
- // 初始化API
- }
- /**
- * @Description: TODO 初始化布局控件
- * @author Sunday
- * @date 2016年3月26日
- */
- private void initView() {
- // TODO Auto-generated method stub
- main_new_frame = (FrameLayout) findViewById(R.id.main_new_frame);
- // 布局
- main_linear_home = (LinearLayout) findViewById(R.id.main_linear_home);
- main_linear_msg = (LinearLayout) findViewById(R.id.main_linear_msg);
- main_linear_user = (LinearLayout) findViewById(R.id.main_linear_my);
- // 底部图片
- main_imageview_home = (ImageView) findViewById(R.id.main_imageview_home);
- main_imageview_msg = (ImageView) findViewById(R.id.main_imageview_msg);
- main_imageview_user = (ImageView) findViewById(R.id.main_imageview_my);
- // 底部文字
- main_txtview_home = (TextView) findViewById(R.id.main_txtview_home);
- main_txtview_msg = (TextView) findViewById(R.id.main_txtview_msg);
- main_txtview_user = (TextView) findViewById(R.id.main_txtview_my);
- fragmentManager = getSupportFragmentManager();
- main_txtColor_nol = getBaseContext().getResources().getColor(R.color.main_txt_nor);
- main_txtColor_sel = getBaseContext().getResources().getColor(R.color.main_txt_sel);
- setTabSelection(0);
- }
- private void setOnClickEvent() {
- main_linear_home.setOnClickListener(this);
- main_linear_msg.setOnClickListener(this);
- main_linear_user.setOnClickListener(this);
- }
- /*
- *
- */
- @Override
- public void onClick(View v) {
- // TODO Auto-generated method stub
- switch (v.getId()) {
- case R.id.main_linear_home:
- setTabSelection(0);
- break;
- case R.id.main_linear_msg:
- setTabSelection(1);
- break;
- case R.id.main_linear_my:
- setTabSelection(2);
- break;
- default:
- break;
- }
- }
- /**
- *
- * @Description: TODO 底部切换选择fragment
- * @author Sunday
- * @date 2016年3月26日
- */
- public void setTabSelection(int index) {
- // 底部切换
- clearSelection(index);
- // 开启一个Fragment事务
- FragmentTransaction transaction = fragmentManager.beginTransaction();
- // 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况
- hideFragments(transaction);
- switch (index) {
- case 0:
- if (homeFragment == null) {
- homeFragment = new HomeFragment();
- transaction.add(R.id.main_new_frame, homeFragment);
- } else {
- transaction.show(homeFragment);
- }
- break;
- case 1:
- if (messageFragment == null) {
- messageFragment = new MessageFragment();
- transaction.add(R.id.main_new_frame, messageFragment);
- } else {
- transaction.show(messageFragment);
- }
- break;
- case 2:
- if (myFragment == null) {
- myFragment = new MyFragment();
- transaction.add(R.id.main_new_frame, myFragment);
- } else {
- transaction.show(myFragment);
- }
- break;
- }
- transaction.commit();
- }
- /**
- *
- * @Description: TODO 清除选中状态
- * @author Sunday
- * @date 2016年3月26日
- */
- private void clearSelection(int index) {
- main_imageview_home.setImageResource(R.drawable.shouye_normal);
- main_txtview_home.setTextColor(main_txtColor_nol);
- main_imageview_msg.setImageResource(R.drawable.massage_normal);
- main_txtview_msg.setTextColor(main_txtColor_nol);
- main_imageview_user.setImageResource(R.drawable.my_normal);
- main_txtview_user.setTextColor(main_txtColor_nol);
- if (index == 0) {
- main_imageview_home.setImageResource(R.drawable.shouye_pressed);
- main_txtview_home.setTextColor(main_txtColor_sel);
- }
- if (index == 1) {
- main_imageview_msg.setImageResource(R.drawable.massage_pressed);
- main_txtview_msg.setTextColor(main_txtColor_sel);
- }
- if (index == 2) {
- main_imageview_user.setImageResource(R.drawable.my_pressed);
- main_txtview_user.setTextColor(main_txtColor_sel);
- }
- }
- /**
- *
- * @Description: TODO 隐藏所有的fragment,防止多个fragment显示在界面
- * @author Sunday
- * @date 2016年3月26日
- */
- private void hideFragments(FragmentTransaction transaction) {
- if (homeFragment != null) {
- transaction.hide(homeFragment);
- }
- if (messageFragment != null) {
- transaction.hide(messageFragment);
- }
- if (myFragment != null) {
- transaction.hide(myFragment);
- }
- }
- // 定义一个变量,来标识是否退出
- private static boolean isExit = false;
- Handler mHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {
- super.handleMessage(msg);
- isExit = false;
- }
- };
- /**
- * 处理返回键事件
- */
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_BACK) {
- exit();
- return false;
- }
- return super.onKeyDown(keyCode, event);
- }
- private void exit() {
- if (!isExit) {
- isExit = true;
- Toasters("再按一次退出应用");
- // 利用handler延迟发送更改状态信息
- mHandler.sendEmptyMessageDelayed(0, 2000);
- } else {
- finish();
- System.exit(0);
- }
- }
- }
public class MainActivity extends BaseActivity implements OnClickListener {/** * 首页 **/private LinearLayout main_linear_home;private ImageView main_imageview_home;private TextView main_txtview_home;/** * 消息 **/private LinearLayout main_linear_msg;private ImageView main_imageview_msg;private TextView main_txtview_msg;/** * 我的 **/private LinearLayout main_linear_user;private ImageView main_imageview_user;private TextView main_txtview_user;/** * 用于对Fragment进行管理 */private FragmentManager fragmentManager;/** * 选中的颜色值 */private int main_txtColor_sel = 0;/** * 正常颜色值 */private int main_txtColor_nol = 0;/** * FrameLayout */private FrameLayout main_new_frame;private HomeFragment homeFragment;private MessageFragment messageFragment;private MyFragment myFragment;@Overrideprotected void onCreate(Bundle savedInstanceState) {// TODO Auto-generated method stubsuper.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();setOnClickEvent();// 初始化API}/** * @Description: TODO 初始化布局控件 * @author Sunday * @date 2016年3月26日 */private void initView() {// TODO Auto-generated method stubmain_new_frame = (FrameLayout) findViewById(R.id.main_new_frame);// 布局main_linear_home = (LinearLayout) findViewById(R.id.main_linear_home);main_linear_msg = (LinearLayout) findViewById(R.id.main_linear_msg);main_linear_user = (LinearLayout) findViewById(R.id.main_linear_my);// 底部图片main_imageview_home = (ImageView) findViewById(R.id.main_imageview_home);main_imageview_msg = (ImageView) findViewById(R.id.main_imageview_msg);main_imageview_user = (ImageView) findViewById(R.id.main_imageview_my);// 底部文字main_txtview_home = (TextView) findViewById(R.id.main_txtview_home);main_txtview_msg = (TextView) findViewById(R.id.main_txtview_msg);main_txtview_user = (TextView) findViewById(R.id.main_txtview_my);fragmentManager = getSupportFragmentManager();main_txtColor_nol = getBaseContext().getResources().getColor(R.color.main_txt_nor);main_txtColor_sel = getBaseContext().getResources().getColor(R.color.main_txt_sel);setTabSelection(0);}private void setOnClickEvent() {main_linear_home.setOnClickListener(this);main_linear_msg.setOnClickListener(this);main_linear_user.setOnClickListener(this);}/* * */@Overridepublic void onClick(View v) {// TODO Auto-generated method stubswitch (v.getId()) {case R.id.main_linear_home:setTabSelection(0);break;case R.id.main_linear_msg:setTabSelection(1);break;case R.id.main_linear_my:setTabSelection(2);break;default:break;}}/** * * @Description: TODO 底部切换选择fragment * @author Sunday * @date 2016年3月26日 */public void setTabSelection(int index) {// 底部切换clearSelection(index);// 开启一个Fragment事务FragmentTransaction transaction = fragmentManager.beginTransaction();// 先隐藏掉所有的Fragment,以防止有多个Fragment显示在界面上的情况hideFragments(transaction);switch (index) {case 0:if (homeFragment == null) {homeFragment = new HomeFragment();transaction.add(R.id.main_new_frame, homeFragment);} else {transaction.show(homeFragment);}break;case 1:if (messageFragment == null) {messageFragment = new MessageFragment();transaction.add(R.id.main_new_frame, messageFragment);} else {transaction.show(messageFragment);}break;case 2:if (myFragment == null) {myFragment = new MyFragment();transaction.add(R.id.main_new_frame, myFragment);} else {transaction.show(myFragment);}break;}transaction.commit();}/** * * @Description: TODO 清除选中状态 * @author Sunday * @date 2016年3月26日 */private void clearSelection(int index) {main_imageview_home.setImageResource(R.drawable.shouye_normal);main_txtview_home.setTextColor(main_txtColor_nol);main_imageview_msg.setImageResource(R.drawable.massage_normal);main_txtview_msg.setTextColor(main_txtColor_nol);main_imageview_user.setImageResource(R.drawable.my_normal);main_txtview_user.setTextColor(main_txtColor_nol);if (index == 0) {main_imageview_home.setImageResource(R.drawable.shouye_pressed);main_txtview_home.setTextColor(main_txtColor_sel);}if (index == 1) {main_imageview_msg.setImageResource(R.drawable.massage_pressed);main_txtview_msg.setTextColor(main_txtColor_sel);}if (index == 2) {main_imageview_user.setImageResource(R.drawable.my_pressed);main_txtview_user.setTextColor(main_txtColor_sel);}}/** * * @Description: TODO 隐藏所有的fragment,防止多个fragment显示在界面 * @author Sunday * @date 2016年3月26日 */private void hideFragments(FragmentTransaction transaction) {if (homeFragment != null) {transaction.hide(homeFragment);}if (messageFragment != null) {transaction.hide(messageFragment);}if (myFragment != null) {transaction.hide(myFragment);}}// 定义一个变量,来标识是否退出private static boolean isExit = false;Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);isExit = false;}};/** * 处理返回键事件 */@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {exit();return false;}return super.onKeyDown(keyCode, event);}private void exit() {if (!isExit) {isExit = true;Toasters("再按一次退出应用");// 利用handler延迟发送更改状态信息mHandler.sendEmptyMessageDelayed(0, 2000);} else {finish();System.exit(0);}}}其实就这么简单的实现了框架的搭建,开发中其实很多项目都是采用了这种框架。
现在,我们再来研究下,让首页加载ViewPager,ViewPager嵌套了三个fragment,fragment可以点击切换,也可以滑动切换。
tab滑动的效果,我们任然是使用的第三方的开源框架PagerSlidingTabStrip,稳定性非常好,还可以随意修改源码。
首先需要将PagerSlidingTabStrip的源码下载下来,并集成到我们的项目当中,PagerSlidingTabStrip的GitHub主页地址是:https://github.com/astuetz/PagerSlidingTabStrip 。
最重要的HomeFragment的代码如下:
- public class HomeFragment extends Fragment {
- /**
- * PagerSlidingTabStrip的实例
- */
- private PagerSlidingTabStrip tabs;
- /**
- * 获取当前屏幕的密度
- */
- private DisplayMetrics dm;
- private OneFragment oneFragment;
- private TwoFragment twoFragment;
- private ThreeFragment threeFragment;
- /*
- *
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- View view = inflater.inflate(R.layout.fragment_home, null);
- setOverflowShowingAlways();
- dm = getResources().getDisplayMetrics();
- ViewPager pager = (ViewPager)view. findViewById(R.id.pager);
- pager.setOffscreenPageLimit(0);//设置ViewPager的缓存界面数,默认缓存为2
- tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);
- pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));
- tabs.setViewPager(pager);
- setTabsValue();
- return view;
- }
- /**
- * 对PagerSlidingTabStrip的各项属性进行赋值。
- */
- private void setTabsValue() {
- // 设置Tab是自动填充满屏幕的
- tabs.setShouldExpand(true);
- // 设置Tab的分割线是透明的
- tabs.setDividerColor(Color.TRANSPARENT);
- // 设置Tab底部线的高度
- tabs.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, dm));
- // 设置Tab Indicator的高度
- tabs.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, dm));
- // 设置Tab标题文字的大小
- tabs.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, dm));
- // 设置Tab Indicator的颜色
- tabs.setIndicatorColor(Color.parseColor("#d83737"));//#d83737 #d83737(绿)
- // 设置选中Tab文字的颜色 (这是我自定义的一个方法)
- tabs.setSelectedTextColor(Color.parseColor("#ffffff"));
- // 取消点击Tab时的背景色
- tabs.setTabBackground(0);
- }
- public class MyPagerAdapter extends FragmentPagerAdapter {
- public MyPagerAdapter(FragmentManager fm) {
- super(fm);
- }
- private final String[] titles = { "TAB1", "TAB2", "TAB3" };
- @Override
- public CharSequence getPageTitle(int position) {
- return titles[position];
- }
- @Override
- public int getCount() {
- return titles.length;
- }
- @Override
- public Fragment getItem(int position) {
- switch (position) {
- case 0:
- if (oneFragment == null) {
- oneFragment = new OneFragment();
- }
- return oneFragment;
- case 1:
- if (twoFragment == null) {
- twoFragment = new TwoFragment();
- }
- return twoFragment;
- case 2:
- if (threeFragment == null) {
- threeFragment = new ThreeFragment();
- }
- return threeFragment;
- default:
- return null;
- }
- }
- }
- private void setOverflowShowingAlways() {
- try {
- ViewConfiguration config = ViewConfiguration.get(getParentFragment().getActivity());
- Field menuKeyField = ViewConfiguration.class
- .getDeclaredField("sHasPermanentMenuKey");
- menuKeyField.setAccessible(true);
- menuKeyField.setBoolean(config, false);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
public class HomeFragment extends Fragment {/** * PagerSlidingTabStrip的实例 */private PagerSlidingTabStrip tabs;/** * 获取当前屏幕的密度 */private DisplayMetrics dm;private OneFragment oneFragment;private TwoFragment twoFragment;private ThreeFragment threeFragment;/* * */@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {// TODO Auto-generated method stubView view = inflater.inflate(R.layout.fragment_home, null);setOverflowShowingAlways();dm = getResources().getDisplayMetrics();ViewPager pager = (ViewPager)view. findViewById(R.id.pager);pager.setOffscreenPageLimit(0);//设置ViewPager的缓存界面数,默认缓存为2tabs = (PagerSlidingTabStrip) view.findViewById(R.id.tabs);pager.setAdapter(new MyPagerAdapter(getChildFragmentManager()));tabs.setViewPager(pager);setTabsValue();return view;}/** * 对PagerSlidingTabStrip的各项属性进行赋值。 */private void setTabsValue() {// 设置Tab是自动填充满屏幕的tabs.setShouldExpand(true);// 设置Tab的分割线是透明的tabs.setDividerColor(Color.TRANSPARENT);// 设置Tab底部线的高度tabs.setUnderlineHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, dm));// 设置Tab Indicator的高度tabs.setIndicatorHeight((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, dm));// 设置Tab标题文字的大小tabs.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16, dm));// 设置Tab Indicator的颜色tabs.setIndicatorColor(Color.parseColor("#d83737"));//#d83737 #d83737(绿)// 设置选中Tab文字的颜色 (这是我自定义的一个方法)tabs.setSelectedTextColor(Color.parseColor("#ffffff"));// 取消点击Tab时的背景色tabs.setTabBackground(0);}public class MyPagerAdapter extends FragmentPagerAdapter {public MyPagerAdapter(FragmentManager fm) {super(fm);}private final String[] titles = { "TAB1", "TAB2", "TAB3" };@Overridepublic CharSequence getPageTitle(int position) {return titles[position];}@Overridepublic int getCount() {return titles.length;}@Overridepublic Fragment getItem(int position) {switch (position) {case 0:if (oneFragment == null) {oneFragment = new OneFragment();}return oneFragment;case 1:if (twoFragment == null) {twoFragment = new TwoFragment();}return twoFragment;case 2:if (threeFragment == null) {threeFragment = new ThreeFragment();}return threeFragment;default:return null;}}}private void setOverflowShowingAlways() {try {ViewConfiguration config = ViewConfiguration.get(getParentFragment().getActivity());Field menuKeyField = ViewConfiguration.class.getDeclaredField("sHasPermanentMenuKey");menuKeyField.setAccessible(true);menuKeyField.setBoolean(config, false);} catch (Exception e) {e.printStackTrace();}}}
其次,布局文件也拿上来了
- <?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" >
- <com.sunday.slidetabfragment.view.PagerSlidingTabStrip
- android:id="@+id/tabs"
- android:layout_width="match_parent"
- android:layout_height="45dp"
- android:background="@color/light_black_bg" />
- <android.support.v4.view.ViewPager
- android:id="@+id/pager"
- android:layout_width="match_parent"
- android:layout_height="wrap_content" />
- </LinearLayout>
<?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" > <com.sunday.slidetabfragment.view.PagerSlidingTabStrip android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="45dp" android:background="@color/light_black_bg" /> <android.support.v4.view.ViewPager android:id="@+id/pager" android:layout_width="match_parent" android:layout_height="wrap_content" /></LinearLayout>
最终的效果图如下:
效果就如期待的那样,是不是觉得超级简单。如果要是觉得难看,tab样式和颜色当然是可以修改的,图片也可以使用UI设计的。
源码地址,点击下载
- Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment
- Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment
- Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment
- Android ViewPager嵌套Fragment
- viewPager+fragment嵌套viewPager+fragment
- ViewPager+Fragment嵌套ViewPager+Fragment
- Android解决ViewPager嵌套Fragment,Fragment嵌套ViewPager滑动冲突
- Android解决ViewPager嵌套Fragment,Fragment嵌套ViewPager滑动冲突
- Fragment里面嵌套ViewPager
- ViewPager+Fragment嵌套
- Fragment嵌套ViewPager
- fragment嵌套viewpager
- ViewPager嵌套Fragment
- Fragment+Viewpager+嵌套Tablelayout+fragment
- Fragment嵌套Fragment和Viewpager
- Fragment嵌套Fragment和Viewpager
- Viewpager+Fragment嵌套Viewpager+Fragment空白页问题
- ViewPager+Fragment以及Fragment嵌套ViewPager
- C++之拷贝函数
- RESIZE方法解决临时表空间过大问题
- Xquery编辑中字符串的拼接
- mysql-installer-community安装gething required infomation后闪退
- shell脚本的三种调用方式
- Android Fragment嵌套ViewPager,ViewPager嵌套多个Fragment
- 重建临时表空间解决临时表空间过大问题
- 【Hadoop】HDFS的运行原理
- Java学习路线个人看法
- thinkphp5 引入前台、后台模板方法
- JVM自带性能分析工具介绍——jstack
- SizeClass的使用介绍
- 分享好的卷积神经网络分析(转载)
- 哈希离散化