关于Android使用animator实现fragment的3D翻转效果和animate的3d旋转工具的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于3D翻转效果介绍,Android动画分
关于Android使用animator实现fragment的3D翻转效果和animate的3d旋转工具的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于3D翻转效果介绍,Android动画分析、Android Fragment – 使用activity的loadermanager而不是Fragment.好吗?、Android Fragment 和 FragmentManager 的代码分析、Android FragmentManage FragmentTransaction 介绍等相关知识的信息别忘了在本站进行查找喔。
本文目录一览:- Android使用animator实现fragment的3D翻转效果(animate的3d旋转工具)
- 3D翻转效果介绍,Android动画分析
- Android Fragment – 使用activity的loadermanager而不是Fragment.好吗?
- Android Fragment 和 FragmentManager 的代码分析
- Android FragmentManage FragmentTransaction 介绍
Android使用animator实现fragment的3D翻转效果(animate的3d旋转工具)
今天老师留的作业,使用俩个Fragment来实现3D翻转效果,遇到了一点点的问题,于是在网上进行了查找,但是发现有些博主的代码不正确,对其他人进行了误导,在网上使用属性动画实现3D效果非常少,所以经过我自己的实验摸索,我将自己的代码和遇到的问题给他讲解一下提供一点点借鉴,并且希望可以帮助到大家。
首先讲解一下主要实现动画的函数:
getFragmentManager().beginTransaction() .setCustomAnimations(R.animator.fragment_second_3d_reversal_enter,R.animator.fragment_second_3d_reversal_exit) .replace(R.id.container,new MainFragment()).commit();
我想信这个函数大家在实现动画时都会使用到,先获得FragmentManager然后进行transaction,主要添加动画的函数是setCustomAnimations(),在网上可以查到的解释,对这个方法有些错误,描述的是当前的Fragment对象的进入和退出时的动画效果,是这个对象的一种属性,但是这个方法真正的解释应该是在当前Activity在切换Fragment时所执行的动画方式,也就是说当前Fragment退出时用的是方法中的退出动画,新的Fragment进入时执行的是进入的动画效果,可以理解为这一次动画效果完全是利用这一个语句来完成,有些博客的记载对我们产生了一些误导。
官方的注释如下:
/** * Set specific animation resources to run for the fragments that are * entering and exiting in this transaction. These animations will not be * played when popping the back stack. */ public abstract FragmentTransaction setCustomAnimations(int enter,int exit);
整体的3D翻转效果代码如下:
第二个Fragment。
/** * Created by Liurs on 2016/6/14. **/ public class SecondFragment extends Fragment { private LinearLayout root; private Button mButton; public SecondFragment() { } @Nullable @Override public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { root = (LinearLayout) inflater.inflate(R.layout.fragment_second,container,false); //Set listener; setListener(); return root; } /** * set listener */ private void setListener() { mButton = (Button) root.findViewById(R.id.button); mButton.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getFragmentManager().beginTransaction() .setCustomAnimations(R.animator.fragment_second_3d_reversal_enter,R.animator.fragment_second_3d_reversal_exit) .replace(R.id.container,new MainFragment()).commit(); } }); } @Override public void onViewCreated(View view,Bundle savedInstanceState) { super.onViewCreated(view,savedInstanceState); } }
第一个Fragment。
/** * Created by Liurs on 2016/6/14. **/ public class MainFragment extends Fragment { private LinearLayout root; private Button mButton; public MainFragment() { } @Nullable @Override public View onCreateView(LayoutInflater inflater,Bundle savedInstanceState) { root = (LinearLayout) inflater.inflate(R.layout.content_main,false); //Set listener; setListener(); return root; } /** * set listener */ private void setListener() { mButton = (Button) root.findViewById(R.id.button); mButton.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getFragmentManager() .beginTransaction() .addToBackStack(null) .setCustomAnimations(R.animator.fragment_3d_reversal_enter,R.animator.fragment_3d_reversal_exit,R.animator.fragment_second_3d_reversal_enter,new SecondFragment()) .commit(); } }); } @Override public void onViewCreated(View view,savedInstanceState); } }
逆时针翻转动画进入时配置文件。
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="0" android:propertyName="rotationY" android:valueFrom="0f" android:valueto="270f" /> <objectAnimator android:duration="500" android:propertyName="rotationY" android:startOffset="500" android:valueFrom="270f" android:valueto="360f" /> </set>
退出时动画配置文件,
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:propertyName="rotationY" android:valueFrom="0f" android:valueto="90f"> </objectAnimator> </set>
顺时针翻转动画进入时配置文件,
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator android:duration="0" android:propertyName="rotationY" android:valueFrom="180f" android:valueto="90f" /> <objectAnimator android:duration="500" android:propertyName="rotationY" android:startOffset="500" android:valueFrom="90f" android:valueto="0f" /> </set>
退出时动画配置文件,
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:ordering="sequentially"> <objectAnimator xmlns:android="http://schemas.android.com/apk/res/android" android:duration="500" android:propertyName="rotationY" android:valueFrom="0f" android:valueto="-90f"> </objectAnimator> </set>
至此,两个Fragment的3D翻转切换已经完成,希望我的经验可以帮助到你们。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。
3D翻转效果介绍,Android动画分析
android中的翻转动画效果的实现,首先看一下运行效果如上图所示。,更多android面试题..
Android中并没有提供直接做3D翻转的动画,所以关于3D翻转的动画效果需要我们自己实现,那么我们首先来分析一下Animation 和 Transformation。
Animation动画的主要接口,其中主要定义了动画的一些属性比如开始时间,持续时间,是否重复播放等等。而Transformation中则包含一个矩阵和alpha值,矩阵是用来做平移,旋转和缩放动画的,而alpha值是用来做alpha动画的,要实现3D旋转动画我们需要继承自Animation类来实现,我们需要重载getTransformation和applyTransformation,在getTransformation中Animation会根据动画的属性来产生一系列的差值点,然后将这些差值点传给applyTransformation,这个函数将根据这些点来生成不同的Transformation。下面是具体实现:
package com.example.textviewtest;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.view.animation.Animation;
import android.view.animation.Transformation;
public class Rotate3dAnimation extends Animation {
// 开始角度
private final float mFromDegrees;
// 结束角度
private final float mToDegrees;
// 中心点
private final float mCenterX;
private final float mCenterY;
private final float mDepthZ;
// 是否需要扭曲
private final boolean mReverse;
// 摄像头
private Camera mCamera;
public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX,
float centerY, float depthZ, boolean reverse) {
mFromDegrees = fromDegrees;
mToDegrees = toDegrees;
mCenterX = centerX;
mCenterY = centerY;
mDepthZ = depthZ;
mReverse = reverse;
}
@Override
public void initialize(int width, int height, int parentWidth,
int parentHeight) {
super.initialize(width, height, parentWidth, parentHeight);
mCamera = new Camera();
}
// 生成Transformation
@Override
protected void applyTransformation(float interpolatedTime, Transformation t) {
final float fromDegrees = mFromDegrees;
// 生成中间角度
float degrees = fromDegrees
+ ((mToDegrees - fromDegrees) * interpolatedTime);
final float centerX = mCenterX;
final float centerY = mCenterY;
final Camera camera = mCamera;
final Matrix matrix = t.getMatrix();
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateY(degrees);
// 取得变换后的矩阵
camera.getMatrix(matrix);
camera.restore();
matrix.preTranslate(-centerX, -centerY);
matrix.postTranslate(centerX, centerY);
}
}
其中包括了旋转的开始和结束角度,中心点、是否扭曲、和一个Camera,这里我们主要分析applyTransformation函数,其中第一个参数就是通过getTransformation函数传递的差指点,然后我们根据这个差值通过线性差值算法计算出一个中间角度degrees,Camera类是用来实现绕Y轴旋转后透视投影的,因此我们首先通过t.getMatrix()取得当前的矩阵,然后通过camera.translate来对矩阵进行平移变换操作,camera.rotateY进行旋转。这样我们就可以很轻松的实现3D旋转效果了。
下面是布局文件main.xml:
MainActivity的代码如下:
package com.example.textviewtest;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv;
private Button btn;
private int count = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tv = (TextView) findViewById(R.id.tv);
tv.setText(String.valueOf(count));
btn = (Button) findViewById(R.id.next_btn);
applyRotation(0, 90);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
applyRotation(0, 90);
}
});
}
private void applyRotation(float start, float end) {
// 计算中心点
final float centerX = tv.getWidth() / 2.0f;
final float centerY = tv.getHeight() / 2.0f;
final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end,
centerX, centerY, 310.0f, true);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new AccelerateInterpolator());
// 设置监听
rotation.setAnimationListener(new DisplayNextView());
tv.startAnimation(rotation);
}
private final class DisplayNextView implements Animation.AnimationListener {
public void onAnimationStart(Animation animation) {
}
// 动画结束
public void onAnimationEnd(Animation animation) {
tv.post(new SwapViews());
}
public void onAnimationRepeat(Animation animation) {
}
}
private final class SwapViews implements Runnable {
public void run() {
final float centerX = tv.getWidth() / 2.0f;
final float centerY = tv.getHeight() / 2.0f;
Rotate3dAnimation rotation = null;
tv.requestFocus();
rotation = new Rotate3dAnimation(90, 0, centerX, centerY, 310.0f,
false);
rotation.setDuration(500);
rotation.setFillAfter(true);
rotation.setInterpolator(new DecelerateInterpolator());
// 开始动画
tv.startAnimation(rotation);
tv.setText(String.valueOf(count++));
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Android Fragment – 使用activity的loadermanager而不是Fragment.好吗?
问题:
我有一个寻呼机适配器,当用户离开拿着它的标签时会破坏该片段,并在用户返回该标签时重新创建它.由于这种重新创建,每次都会创建一个新的加载器,并且每次都会加载数据.
题 :
为了避免每次创建片段时重新创建加载器,是否可以在片段的onActivityCreated方法中使用getActivity.getSupportLoaderManager.initLoader(loaderId,null,false)?
我试过它,测试它,似乎工作正常.但我不相信这是对的.
解决方法
Fragment.getLoaderManager:
/** * Return the LoaderManager for this fragment,creating it if needed. */ public LoaderManager getLoaderManager() { if (mloaderManager != null) { return mloaderManager; } if (mActivity == null) { throw new IllegalStateException("Fragment " + this + " not attached to Activity"); } mCheckedForLoaderManager = true; mloaderManager = mActivity.getLoaderManager(mWho,mloadeRSStarted,true); return mloaderManager; }
mWho基本上是片段ID.
final void setIndex(int index,Fragment parent) { mIndex = index; if (parent != null) { mWho = parent.mWho + ":" + mIndex; } else { mWho = "android:fragment:" + mIndex; } }
Activity.getLoaderManager()的区别在于谁(root)
所以即使你可以做你想要的,直接从Fragment调用它可能是一个更好的方法
> Activity source code
> Fragment source code
免责声明:我只检查了最新版本的源代码,但我不认为它会有很大不同
Android Fragment 和 FragmentManager 的代码分析
这两天在研究插件化编程,在使用 Fragment 碰到了一些问题,于是查看源码,顺便分析了一下 Fragment 和 FragmentManager 以及其他几个 API 的原代码,看看他们是怎么工作的。
我们知道 Fragment 有个 onCreateView() 方法,这个方法在 Fragment 创建 View 的时候被调用,并且返回一个 View 对象。那么 onCreateView 在什么时候被调用呢,咱们在 Fragment 这个类里找到了一个方法,performCreateView() 方法。
Fragment.java public View onCreateView(LayoutInflater inflater,@Nullable ViewGroup container,@Nullable Bundle savedInstanceState) { return null; }
performCreateView 这个方法在什么时候会被调用呢,在 Fragment 里找不到调用它的代码。咱们可以猜测一下,大概会在 FragmentManager 里。
View performCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) { if (mChildFragmentManager != null) { mChildFragmentManager.noteStateNotSaved(); } return onCreateView(inflater,container,savedInstanceState); }
在 FragmentManager 里,咱们找到了调用 Fragment.performCreateView 的代码,在 movetoState() 方法里,这个方法有点大,我只粘贴了部分代码。可以看到,它会在 Fragment 初始化或者创建的时候被调用。并且我们知道,创建的View 被赋值给 Fragment 的 mView 成员变量了。
FragmentManager.java void movetoState(Fragment f,int newState,int transit,int transitionStyle,boolean keepActive) { switch (f.mState) { case Fragment.INITIALIZING: if (f.mFromLayout) { f.mView = f.performCreateView(f.getLayoutInflater( f.mSavedFragmentState),null,f.mSavedFragmentState); } break; case Fragment.CREATED: if (!f.mFromLayout) { f.mView = f.performCreateView(f.getLayoutInflater( f.mSavedFragmentState),f.mSavedFragmentState); } break; } }
接下来,咱们要看什么时候会调用 movetoState() 这个方法。找了一下,发现很 N 多的地方调用了这个方法。这样给咱们逆推找代码造成了一定的难度。于是咱们换个思路,正推来分析。怎么正推了,看咱们怎么使用 Fragment 和 FragmentManager 来分析。
一般咱们都是 getFragmentManager() 或者 getSupportFragmentManager() 的方法来获取 FragmentManager.以 FragmentActivity 为例,一般情况下,咱们在这个类的子类里调用这两个方法之一。
咱们在 FragmentActivity 里找到了相应的代码。FragmentManager 是一个抽象类,FragmentManagerImpl 是 FragmentManager 的子类,在 FragmentManager 同一个 java 文件内,是一个内部类。它是 FragmentManager 的实现。
FragmentActivity.java //FragmentManagerImpl is subclass of FragmentManager final FragmentManagerImpl mFragments = new FragmentManagerImpl(); public FragmentManager getSupportFragmentManager() { return mFragments; }
获取到 FragmentManager 后,咱们一般就会调用 beginTransaction() 方法,返回一个 FragmentTransaction 。咱们看代码去。
FragmentManager.java public abstract FragmentTransaction beginTransaction(); FragmentManagerImpl extends FragmentManager @Override public FragmentTransaction beginTransaction() { return new BackStackRecord(this); } /** * Static library support version of the framework's {@link android.app.FragmentTransaction}. * Used to write apps that run on platforms prior to Android 3.0. When running * on Android 3.0 or above,this implementation is still used; it does not try * to switch to the framework's implementation. See the framework SDK * documentation for a class overview. */ public abstract class FragmentTransaction
我们发现 FragmentManager 是一个抽象方法,实现在 FragmentManagerImpl。FragmentManagerImpl.beginTransaction() 返回的是一个BackStackRecord,而 FragmentTransaction 是一个抽象类。那么 BackStackRecord 是个什么鬼。
我们找到了 BackStackRecord 这个类。我们注意到,它继承于 FragmentTransaction,并且实现了 Runable 接口。它的方法有很多,咱们就分析一个咱们比较常用的,比如 add() 方法。
BackStackRecord.java final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry,Runnable final FragmentManagerImpl mManager; public BackStackRecord(FragmentManagerImpl manager) { mManager = manager; }
add() 方法其实没干啥,咱们一路追下去看。
public FragmentTransaction add(Fragment fragment,String tag) { doAddOp(0,fragment,tag,OP_ADD); return this; } private void doAddOp(int containerViewId,Fragment fragment,String tag,int opcmd) { fragment.mFragmentManager = mManager; if (tag != null) { if (fragment.mTag != null && !tag.equals(fragment.mTag)) { throw new IllegalStateException("Can't change tag of fragment " + fragment + ": was " + fragment.mTag + " Now " + tag); } fragment.mTag = tag; } if (containerViewId != 0) { if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) { throw new IllegalStateException("Can't change container ID of fragment " + fragment + ": was " + fragment.mFragmentId + " Now " + containerViewId); } fragment.mContainerId = fragment.mFragmentId = containerViewId; } Op op = new Op(); op.cmd = opcmd; op.fragment = fragment; addOp(op); } void addOp(Op op) { if (mHead == null) { mHead = mTail = op; } else { op.prev = mTail; mTail.next = op; mTail = op; } op.enteranim = mEnteranim; op.exitAnim = mExitAnim; op.popEnteranim = mPopEnteranim; op.popExitAnim = mPopExitAnim; mNumOp++; }
一直追到 addOp() 就断了,好像啥事也没干。不过它大概是在一个 add 操作添加到一个链表上了。那咱们怎么办呢?一般咱们add 完后会 commit 一下,咱们看看 commit 都干了啥。
public int commit() { return commitInternal(false); } int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this,allowStateLoss); return mIndex; }
commit 好像也没干啥特殊的事情,不过可以看到这么一行代码 mManager.enqueueAction(this,allowStateLoss); 看 enqueueAction 这个方法名,应该会做点事情的。
同样,咱们在 FragmentManagerImpl 里找到了这个方法。
public void enqueueAction(Runnable action,boolean allowStateLoss) { if (!allowStateLoss) { checkStateLoss(); } synchronized (this) { if (mDestroyed || mActivity == null) { throw new IllegalStateException("Activity has been destroyed"); } if (mPendingActions == null) { mPendingActions = new ArrayList<Runnable>(); } mPendingActions.add(action); if (mPendingActions.size() == 1) { mActivity.mHandler.removeCallbacks(mExecCommit); mActivity.mHandler.post(mExecCommit); } } }
这个方法把咱们的 BackStackRecord -- 其实是 FragmentTransaction,也是 Runnable -- 添加到一个 mPendingActions 的 ArrayList 里了。然后调用 mActivity.mHandler.post(mExecCommit); mExecCommit 又是什么鬼?
Runnable mExecCommit = new Runnable() { @Override public void run() { execPendingActions(); } }; mActivity.mHandler.post(mExecCommit); 说明它在主线程里执行了 mExecCommit 的 run 方法。别问我咋知道的。 execPendingActions() 方法稍微比较大,我把注释写在代码里。 public boolean execPendingActions() { if (mExecutingActions) { throw new IllegalStateException("Recursive entry to executePendingTransactions"); } //如果不是在主线程,抛出一个异常。 if (Looper.myLooper() != mActivity.mHandler.getLooper()) { throw new IllegalStateException("Must be called from main thread of process"); } boolean didSomething = false; // 这里有一个 while true 循环。 while (true) { int numActions; // 这里在一个同步语句块里,把上次 mPendingActions 里的元素转移到 mTmpActions 数组里。并且执行 run方法。执行谁的 run 方法呢?!就是 BackStackRecord , 也就是 FragmentTransaction 。我在最后面贴了 BackStackRecord 的 run 方法。 synchronized (this) { if (mPendingActions == null || mPendingActions.size() == 0) { break; } numActions = mPendingActions.size(); if (mTmpActions == null || mTmpActions.length < numActions) { mTmpActions = new Runnable[numActions]; } mPendingActions.toArray(mTmpActions); mPendingActions.clear(); mActivity.mHandler.removeCallbacks(mExecCommit); } mExecutingActions = true; for (int i=0; i<numActions; i++) { mTmpActions[i].run(); mTmpActions[i] = null; } mExecutingActions = false; didSomething = true; } // 这里有好几行代码,不知道干啥的,反正就是做了一些判断,最后可能会调用 startPendingDeferredFragments() 方法。 if (mHavePendingDeferredStart) { boolean loadersRunning = false; for (int i=0; i<mActive.size(); i++) { Fragment f = mActive.get(i); if (f != null && f.mloaderManager != null) { loadersRunning |= f.mloaderManager.hasRunningLoaders(); } } if (!loadersRunning) { mHavePendingDeferredStart = false; startPendingDeferredFragments(); } } return didSomething; }
startPendingDeferredFragments 方法又是一坨不知道啥意思的代码。最后可能调用了 performPendingDeferredStart()
void startPendingDeferredFragments() { if (mActive == null) return; for (int i=0; i<mActive.size(); i++) { Fragment f = mActive.get(i); if (f != null) { performPendingDeferredStart(f); } } }
在 这个方法里,咱们看到了很熟悉的 movetoState() 方法。接着就是上面的分析,Fragment 的 onCreateView 会被调用。
public void performPendingDeferredStart(Fragment f) { if (f.mDeferStart) { if (mExecutingActions) { // Wait until we're done executing our pending transactions mHavePendingDeferredStart = true; return; } f.mDeferStart = false; movetoState(f,mCurState,false); } }
咱们在回来看 BackStackRecord 的 run 方法。这坨代码有点大,我还是写注释在代码里。
public void run() { if (FragmentManagerImpl.DEBUG) Log.v(TAG,"Run: " + this); if (mAddToBackStack) { if (mIndex < 0) { throw new IllegalStateException("addToBackStack() called after commit()"); } } bumpBackStacknesting(1); TransitionState state = null; SparseArray<Fragment> firstOutFragments = null; SparseArray<Fragment> lastInFragments = null; if (SUPPORTS_TRANSITIONS) { firstOutFragments = new SparseArray<Fragment>(); lastInFragments = new SparseArray<Fragment>(); calculateFragments(firstOutFragments,lastInFragments); state = beginTransition(firstOutFragments,lastInFragments,false); } int transitionStyle = state != null ? 0 : mTransitionStyle; int transition = state != null ? 0 : mTransition; // 注意这里要开始 while 循环了,要遍历刚才咱们说的链表了。 Op op = mHead; while (op != null) { int enteranim = state != null ? 0 : op.enteranim; int exitAnim = state != null ? 0 : op.exitAnim; switch (op.cmd) { // OP_ADD 很简单,mManager.addFragment(f,false); 其他的几个也类似,调用 mManager 相应的方法。 case OP_ADD: { Fragment f = op.fragment; f.mNextAnim = enteranim; mManager.addFragment(f,false); } break; case OP_REPLACE: { Fragment f = op.fragment; if (mManager.mAdded != null) { for (int i=0; i<mManager.mAdded.size(); i++) { Fragment old = mManager.mAdded.get(i); if (FragmentManagerImpl.DEBUG) Log.v(TAG,"OP_REPLACE: adding=" + f + " old=" + old); if (f == null || old.mContainerId == f.mContainerId) { if (old == f) { op.fragment = f = null; } else { if (op.removed == null) { op.removed = new ArrayList<Fragment>(); } op.removed.add(old); old.mNextAnim = exitAnim; if (mAddToBackStack) { old.mBackStacknesting += 1; if (FragmentManagerImpl.DEBUG) Log.v(TAG,"Bump nesting of " + old + " to " + old.mBackStacknesting); } mManager.removeFragment(old,transition,transitionStyle); } } } } if (f != null) { f.mNextAnim = enteranim; mManager.addFragment(f,false); } } break; case OP_REMOVE: { Fragment f = op.fragment; f.mNextAnim = exitAnim; mManager.removeFragment(f,transitionStyle); } break; case OP_HIDE: { Fragment f = op.fragment; f.mNextAnim = exitAnim; mManager.hideFragment(f,transitionStyle); } break; case OP_SHOW: { Fragment f = op.fragment; f.mNextAnim = enteranim; mManager.showFragment(f,transitionStyle); } break; case OP_DETACH: { Fragment f = op.fragment; f.mNextAnim = exitAnim; mManager.detachFragment(f,transitionStyle); } break; case OP_ATTACH: { Fragment f = op.fragment; f.mNextAnim = enteranim; mManager.attachFragment(f,transitionStyle); } break; default: { throw new IllegalArgumentException("UnkNown cmd: " + op.cmd); } } op = op.next; } // 最后还调用了movetoState() 这个方法。跟刚才的区别,看最后一个参数,一个true,一个false。 // 而且注意,这行代码在 while 循环之后。 mManager.movetoState(mManager.mCurState,transitionStyle,true); if (mAddToBackStack) { mManager.addBackStackState(this); } }
以上所述是小编给大家介绍的Android Fragment 和 FragmentManager 的代码分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对编程小技巧网站的支持!
Android FragmentManage FragmentTransaction 介绍

FragmentManage:
FragmentManager 能够实现管理 activity 中 fragment. 通过调用 activity 的 getFragmentManager () 取得它的实例.
1、使用 findFragmentById () (用于在 activity layout 中提供一个 UI 的 fragment) 或 findFragmentByTag ()(适用于有或没有 UI 的 fragment) 获取 activity 中存在的 fragment2、将 fragment 从后台堆栈中弹出,使用 popBackStack () (模拟用户按下 BACK 命令).3、使用 addOnBackStackChangeListener () 注册一个监听后台堆栈变化的 listener.
FragmentTransaction:
FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
// Create new fragment and transaction Fragment newFragment = new ExampleFragment(); FragmentTransaction transaction = getFragmentManager().beginTransaction(); // Replace whatever is in the fragment_container view with this fragment, // and add the transaction to the back stack transaction.replace(R.id.fragment_container, newFragment); transaction.addToBackStack(null); // Commit the transaction transaction.commit();
- 必须最后调用 commit ().
- 如果添加多个 fragment 到同一个容器,那么添加的顺序决定了它们在 view hierarchy 中显示的顺序.
* @author 张兴业
* 邮箱: xy-zhang#163.com
* android 开发进阶群: 278401545
*
*/
今天关于Android使用animator实现fragment的3D翻转效果和animate的3d旋转工具的介绍到此结束,谢谢您的阅读,有关3D翻转效果介绍,Android动画分析、Android Fragment – 使用activity的loadermanager而不是Fragment.好吗?、Android Fragment 和 FragmentManager 的代码分析、Android FragmentManage FragmentTransaction 介绍等更多相关知识的信息可以在本站进行查询。
本文标签: