前几天,项目中要实现这么一个功能。就配置了下。其实很简单,首先 需要阅读下我转载的前两篇文章,都是转载的郭神的,写的非常好。我的项目中逢者必用,其实就相当于一个很好的框架来使用,非常方便。
前两篇的项目地址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(); } }首先,应用启动后会进入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); } } }其实就这么简单的实现了框架的搭建,开发中其实很多项目都是采用了这种框架。
现在,我们再来研究下,让首页加载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(); } } }
<?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设计的。
源码地址,点击下载