Mvvmcross Android Fragment (ShowViewModel) 自定义动画效果(滑动)
Mvvmcross Android Fragment (ShowViewModel) Custom Animation effect (swipe)
我在 Fragment 上覆盖自定义动画时遇到问题。我的主视图上有三个按钮(第一、第二和第三),当我在这个视图中时,我想在这些视图之间滑动,我需要从左到右和从右到左滑动动画效果等。
例如,我的 SecondFragments 如下所示:
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
public class SecondFragment : BaseFragment<SecondViewModel>, View.IOnTouchListener
{
private Easter _easter;
protected override int FragmentId => Resource.Layout.fragment_second;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
_easter = new Easter(new KonamiCode());
var easyEgg = new CustomEgg("Easy")
.WatchForSequence(Command.SwipeLeft(), Command.SwipeRight());
_easter = new Easter(easyEgg);=
_easter.CommandDetected += cmd => DoSwipe(cmd.Value);
var coreLayout = view.FindViewById<LinearLayout>(Resource.Id.coreLayout);
coreLayout?.SetOnTouchListener(this);
return view;
}
private void DoSwipe(string swipeText)
{
if (swipeText.Equals("LEFT"))
{
Activity.OverridePendingTransition(Resource.Animator.slide_to_right, Resource.Animator.slide_from_left);
}
if (swipeText.Equals("RIGHT"))
{
Activity.OverridePendingTransition(Resource.Animator.slide_to_left, Resource.Animator.slide_from_right);
}
ViewModel.SwipeView(swipeText);
}
public bool OnTouch(View v, MotionEvent e)
{
_easter.OnTouchEvent(e);
return true;
}
}
方法ViewModel.SwipeView看起来像:
public override void SwipeView(string swipeText)
{
if (swipeText.Equals("RIGHT"))
{
Close(this);
UserDialogs.Instance.Toast("RIGHT SWIPE!");
ShowViewModel<FirstViewModel>();
}
if (swipeText.Equals("LEFT"))
{
Close(this);
UserDialogs.Instance.Toast("LEFT SWIPE!");
ShowViewModel<ThirdViewModel>();
}
}
我试过 Activity.OverridePendingTransition 但是没用。我用 TransactionManager 做了一些尝试,但仍然没有用。我只需要为这三个视图覆盖整个应用程序的动画。
例如,我的测试项目是 github 上的 HERE。
实现此目的的最佳方法是使用包含您的片段的 ViewPager。我昨天实现了确切的东西,你可以看看 this example 如何将它与 MvvmCross 一起使用。
I tried Activity.OverridePendingTransition for this but it doesnt work.
OverridePendingTransition 允许您在从当前顶部 Activity
的 Context
外部启动 activity 时指定自定义动画。这意味着 OverridePendingTransition
方法 只能在 startActivity(Intent)
或 finish()
的其中一种风格之后立即调用 以指定接下来要执行的显式过渡动画。因此,当您在 Fragment
之间滑动时,它没有任何效果。
Difference between Animator folder and Anim fodler.
动画资源可以定义两种动画之一:Property Animation and View Animation。
属性动画
文件位置:
Resource/animator/filename.xml
语法:
文件必须有一个根元素:<set>
、<objectAnimator>
或 <valueAnimator>
。您可以在 <set>
元素内将动画元素组合在一起,包括其他 <set>
元素。
观看动画
文件位置:
Resource/anim/filename.xml
语法:
文件必须有一个根元素:<alpha>
、<scale>
、<translate>
、<rotate>
或 <set>
元素一组(或多组)其他动画元素(甚至嵌套 <set>
元素)。
由于您的动画使用 translate
,我建议您将这些 xml
文件放在 Resource/anim
文件夹中。
I need just override animations only for these three view no for whole app.
由于您的基础 Activity
是 MvxCachingFragmentCompatActivityas
,您可以覆盖 OnBeforeFragmentChanging
方法来设置自定义过渡动画。
public override void OnBeforeFragmentChanging(MvvmCross.Droid.Shared.Caching.IMvxCachedFragmentInfo fragmentInfo, Android.Support.V4.App.FragmentTransaction transaction)
{
//Replace this animation with your own animation.
transaction.SetCustomAnimations(
// Your entrance animation xml reference
Resource.Animation.abc_fade_in,
// Your exit animation xml reference
Resource.Animation.abc_fade_out,
Resource.Animation.abc_fade_in,
Resource.Animation.abc_fade_out);
base.OnBeforeFragmentChanging(fragmentInfo, transaction);
}
SetCustomAnimations
将特定的动画资源设置为 运行 用于在该事务中进入和退出的片段。 popEnter 和 popExit 动画将为 enter/exit 操作播放,特别是在弹出返回堆栈时。
FragmentTransaction setCustomAnimations (int enter,
int exit,
int popEnter,
int popExit)
编辑:
为 Fragment
之间的每次滑动自定义动画,对于每个 Fragment
,您可以像这样自定义动画:
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
public class SecondFragment : BaseFragment<SecondViewModel>, View.IOnTouchListener
{
private void DoSwipe(string swipeText)
{
if (swipeText.Equals("LEFT"))
{
FragmentManager.BeginTransaction()
.SetCustomAnimations(Resource.Animation.slide_from_left, Resource.Animation.slide_from_right)
.Replace(Resource.Id.content_frame,ThirdFragment.NewInstance(null))
.Commit();
}
if (swipeText.Equals("RIGHT"))
{
...
}
ViewModel.SwipeView(swipeText);
}
}
我在 Fragment 上覆盖自定义动画时遇到问题。我的主视图上有三个按钮(第一、第二和第三),当我在这个视图中时,我想在这些视图之间滑动,我需要从左到右和从右到左滑动动画效果等。
例如,我的 SecondFragments 如下所示:
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
public class SecondFragment : BaseFragment<SecondViewModel>, View.IOnTouchListener
{
private Easter _easter;
protected override int FragmentId => Resource.Layout.fragment_second;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = base.OnCreateView(inflater, container, savedInstanceState);
_easter = new Easter(new KonamiCode());
var easyEgg = new CustomEgg("Easy")
.WatchForSequence(Command.SwipeLeft(), Command.SwipeRight());
_easter = new Easter(easyEgg);=
_easter.CommandDetected += cmd => DoSwipe(cmd.Value);
var coreLayout = view.FindViewById<LinearLayout>(Resource.Id.coreLayout);
coreLayout?.SetOnTouchListener(this);
return view;
}
private void DoSwipe(string swipeText)
{
if (swipeText.Equals("LEFT"))
{
Activity.OverridePendingTransition(Resource.Animator.slide_to_right, Resource.Animator.slide_from_left);
}
if (swipeText.Equals("RIGHT"))
{
Activity.OverridePendingTransition(Resource.Animator.slide_to_left, Resource.Animator.slide_from_right);
}
ViewModel.SwipeView(swipeText);
}
public bool OnTouch(View v, MotionEvent e)
{
_easter.OnTouchEvent(e);
return true;
}
}
方法ViewModel.SwipeView看起来像:
public override void SwipeView(string swipeText)
{
if (swipeText.Equals("RIGHT"))
{
Close(this);
UserDialogs.Instance.Toast("RIGHT SWIPE!");
ShowViewModel<FirstViewModel>();
}
if (swipeText.Equals("LEFT"))
{
Close(this);
UserDialogs.Instance.Toast("LEFT SWIPE!");
ShowViewModel<ThirdViewModel>();
}
}
我试过 Activity.OverridePendingTransition 但是没用。我用 TransactionManager 做了一些尝试,但仍然没有用。我只需要为这三个视图覆盖整个应用程序的动画。
例如,我的测试项目是 github 上的 HERE。
实现此目的的最佳方法是使用包含您的片段的 ViewPager。我昨天实现了确切的东西,你可以看看 this example 如何将它与 MvvmCross 一起使用。
I tried Activity.OverridePendingTransition for this but it doesnt work.
OverridePendingTransition 允许您在从当前顶部 Activity
的 Context
外部启动 activity 时指定自定义动画。这意味着 OverridePendingTransition
方法 只能在 startActivity(Intent)
或 finish()
的其中一种风格之后立即调用 以指定接下来要执行的显式过渡动画。因此,当您在 Fragment
之间滑动时,它没有任何效果。
Difference between Animator folder and Anim fodler.
动画资源可以定义两种动画之一:Property Animation and View Animation。
属性动画
文件位置:
Resource/animator/filename.xml
语法:
文件必须有一个根元素:
<set>
、<objectAnimator>
或<valueAnimator>
。您可以在<set>
元素内将动画元素组合在一起,包括其他<set>
元素。观看动画
文件位置:
Resource/anim/filename.xml
语法:
文件必须有一个根元素:
<alpha>
、<scale>
、<translate>
、<rotate>
或<set>
元素一组(或多组)其他动画元素(甚至嵌套<set>
元素)。
由于您的动画使用 translate
,我建议您将这些 xml
文件放在 Resource/anim
文件夹中。
I need just override animations only for these three view no for whole app.
由于您的基础 Activity
是 MvxCachingFragmentCompatActivityas
,您可以覆盖 OnBeforeFragmentChanging
方法来设置自定义过渡动画。
public override void OnBeforeFragmentChanging(MvvmCross.Droid.Shared.Caching.IMvxCachedFragmentInfo fragmentInfo, Android.Support.V4.App.FragmentTransaction transaction)
{
//Replace this animation with your own animation.
transaction.SetCustomAnimations(
// Your entrance animation xml reference
Resource.Animation.abc_fade_in,
// Your exit animation xml reference
Resource.Animation.abc_fade_out,
Resource.Animation.abc_fade_in,
Resource.Animation.abc_fade_out);
base.OnBeforeFragmentChanging(fragmentInfo, transaction);
}
SetCustomAnimations
将特定的动画资源设置为 运行 用于在该事务中进入和退出的片段。 popEnter 和 popExit 动画将为 enter/exit 操作播放,特别是在弹出返回堆栈时。
FragmentTransaction setCustomAnimations (int enter,
int exit,
int popEnter,
int popExit)
编辑:
为 Fragment
之间的每次滑动自定义动画,对于每个 Fragment
,您可以像这样自定义动画:
[MvxFragment(typeof(MainViewModel), Resource.Id.content_frame, true)]
public class SecondFragment : BaseFragment<SecondViewModel>, View.IOnTouchListener
{
private void DoSwipe(string swipeText)
{
if (swipeText.Equals("LEFT"))
{
FragmentManager.BeginTransaction()
.SetCustomAnimations(Resource.Animation.slide_from_left, Resource.Animation.slide_from_right)
.Replace(Resource.Id.content_frame,ThirdFragment.NewInstance(null))
.Commit();
}
if (swipeText.Equals("RIGHT"))
{
...
}
ViewModel.SwipeView(swipeText);
}
}