简要:之前看过很多文章实现Fragment和ViewPager的结合使用,这样就可以实现滑动的Fragment。但是 JazzyViewPager加FragmentTabHost可以说是一个升级版,JazzyViewPager增加了ViewPager的切换效果,FragmentTabHost更加的灵活。注意事项已经在代码里注释很详细了,本人能力有限,错误之处请大家多多指正,在此谢谢!
要点:FragmentTabHost基本可以理解为一个封装好的工具类,我们只需要调用即可,JazzyViewPager使用需要导入nineoldandroids-2.4.0.jar类库,JazzyViewPager说直白点就是丰富viewpager切换样式。
扩展:http://blog.csdn.net/u012372365/article/details/52238469
1.目录结构:
2.代码片段
FragmentTabHost代码:
package com.example.lin_tab_demo;
import java.util.ArrayList;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.TabHost;
import android.widget.TabWidget;
/**
* Special TabHost that allows the use of {@link Fragment} objects for its tab
* content. When placing this in a view hierarchy, after inflating the hierarchy
* you must call {@link #setup(Context, FragmentManager, int)} to complete the
* initialization of the tab host.
*
* <p>
* Here is a simple example of using a FragmentTabHost in an Activity:
*
* {@sample
* development/samples/Support4Demos/src/com/example/android/supportv4/app/
* FragmentTabs.java complete}
*
* <p>
* This can also be used inside of a fragment through fragment nesting:
*
* {@sample
* development/samples/Support4Demos/src/com/example/android/supportv4/app/
* FragmentTabsFragmentSupport.java complete}
*/
public class FragmentTabHost extends TabHost implements
TabHost.OnTabChangeListener {
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
private FrameLayout mRealTabContent;
private Context mContext;
private FragmentManager mFragmentManager;
private int mContainerId;
private TabHost.OnTabChangeListener mOnTabChangeListener;
private TabInfo mLastTab;
private boolean mAttached;
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
private Fragment fragment;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
static class SavedState extends BaseSavedState {
String curTab;
SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
curTab = in.readString();
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeString(curTab);
}
@Override
public String toString() {
return "FragmentTabHost.SavedState{"
+ Integer.toHexString(System.identityHashCode(this))
+ " curTab=" + curTab + "}";
}
public static final Parcelable.Creator<SavedState> CREATOR = new Parcelable.Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
public FragmentTabHost(Context context) {
// Note that we call through to the version that takes an AttributeSet,
// because the simple Context construct can result in a broken object!
super(context, null);
initFragmentTabHost(context, null);
}
public FragmentTabHost(Context context, AttributeSet attrs) {
super(context, attrs);
initFragmentTabHost(context, attrs);
}
private void initFragmentTabHost(Context context, AttributeSet attrs) {
TypedArray a = context.obtainStyledAttributes(attrs,
new int[] { android.R.attr.inflatedId }, 0, 0);
mContainerId = a.getResourceId(0, 0);
a.recycle();
super.setOnTabChangedListener(this);
}
private void ensureHierarchy(Context context) {
// If owner hasn't made its own view hierarchy, then as a convenience
// we will construct a standard one here.
if (findViewById(android.R.id.tabs) == null) {
LinearLayout ll = new LinearLayout(context);
ll.setOrientation(LinearLayout.VERTICAL);
addView(ll, new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
TabWidget tw = new TabWidget(context);
tw.setId(android.R.id.tabs);
tw.setOrientation(TabWidget.HORIZONTAL);
ll.addView(tw, new LinearLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT, 0));
FrameLayout fl = new FrameLayout(context);
fl.setId(android.R.id.tabcontent);
ll.addView(fl, new LinearLayout.LayoutParams(0, 0, 0));
mRealTabContent = fl = new FrameLayout(context);
mRealTabContent.setId(mContainerId);
ll.addView(fl, new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT, 0, 1));
}
}
/**
* @deprecated Don't call the original TabHost setup, you must instead call
* {@link #setup(Context, FragmentManager)} or
* {@link #setup(Context, FragmentManager, int)}.
*/
@Override
@Deprecated
public void setup() {
throw new IllegalStateException(
"Must call setup() that takes a Context and FragmentManager");
}
public void setup(Context context, FragmentManager manager) {
ensureHierarchy(context); // Ensure views required by super.setup()
super.setup();
mContext = context;
mFragmentManager = manager;
ensureContent();
}
public void setup(Context context, FragmentManager manager, int containerId) {
ensureHierarchy(context); // Ensure views required by super.setup()
super.setup();
mContext = context;
mFragmentManager = manager;
mContainerId = containerId;
ensureContent();
mRealTabContent.setId(containerId);
// We must have an ID to be able to save/restore our state. If
// the owner hasn't set one at this point, we will set it ourself.
if (getId() == View.NO_ID) {
setId(android.R.id.tabhost);
}
}
private void ensureContent() {
if (mRealTabContent == null) {
mRealTabContent = (FrameLayout) findViewById(mContainerId);
if (mRealTabContent == null) {
throw new IllegalStateException(
"No tab content FrameLayout found for id "
+ mContainerId);
}
}
}
@Override
public void setOnTabChangedListener(OnTabChangeListener l) {
mOnTabChangeListener = l;
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
if (mAttached) {
// If we are already attached to the window, then check to make
// sure this tab's fragment is inactive if it exists. This shouldn't
// normally happen.
info.fragment = mFragmentManager.findFragmentByTag(tag);
if (info.fragment != null && !info.fragment.isDetached()) {
FragmentTransaction ft = mFragmentManager.beginTransaction();
// ft.detach(info.fragment);
ft.hide(info.fragment);
ft.commit();
}
}
mTabs.add(info);
addTab(tabSpec);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
String currentTab = getCurrentTabTag();
// Go through all tabs and make sure their fragments match
// the correct state.
FragmentTransaction ft = null;
for (int i = 0; i < mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
tab.fragment = mFragmentManager.findFragmentByTag(tab.tag);
// if (tab.fragment != null && !tab.fragment.isDetached()) {
if (tab.fragment != null) {
if (tab.tag.equals(currentTab)) {
// The fragment for this tab is already there and
// active, and it is what we really want to have
// as the current tab. Nothing to do.
mLastTab = tab;
} else {
// This fragment was restored in the active state,
// but is not the current tab. Deactivate it.
if (ft == null) {
ft = mFragmentManager.beginTransaction();
}
// ft.detach(tab.fragment);
ft.hide(tab.fragment);
}
}
}
// We are now ready to go. Make sure we are switched to the
// correct tab.
mAttached = true;
ft = doTabChanged(currentTab, ft);
if (ft != null) {
ft.commit();
mFragmentManager.executePendingTransactions();
}
}
@Override
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mAttached = false;
}
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState ss = new SavedState(superState);
ss.curTab = getCurrentTabTag();
return ss;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
setCurrentTabByTag(ss.curTab);
}
@Override
public void onTabChanged(String tabId) {
if (mAttached) {
FragmentTransaction ft = doTabChanged(tabId, null);
if (ft != null) {
ft.commit();
}
}
if (mOnTabChangeListener != null) {
mOnTabChangeListener.onTabChanged(tabId);
}
}
private FragmentTransaction doTabChanged(String tabId,
FragmentTransaction ft) {
TabInfo newTab = null;
for (int i = 0; i < mTabs.size(); i++) {
TabInfo tab = mTabs.get(i);
if (tab.tag.equals(tabId)) {
newTab = tab;
}
}
if (newTab == null) {
throw new IllegalStateException("No tab known for tag " + tabId);
}
if (mLastTab != newTab) {
if (ft == null) {
ft = mFragmentManager.beginTransaction();
}
if (mLastTab != null) {
if (mLastTab.fragment != null) {
// ft.detach(mLastTab.fragment);
ft.hide(mLastTab.fragment);
}
}
if (newTab != null) {
if (newTab.fragment == null) {
newTab.fragment = Fragment.instantiate(mContext,
newTab.clss.getName(), newTab.args);
ft.add(mContainerId, newTab.fragment, newTab.tag);
} else {
// ft.attach(newTab.fragment);
ft.show(newTab.fragment);
}
}
mLastTab = newTab;
}
return ft;
}
}
main实现类:
package aa.a3;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.TabHost;
import android.widget.TextView;
import com.nineoldandroids.view.ViewHelper;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import aa.a3.adapter.MainPagerAdapter;
import aa.a3.fragment.er_fragment;
import aa.a3.fragment.san_fragment;
import aa.a3.fragment.yi_fragment;
import aa.a3.tool.FragmentTabHost;
import aa.a3.tool.JazzyViewPager;
public class MainActivity extends FragmentActivity {
private LayoutInflater layoutinflater;
// 定义数组来存放Fragment界面
private Class mfragmentArray[] = { yi_fragment.class, er_fragment.class,san_fragment.class };
// 定义栏目的名称
private String mtextviewArray[] = { "首页", "军事", "科技" };
//定义关闭按钮的图片
private int off_mimageArray[]={R.mipmap.yi,R.mipmap.er,R.mipmap.san};
//定义开启按钮的图片
private int on_mimageArray[]={R.mipmap.yiyi,R.mipmap.erer,R.mipmap.sansan};
FragmentTabHost tabhost;
private List<Map<String, View>> tabViews = new ArrayList<Map<String, View>>();
private JazzyViewPager jazzyPager;
private MainPagerAdapter mainPagerAdapter;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initview();
initJazzyPager();
}
private void initview() {
//layoutinflater.inflate(R.layout.item_layout, null);
tabhost=(FragmentTabHost) findViewById(android.R.id.tabhost);
//初始化tabhost
tabhost.setup(this, getSupportFragmentManager(), R.id.realtabcontent);
//给每一个tab添加视图(图片文字) 还有对应的fragment
for (int i = 0; i < mtextviewArray.length; i++) {
tabhost.addTab(tabhost.newTabSpec(i+"").setIndicator(createTab(i)),mfragmentArray[i],null);
}
// 设置Tab按钮的背景
tabhost.getTabWidget().setDividerDrawable(R.color.white);
// 设置Tab按钮的点击事件
tabhost.setOnTabChangedListener(new TabHost.OnTabChangeListener() {
public void onTabChanged(String tabId) {
//点击Tab的int值(即第几个,默认初始下标为0)
int index = Integer.parseInt(tabId);
setTabSelectedState(index, mfragmentArray.length);
}
});
// 设置Tab按钮的默认选项
tabhost.setCurrentTab(0);
}
//设置每个Tab的样式
private View createTab(int id) {
View tabIndicator = LayoutInflater.from(this).inflate(R.layout.item_layout, null);
TextView normal_tv = (TextView) tabIndicator.findViewById(R.id.normal_tv);
TextView selected_tv = (TextView) tabIndicator.findViewById(R.id.selected_tv);
normal_tv.setText(mtextviewArray[id]);
selected_tv.setText(mtextviewArray[id]);
ImageView normal_iv = (ImageView) tabIndicator.findViewById(R.id.normal_iv);
ImageView selected_iv = (ImageView) tabIndicator.findViewById(R.id.selected_iv);
normal_iv.setImageResource(off_mimageArray[id]);
selected_iv.setImageResource(on_mimageArray[id]);
View normal_layout = tabIndicator.findViewById(R.id.normal_layout);
normal_layout.setAlpha(1f);
View selected_layout = tabIndicator.findViewById(R.id.selected_layout);
selected_layout.setAlpha(0f);
Map<String, View> map = new HashMap<String, View>();
map.put("ALPHA_NORMAL", normal_layout);
map.put("ALPHA_SELECTED", selected_layout);
tabViews.add(map);
return tabIndicator;
}
//设置每个Tab点击样式切换
private void setTabSelectedState(int index, int tabCount) {
System.out.println("index="+index+"tabCount"+tabCount);
for (int i = 0; i < tabCount; i++) {
if (i == index) {
tabViews.get(i).get("ALPHA_NORMAL").setAlpha(0f);
tabViews.get(i).get("ALPHA_SELECTED").setAlpha(1f);
} else {
tabViews.get(i).get("ALPHA_NORMAL").setAlpha(1f);
tabViews.get(i).get("ALPHA_SELECTED").setAlpha(0f);
}
}
//设置ViewPager的显示页》》注:jazzyPager.setCurrentItem(index)继承这个方法会造成Tab无法删除有残留
jazzyPager.setCurrentItem(index, false);
}
/**
* ViewPager
* */
private void initJazzyPager() {
jazzyPager = (JazzyViewPager) findViewById(R.id.realtabcontent);
jazzyPager.setOffscreenPageLimit(5);
//Viewpager的间隔
jazzyPager.setPageMargin(30);
jazzyPager.setFadeEnabled(true);
//设置ViewPager的切换样式(可选样式:* Standard* Tablet* CubeIn* CubeOut* FlipVertical* FlipHorizontal* Stack* ZoomIn* ZoomOut* RotateUp* RotateDown* Accordion)
jazzyPager.setTransitionEffect(JazzyViewPager.TransitionEffect.CubeOut);
jazzyPager.setSlideCallBack(new JazzyViewPager.SlideCallback() {
@Override
public void callBack(int position, float positionOffset) {
Map<String, View> map = tabViews.get(position);
ViewHelper.setAlpha(map.get("ALPHA_SELECTED"), positionOffset);
ViewHelper.setAlpha(map.get("ALPHA_NORMAL"), 1 - positionOffset);
}
});
mainPagerAdapter = new MainPagerAdapter(getSupportFragmentManager(), jazzyPager);
jazzyPager.setAdapter(mainPagerAdapter);
jazzyPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
public void onPageSelected(int position) {
// 设置Tab按钮的默认选项
tabhost.setCurrentTab(position);
}
public void onPageScrollStateChanged(int state) {
}
});
}
}
JazzyViewPager 代码:
package aa.a3.tool;
import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Camera;
import android.graphics.Color;
import android.graphics.Matrix;
import android.os.Build;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.jfeinstein.jazzyviewpager.OutlineContainer;
import com.nineoldandroids.view.ViewHelper;
import java.util.HashMap;
import java.util.LinkedHashMap;
import aa.a3.R;
public class JazzyViewPager extends ViewPager {
public static final String TAG = "JazzyViewPager";
private boolean mEnabled = true;
private boolean mFadeEnabled = false;
private boolean mOutlineEnabled = false;
public static int sOutlineColor = Color.WHITE;
private TransitionEffect mEffect = TransitionEffect.Standard;
private HashMap<Integer, Object> mObjs = new LinkedHashMap<Integer, Object>();
private static final float SCALE_MAX = 0.5f;
private static final float ZOOM_MAX = 0.5f;
private static final float ROT_MAX = 15.0f;
public enum TransitionEffect {
Standard, Tablet, CubeIn, CubeOut, FlipVertical, FlipHorizontal, Stack, ZoomIn, ZoomOut, RotateUp, RotateDown, Accordion
}
private static final boolean API_11;
static {
API_11 = Build.VERSION.SDK_INT >= 11;
}
public JazzyViewPager(Context context) {
this(context, null);
}
@SuppressWarnings("incomplete-switch")
public JazzyViewPager(Context context, AttributeSet attrs) {
super(context, attrs);
setClipChildren(false);
// now style everything!
TypedArray ta = context.obtainStyledAttributes(attrs, R.styleable.JazzyViewPager);
int effect = ta.getInt(R.styleable.JazzyViewPager_style, 0);
String[] transitions = getResources().getStringArray(R.array.jazzy_effects);
setTransitionEffect(TransitionEffect.valueOf(transitions[effect]));
setFadeEnabled(ta.getBoolean(R.styleable.JazzyViewPager_fadeEnabled, false));
setOutlineEnabled(ta.getBoolean(R.styleable.JazzyViewPager_outlineEnabled, false));
setOutlineColor(ta.getColor(R.styleable.JazzyViewPager_outlineColor, Color.WHITE));
switch (mEffect) {
case Stack:
case ZoomOut:
setFadeEnabled(true);
}
ta.recycle();
}
public void setTransitionEffect(TransitionEffect effect) {
mEffect = effect;
// reset();
}
public void setPagingEnabled(boolean enabled) {
mEnabled = enabled;
}
public void setFadeEnabled(boolean enabled) {
mFadeEnabled = enabled;
}
public boolean getFadeEnabled() {
return mFadeEnabled;
}
public void setOutlineEnabled(boolean enabled) {
mOutlineEnabled = enabled;
wrapWithOutlines();
}
public void setOutlineColor(int color) {
sOutlineColor = color;
}
private void wrapWithOutlines() {
for (int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if (!(v instanceof OutlineContainer)) {
removeView(v);
super.addView(wrapChild(v), i);
}
}
}
private View wrapChild(View child) {
if (!mOutlineEnabled || child instanceof OutlineContainer)
return child;
OutlineContainer out = new OutlineContainer(getContext());
out.setLayoutParams(generateDefaultLayoutParams());
child.setLayoutParams(new OutlineContainer.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
out.addView(child);
return out;
}
public void addView(View child) {
super.addView(wrapChild(child));
}
public void addView(View child, int index) {
super.addView(wrapChild(child), index);
}
public void addView(View child, LayoutParams params) {
super.addView(wrapChild(child), params);
}
public void addView(View child, int width, int height) {
super.addView(wrapChild(child), width, height);
}
public void addView(View child, int index, LayoutParams params) {
super.addView(wrapChild(child), index, params);
}
@Override
public boolean onInterceptTouchEvent(MotionEvent arg0) {
return mEnabled ? super.onInterceptTouchEvent(arg0) : false;
}
private State mState;
private int oldPage;
private View mLeft;
private View mRight;
private float mRot;
private float mTrans;
private float mScale;
private enum State {
IDLE, GOING_LEFT, GOING_RIGHT
}
private void logState(View v, String title) {
Log.v(TAG,
title + ": ROT (" + ViewHelper.getRotation(v) + ", " + ViewHelper.getRotationX(v) + ", " + ViewHelper.getRotationY(v) + "), TRANS (" + ViewHelper.getTranslationX(v) + ", " + ViewHelper.getTranslationY(v)
+ "), SCALE (" + ViewHelper.getScaleX(v) + ", " + ViewHelper.getScaleY(v) + "), ALPHA " + ViewHelper.getAlpha(v));
}
protected void animateScroll(int position, float positionOffset) {
if (mState != State.IDLE) {
mRot = (float) (1 - Math.cos(2 * Math.PI * positionOffset)) / 2 * 30.0f;
ViewHelper.setRotationY(this, mState == State.GOING_RIGHT ? mRot : -mRot);
ViewHelper.setPivotX(this, getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(this, getMeasuredHeight() * 0.5f);
}
}
protected void animateTablet(View left, View right, float positionOffset) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = 30.0f * positionOffset;
mTrans = getOffsetXForRotation(mRot, left.getMeasuredWidth(), left.getMeasuredHeight());
ViewHelper.setPivotX(left, left.getMeasuredWidth() / 2);
ViewHelper.setPivotY(left, left.getMeasuredHeight() / 2);
ViewHelper.setTranslationX(left, mTrans);
ViewHelper.setRotationY(left, mRot);
logState(left, "Left");
}
if (right != null) {
manageLayer(right, true);
mRot = -30.0f * (1 - positionOffset);
mTrans = getOffsetXForRotation(mRot, right.getMeasuredWidth(), right.getMeasuredHeight());
ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
ViewHelper.setTranslationX(right, mTrans);
ViewHelper.setRotationY(right, mRot);
logState(right, "Right");
}
}
}
private void animateCube(View left, View right, float positionOffset, boolean in) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = (in ? 90.0f : -90.0f) * positionOffset;
ViewHelper.setPivotX(left, left.getMeasuredWidth());
ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
ViewHelper.setRotationY(left, mRot);
}
if (right != null) {
manageLayer(right, true);
mRot = -(in ? 90.0f : -90.0f) * (1 - positionOffset);
ViewHelper.setPivotX(right, 0);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
ViewHelper.setRotationY(right, mRot);
}
}
}
private void animateAccordion(View left, View right, float positionOffset) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
ViewHelper.setPivotX(left, left.getMeasuredWidth());
ViewHelper.setPivotY(left, 0);
ViewHelper.setScaleX(left, 1 - positionOffset);
}
if (right != null) {
manageLayer(right, true);
ViewHelper.setPivotX(right, 0);
ViewHelper.setPivotY(right, 0);
ViewHelper.setScaleX(right, positionOffset);
}
}
}
private void animateZoom(View left, View right, float positionOffset, boolean in) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mScale = in ? ZOOM_MAX + (1 - ZOOM_MAX) * (1 - positionOffset) : 1 + ZOOM_MAX - ZOOM_MAX * (1 - positionOffset);
ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
ViewHelper.setScaleX(left, mScale);
ViewHelper.setScaleY(left, mScale);
}
if (right != null) {
manageLayer(right, true);
mScale = in ? ZOOM_MAX + (1 - ZOOM_MAX) * positionOffset : 1 + ZOOM_MAX - ZOOM_MAX * positionOffset;
ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
ViewHelper.setScaleX(right, mScale);
ViewHelper.setScaleY(right, mScale);
}
}
}
private void animateRotate(View left, View right, float positionOffset, boolean up) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = (up ? 1 : -1) * (ROT_MAX * positionOffset);
mTrans = (up ? -1 : 1) * (float) (getMeasuredHeight() - getMeasuredHeight() * Math.cos(mRot * Math.PI / 180.0f));
ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(left, up ? 0 : left.getMeasuredHeight());
ViewHelper.setTranslationY(left, mTrans);
ViewHelper.setRotation(left, mRot);
}
if (right != null) {
manageLayer(right, true);
mRot = (up ? 1 : -1) * (-ROT_MAX + ROT_MAX * positionOffset);
mTrans = (up ? -1 : 1) * (float) (getMeasuredHeight() - getMeasuredHeight() * Math.cos(mRot * Math.PI / 180.0f));
ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(right, up ? 0 : right.getMeasuredHeight());
ViewHelper.setTranslationY(right, mTrans);
ViewHelper.setRotation(right, mRot);
}
}
}
private void animateFlipHorizontal(View left, View right, float positionOffset, int positionOffsetPixels) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = 180.0f * positionOffset;
if (mRot > 90.0f) {
left.setVisibility(View.INVISIBLE);
} else {
if (left.getVisibility() == View.INVISIBLE)
left.setVisibility(View.VISIBLE);
mTrans = positionOffsetPixels;
ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
ViewHelper.setTranslationX(left, mTrans);
ViewHelper.setRotationY(left, mRot);
}
}
if (right != null) {
manageLayer(right, true);
mRot = -180.0f * (1 - positionOffset);
if (mRot < -90.0f) {
right.setVisibility(View.INVISIBLE);
} else {
if (right.getVisibility() == View.INVISIBLE)
right.setVisibility(View.VISIBLE);
mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
ViewHelper.setTranslationX(right, mTrans);
ViewHelper.setRotationY(right, mRot);
}
}
}
}
private void animateFlipVertical(View left, View right, float positionOffset, int positionOffsetPixels) {
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
mRot = 180.0f * positionOffset;
if (mRot > 90.0f) {
left.setVisibility(View.INVISIBLE);
} else {
if (left.getVisibility() == View.INVISIBLE)
left.setVisibility(View.VISIBLE);
mTrans = positionOffsetPixels;
ViewHelper.setPivotX(left, left.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(left, left.getMeasuredHeight() * 0.5f);
ViewHelper.setTranslationX(left, mTrans);
ViewHelper.setRotationX(left, mRot);
}
}
if (right != null) {
manageLayer(right, true);
mRot = -180.0f * (1 - positionOffset);
if (mRot < -90.0f) {
right.setVisibility(View.INVISIBLE);
} else {
if (right.getVisibility() == View.INVISIBLE)
right.setVisibility(View.VISIBLE);
mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
ViewHelper.setPivotX(right, right.getMeasuredWidth() * 0.5f);
ViewHelper.setPivotY(right, right.getMeasuredHeight() * 0.5f);
ViewHelper.setTranslationX(right, mTrans);
ViewHelper.setRotationX(right, mRot);
}
}
}
}
protected void animateStack(View left, View right, float positionOffset, int positionOffsetPixels) {
if (mState != State.IDLE) {
if (right != null) {
manageLayer(right, true);
mScale = (1 - SCALE_MAX) * positionOffset + SCALE_MAX;
mTrans = -getWidth() - getPageMargin() + positionOffsetPixels;
ViewHelper.setScaleX(right, mScale);
ViewHelper.setScaleY(right, mScale);
ViewHelper.setTranslationX(right, mTrans);
}
if (left != null) {
left.bringToFront();
}
}
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void manageLayer(View v, boolean enableHardware) {
if (!API_11)
return;
int layerType = enableHardware ? View.LAYER_TYPE_HARDWARE : View.LAYER_TYPE_NONE;
if (layerType != v.getLayerType())
v.setLayerType(layerType, null);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void disableHardwareLayer() {
if (!API_11)
return;
View v;
for (int i = 0; i < getChildCount(); i++) {
v = getChildAt(i);
if (v.getLayerType() != View.LAYER_TYPE_NONE)
v.setLayerType(View.LAYER_TYPE_NONE, null);
}
}
private Matrix mMatrix = new Matrix();
private Camera mCamera = new Camera();
private float[] mTempFloat2 = new float[2];
protected float getOffsetXForRotation(float degrees, int width, int height) {
mMatrix.reset();
mCamera.save();
mCamera.rotateY(Math.abs(degrees));
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-width * 0.5f, -height * 0.5f);
mMatrix.postTranslate(width * 0.5f, height * 0.5f);
mTempFloat2[0] = width;
mTempFloat2[1] = height;
mMatrix.mapPoints(mTempFloat2);
return (width - mTempFloat2[0]) * (degrees > 0.0f ? 1.0f : -1.0f);
}
public static interface SlideCallback {
void callBack(int position, float positionOffset);
}
private SlideCallback slideCallback = null;
public void setSlideCallBack(SlideCallback slideCallBack) {
this.slideCallback = slideCallBack;
}
protected void animateFade(View left, View right, float positionOffset, int position) {
if (left != null) {
ViewHelper.setAlpha(left, 1 - positionOffset);
if (slideCallback != null) {
slideCallback.callBack(position, 1 - positionOffset);
}
}
if (right != null) {
ViewHelper.setAlpha(right, positionOffset);
if (slideCallback != null) {
slideCallback.callBack(position + 1, positionOffset);
}
}
}
protected void animateOutline(View left, View right) {
if (!(left instanceof OutlineContainer))
return;
if (mState != State.IDLE) {
if (left != null) {
manageLayer(left, true);
((OutlineContainer) left).setOutlineAlpha(1.0f);
}
if (right != null) {
manageLayer(right, true);
((OutlineContainer) right).setOutlineAlpha(1.0f);
}
} else {
if (left != null)
((OutlineContainer) left).start();
if (right != null)
((OutlineContainer) right).start();
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (mState == State.IDLE && positionOffset > 0) {
oldPage = getCurrentItem();
mState = position == oldPage ? State.GOING_RIGHT : State.GOING_LEFT;
}
boolean goingRight = position == oldPage;
if (mState == State.GOING_RIGHT && !goingRight)
mState = State.GOING_LEFT;
else if (mState == State.GOING_LEFT && goingRight)
mState = State.GOING_RIGHT;
float effectOffset = isSmall(positionOffset) ? 0 : positionOffset;
// mLeft = getChildAt(position);
// mRight = getChildAt(position+1);
mLeft = findViewFromObject(position);
mRight = findViewFromObject(position + 1);
if (mFadeEnabled)
animateFade(mLeft, mRight, effectOffset, position);
if (mOutlineEnabled)
animateOutline(mLeft, mRight);
switch (mEffect) {
case Standard:
break;
case Tablet:
animateTablet(mLeft, mRight, effectOffset);
break;
case CubeIn:
animateCube(mLeft, mRight, effectOffset, true);
break;
case CubeOut:
animateCube(mLeft, mRight, effectOffset, false);
break;
case FlipVertical:
animateFlipVertical(mLeft, mRight, positionOffset, positionOffsetPixels);
break;
case FlipHorizontal:
animateFlipHorizontal(mLeft, mRight, effectOffset, positionOffsetPixels);
case Stack:
animateStack(mLeft, mRight, effectOffset, positionOffsetPixels);
break;
case ZoomIn:
animateZoom(mLeft, mRight, effectOffset, true);
break;
case ZoomOut:
animateZoom(mLeft, mRight, effectOffset, false);
break;
case RotateUp:
animateRotate(mLeft, mRight, effectOffset, true);
break;
case RotateDown:
animateRotate(mLeft, mRight, effectOffset, false);
break;
case Accordion:
animateAccordion(mLeft, mRight, effectOffset);
break;
}
super.onPageScrolled(position, positionOffset, positionOffsetPixels);
if (effectOffset == 0) {
disableHardwareLayer();
mState = State.IDLE;
}
}
private boolean isSmall(float positionOffset) {
return Math.abs(positionOffset) < 0.0001;
}
public void setObjectForPosition(Object obj, int position) {
mObjs.put(Integer.valueOf(position), obj);
}
public View findViewFromObject(int position) {
Object o = mObjs.get(Integer.valueOf(position));
if (o == null) {
return null;
}
PagerAdapter a = getAdapter();
View v;
for (int i = 0; i < getChildCount(); i++) {
v = getChildAt(i);
if (a.isViewFromObject(v, o))
return v;
}
return null;
}
}
适配器代码:
package aa.a3.adapter;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import aa.a3.fragment.er_fragment;
import aa.a3.fragment.san_fragment;
import aa.a3.fragment.yi_fragment;
import aa.a3.tool.JazzyViewPager;
public class MainPagerAdapter extends FragmentPagerAdapter {
private JazzyViewPager mJazzyViewPager;
// 定义数组来存放Fragment界面
private Class mfragmentArray[] = { yi_fragment.class, er_fragment.class,san_fragment.class };
public MainPagerAdapter(FragmentManager fm, JazzyViewPager jazzyViewPager) {
super(fm);
mJazzyViewPager = jazzyViewPager;
}
@Override
public Fragment getItem(int position) {
yi_fragment yi=new yi_fragment();
er_fragment er=new er_fragment();
san_fragment san=new san_fragment();
Fragment fm[]={yi,er,san};
Fragment fragment = fm[position];
mJazzyViewPager.setObjectForPosition(fragment, position);
return fragment;
}
@Override
public int getCount() {
return mfragmentArray.length;
}
@Override
public int getItemPosition(Object object) {
return super.getItemPosition(object);
}
}
XML布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<com.example.lin_tab_demo.JazzyViewPager
android:id="@+id/realtabcontent"
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="1" />
<com.example.lin_tab_demo.FragmentTabHost
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@drawable/ic_launcher">
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
</com.example.lin_tab_demo.FragmentTabHost>
</LinearLayout>
3.重点说明(JazzyViewPager依赖库的导入)
导入依赖库的方法为Android Studio导入方法.
注:依赖库在源码里,可以下载
第一步:将依赖库放入项目的根目录下面。
第二步:在项目里配置(直接上图)
(图一)
(图二)
右键单击项目——Open Moduleu Settings 成功后你会看到图三,表明已经添加成功。
(图三)
4.源码地址
eclipse源码地址:http://download.csdn.net/detail/u012372365/9610749
AndroidStudio源码地址: http://download.csdn.net/detail/u012372365/9614024