码迷,mamicode.com
首页 > 其他好文 > 详细

低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航

时间:2014-07-30 20:35:44      阅读:366      评论:0      收藏:0      [点我收藏+]

标签:android   des   style   blog   http   color   java   使用   

bubuko.com,布布扣

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

bubuko.com,布布扣

先定义一个主布局,里面放入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

bubuko.com,布布扣 这是准备放入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

bubuko.com,布布扣

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

bubuko.com,布布扣

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

低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航,布布扣,bubuko.com

低版本系统兼容的ActionBar(六)用Fragment+ViewPager+Tab实现快速导航

标签:android   des   style   blog   http   color   java   使用   

原文地址:http://www.cnblogs.com/tianzhijiexian/p/3878806.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!