首页 > 代码库 > 低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航
低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航
Tab经常和Fragment结合使用,这一讲我们用3种方式来实现这种快捷导航。
0、重要的两个监听器
MyTabListener,这个我们之前已经接触过了
package com.kale.actionbar05;import android.support.v4.app.FragmentTransaction;import android.support.v4.view.ViewPager;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBar.Tab;/** * @author:Jack Tony * @tips :设置tab的监听器,控制viewpager的显示 * @date :2014-7-30 */public class MyTabListener implements ActionBar.TabListener{ ViewPager viewPager; public MyTabListener(ViewPager viewPager) { this.viewPager =viewPager; } @Override public void onTabReselected(Tab arg0, FragmentTransaction arg1) { } @Override public void onTabSelected(Tab tab, FragmentTransaction arg1) { if (viewPager != null && viewPager.getCurrentItem() != tab.getPosition()){ viewPager.setCurrentItem(tab.getPosition()); } } @Override public void onTabUnselected(Tab arg0, FragmentTransaction arg1) { } }
PageChangeListener(这里面是滑动ViewPager会触发的动作)
package com.kale.actionbar05;import android.support.v4.view.ViewPager;import android.support.v7.app.ActionBar;public class PageChangeListener implements ViewPager.OnPageChangeListener { private ActionBar actionBar; public PageChangeListener(ActionBar actionBar) { this.actionBar = actionBar; } @Override public void onPageScrollStateChanged(int arg0) { // TODO 自动生成的方法存根 } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { // TODO 自动生成的方法存根 } @Override public void onPageSelected(int position) { //System.out.println("position:" + position); actionBar.setSelectedNavigationItem(position); }}
一、Tab+ViewPager
先定义一个主布局,里面放入ViewPager。我们即将在这个ViewPager中放入视图
view_main.xml
<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.support.v4.view.ViewPager android:id="@+id/viewPager01" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:text="下面是ViewPager" android:textAppearance="?android:attr/textAppearanceLarge" /></RelativeLayout>
view_item.xml
这是准备放入ViewPager的视图。我们放3个TextView,然后再放入这整个视图
<?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" > <ImageView android:layout_width="100dp" android:layout_height="100dp" android:layout_gravity="center_horizontal" android:src="@drawable/ic_launcher" /> <TextView android:id="@+id/viewItem_textView" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:text="No 4" android:textSize="40sp"/></LinearLayout>
ViewMainActivity
package com.kale.actionbar05.view;import java.util.ArrayList;import com.kale.actionbar05.MyTabListener;import com.kale.actionbar05.PageChangeListener;import com.kale.actionbar05.R;import android.os.Bundle;import android.support.v4.view.ViewPager;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBarActivity;import android.view.LayoutInflater;import android.view.View;import android.widget.TextView;public class ViewMainActivity extends ActionBarActivity { private ActionBar actionBar; private ArrayList<View> viewList; ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.view_main); initView(); initActionBar(); viewList = new ArrayList<View>(); //得到填充器,准备获得对象 LayoutInflater mLayoutInflater = getLayoutInflater(); //给适配器准备好数据,添加进list中 for (int i = 0; i < 3; i++) { TextView tv = (TextView)(mLayoutInflater.inflate(R.layout.view_item, null)) .findViewById(R.id.viewItem_textView); tv.setText("No "+(i+1)); viewList.add(tv); } viewList.add(mLayoutInflater.inflate(R.layout.view_item, null));//也可以直接用布局做一个视图 //内容准备好后,设置适配器 viewPager.setAdapter(new MyPagerAdapter(viewList)); viewPager.setOnPageChangeListener(new PageChangeListener(getSupportActionBar())); } /** *初始化actionBar和Tab */ private void initActionBar() { actionBar = getSupportActionBar(); //设定有Tab actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); ActionBar.Tab tab; //开始添加Tab for (int i = 1; i <= 4; i++) { tab = actionBar.newTab(); tab.setText("Tab " + i); tab.setTabListener(new MyTabListener(viewPager)); actionBar.addTab(tab); } } private void initView() { viewPager = (ViewPager)findViewById(R.id.viewPager01); }}
MyPagerAdapter(这里设置适配器,从list中得到一个个View,然后展现出来)
package com.kale.actionbar05.view;import java.util.ArrayList;import android.support.v4.view.PagerAdapter;import android.support.v4.view.ViewPager;import android.view.View;import android.view.ViewGroup;public class MyPagerAdapter extends PagerAdapter { private ArrayList<View> mViewList; private int pagerNum = 0; public MyPagerAdapter(ArrayList<View> viewList) { mViewList = viewList; } public int getPagerNum() { return pagerNum; } @Override public int getCount() { return mViewList.size(); } @Override public boolean isViewFromObject(View arg0, Object arg1) { return arg0 == arg1; } @Override public void destroyItem(View arg0, int arg1, Object arg2) { if (mViewList.get(arg1) != null) { ((ViewPager) arg0).removeView(mViewList.get(arg1)); } } @Override public Object instantiateItem(View arg0, int arg1) { try { if (mViewList.get(arg1).getParent() == null) { ((ViewPager) arg0).addView(mViewList.get(arg1), 0); } else { /* * 很难理解新添加进来的view会自动绑定一个父类,由于一个儿子view不能与两个父类相关, 所以得解绑不这样做否则会产生 * viewpager java.lang.IllegalStateException: The specified * child already has a parent. You must call removeView() on the * child‘s parent first. */ ((ViewGroup) mViewList.get(arg1).getParent()) .removeView(mViewList.get(arg1)); ((ViewPager) arg0).addView(mViewList.get(arg1), 0); } } catch (Exception e) { e.printStackTrace(); } finally { pagerNum = arg1; } return mViewList.get(arg1); }}
二、Tab+Fragment+ViewPager
fragment_main.xml (主布局)
<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.support.v4.view.ViewPager android:id="@+id/viewPager02" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" /></RelativeLayout>
DummyFragment(准备填充进去的Fragment,这里面接受一个参数用来方便说明)
package com.kale.actionbar05.fragment;import android.os.Bundle;import android.support.annotation.Nullable;import android.support.v4.app.Fragment;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.TextView;public class DummyFragment extends Fragment { public static final String BUNDLE_SECTION_NUMBER = "section_number"; // 该返回值就是这个Fragment显示的view组件 @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); TextView textView = new TextView(getActivity()); textView.setGravity(Gravity.CENTER); // 获取创建该Fragment时传入的参数的Bundle Bundle bundle = getArguments(); textView.setText("Fragment 0" + bundle.getInt(BUNDLE_SECTION_NUMBER)); textView.setTextSize(50); return textView; }}
FragmentMainActivity
package com.kale.actionbar05.fragment;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentPagerAdapter;import android.support.v4.app.FragmentStatePagerAdapter;import android.support.v4.view.ViewPager;import android.support.v7.app.ActionBar;import android.support.v7.app.ActionBarActivity;import android.view.ViewGroup;import com.kale.actionbar05.MyTabListener;import com.kale.actionbar05.PageChangeListener;import com.kale.actionbar05.R;/** * @author:Jack Tony * @tips :出于使用FragmentPagerAdapter 时,Fragment对象会一直存留在内存中. * 所以当有大量的显示页时,就不适合用FragmentPagerAdapter了 * ,FragmentPagerAdapter适用于只有少数的page情况。 * 多的话请考虑使用FragmentStatePagerAdapter,当使用FragmentStatePagerAdapter时, * 如果Fragment不显示,那么Fragment对象会被销毁,但在回调onDestroy()方法之前 * 会回调onSaveInstanceState(Bundle outState)方法来保存Fragment的状态, * 下次Fragment显示时通过onCreate(Bundle savedInstanceState)把存储的状态值取出来, * FragmentStatePagerAdapter 比较适合页面比较多的情况,像一个页面的ListView * @date :2014-7-30 */public class FragmentMainActivity extends ActionBarActivity { ActionBar actionBar; ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { // TODO 自动生成的方法存根 super.onCreate(savedInstanceState); setContentView(R.layout.fragment_main); initView(); initActionBar(); viewPager.setAdapter(new MyFragmentPagerAdapter( getSupportFragmentManager())); //下面是用另一种适配器的方式,其实就是换个名字。主要针对的是很多个fragment的情况 //viewPager.setAdapter(new MyFragmentStaticAdapter(getSupportFragmentManager())); viewPager.setOnPageChangeListener(new PageChangeListener(actionBar)); } public class MyFragmentPagerAdapter extends FragmentPagerAdapter { private int NUM_ITEMS = 4; public MyFragmentPagerAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { Fragment fragment = new DummyFragment(); Bundle args = new Bundle(); args.putInt(DummyFragment.BUNDLE_SECTION_NUMBER, position + 1); fragment.setArguments(args); return fragment; } @Override public int getCount() { return NUM_ITEMS; } @Override public void destroyItem(ViewGroup container, int position, Object object) { // 这里Destroy的是Fragment的视图层次,并不是Destroy Fragment对象 super.destroyItem(container, position, object); //Log.i("INFO", "Destroy Item " + position); } } private void initView() { viewPager = (ViewPager) findViewById(R.id.viewPager02); } /** * 初始化actionBar和Tab */ private void initActionBar() { actionBar = getSupportActionBar(); // 设定有Tab actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); ActionBar.Tab tab; // 开始添加Tab for (int i = 1; i <= 4; i++) { tab = actionBar.newTab(); tab.setText("Tab " + i); tab.setTabListener(new MyTabListener(viewPager)); actionBar.addTab(tab); } } public class MyFragmentStaticAdapter extends FragmentStatePagerAdapter { private int NUM_ITEMS = 5; public MyFragmentStaticAdapter(FragmentManager fm) { super(fm); } @Override public Fragment getItem(int position) { Fragment fragment = new DummyFragment(); Bundle args = new Bundle(); args.putInt(DummyFragment.BUNDLE_SECTION_NUMBER, position + 1); fragment.setArguments(args); return fragment; } @Override public int getCount() { return NUM_ITEMS; } }}
三、PagerSlidingTabStrip+ViewPager+Fragment
tab_main.xml
<LinearLayout 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:orientation="vertical" xmlns:app="http://schemas.android.com/apk/res/com.kale.actionbar05"> <com.astuetz.PagerSlidingTabStrip android:id="@+id/tabs" android:layout_width="match_parent" android:layout_height="40dp" app:pstsShouldExpand="true" app:pstsUnderlineHeight="1dp" app:pstsIndicatorHeight="4dp" app:pstsIndicatorColor="#45c01a" app:pstsSelectedTabTextColor="#45c01a" app:pstsTabTextSize="16sp" app:pstsTabTextColor="#666666" app:pstsDividerColor="@android:color/transparent" /> <android.support.v4.view.ViewPager android:id="@+id/viewPager03" android:layout_width="match_parent" android:layout_height="match_parent" android:visibility="visible" /></LinearLayout>
ChatFragment (其中的一个Fragment,其余的都一样,就是文字变了)
package com.kale.actionbar05.tab;import android.app.ActionBar.LayoutParams;import android.os.Bundle;import android.support.v4.app.Fragment;import android.util.DisplayMetrics;import android.util.TypedValue;import android.view.Gravity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.FrameLayout;import android.widget.TextView;public class ChatFragment extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); FrameLayout fl = new FrameLayout(getActivity()); fl.setLayoutParams(params); DisplayMetrics dm = getResources().getDisplayMetrics(); final int margin = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 8, dm); TextView v = new TextView(getActivity()); params.setMargins(margin, margin, margin, margin); v.setLayoutParams(params); v.setLayoutParams(params); v.setGravity(Gravity.CENTER); v.setText("聊天界面"); v.setTextSize((int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 12, dm)); fl.addView(v); return fl; }}
TabMainActivity(定义个Tab,然后设定个ViewPager就行了。Fragment在适配器中设置)
package com.kale.actionbar05.tab;import android.graphics.Color;import android.os.Bundle;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.v7.app.ActionBarActivity;import android.util.DisplayMetrics;import android.util.TypedValue;import com.astuetz.PagerSlidingTabStrip;import com.kale.actionbar05.R;public class TabMainActivity extends ActionBarActivity { private ChatFragment chatFragment; private FoundFragment foundFragment; private ContactsFragment contactsFragment; /** * PagerSlidingTabStrip的实例 */ private PagerSlidingTabStrip tabs; private ViewPager viewPager; @Override protected void onCreate(Bundle savedInstanceState) { // TODO 自动生成的方法存根 super.onCreate(savedInstanceState); setContentView(R.layout.tab_main); initView(); //initTabs(); //用代码来设置tab的样式,因为我在xml中已经设置了,所以就不在代码中写了 viewPager.setAdapter(new MyPagerAdapter(getSupportFragmentManager())); tabs.setViewPager(viewPager); } /** * @author:Jack Tony * @tips :定义适配器,返回一个fragment对象 * @date :2014-7-30 */ public class MyPagerAdapter extends FragmentPagerAdapter { public MyPagerAdapter(FragmentManager fm) { super(fm); } private final String[] titles = { "聊天", "发现", "通讯录" }; @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 (chatFragment == null) { chatFragment = new ChatFragment(); } return chatFragment; case 1: if (foundFragment == null) { foundFragment = new FoundFragment(); } return foundFragment; case 2: if (contactsFragment == null) { contactsFragment = new ContactsFragment(); } return contactsFragment; default: return null; } } } /** *定义的属性,参考:https://github.com/astuetz/PagerSlidingTabStrip */ private void initTabs() { /** * 获取当前屏幕的密度 */ DisplayMetrics dm; dm = getResources().getDisplayMetrics(); // 设置Tab是自动填充满屏幕,也就是均分屏幕宽度,每个tab的weight都是一致的 app:pstsShouldExpand="true" tabs.setShouldExpand(true); // 设置Tab的分割线是透明的 app:pstsDividerColor="@android:color/transparent" tabs.setDividerColor(Color.TRANSPARENT); // 设置Tab底部与下面分割的细线的高度 app:pstsUnderlineHeight="1dp" tabs.setUnderlineHeight((int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 1, dm)); // 设置Tab 指示器的高度 app:pstsIndicatorHeight="4dp" tabs.setIndicatorHeight((int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, 4, dm)); // 设置Tab标题文字的大小 app:pstsTabTextSize="16sp" tabs.setTextSize((int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, 16, dm)); // 设置Tab Indicator的颜色 app:pstsIndicatorColor="#45c01a" tabs.setIndicatorColor(Color.parseColor("#45c01a")); // 设置选中Tab文字的颜色 app:pstsSelectedTabTextColor="#45c01a" tabs.setSelectedTextColor(Color.parseColor("#45c01a")); // 取消点击Tab时的背景色 app:pstsTabBackground="0" tabs.setTabBackground(0); } private void initView() { tabs = (PagerSlidingTabStrip) findViewById(R.id.tabs); viewPager = (ViewPager) findViewById(R.id.viewPager03); }}
源码下载:http://download.csdn.net/detail/shark0017/7696295
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。