【问题标题】:Add animations for Multi-Screen intro tutorial - Xamarin.Android为多屏介绍教程添加动画 - Xamarin.Android
【发布时间】:2017-05-18 13:32:06
【问题描述】:

我需要为我们的应用制作多屏介绍教程。它应该看起来像这样--> 第一个屏幕有动画并且它会自动启动->用户滑动以更改页面(屏幕)->第二个屏幕有动画并且它会自动启动->用户滑动...等等四个屏幕。

我做了一个完美的例子,但它适用于每个屏幕而不是动画,它有一张图片。我知道如何制作 DrawableAnimations,您可以在下面的示例中看到它是逐帧制作的。我只是要求有人帮助我在布局和 MainActivity 中实现这些动画。这是我的 MainActivity、Main 布局、LayoutSlide(显示该步骤动画的每个屏幕的布局)的代码。 AnimatedScreen(要设置动画的项目列表)。

注意:这是使用图像而不是动画的代码,如果我的问题的解决方案比我想象的更复杂并且有人有解决方案,我们可以联系通过电子邮件或 Skype 或任何其他服务相互联系。

主活动:

using Android.App;
using Android.Widget;
using Android.OS;
using Android.Support.V7.App;
using Android.Support.V4.View;
using Android.Views;
using Android.Content;
using Android.Text;
using Android.Content.Res;
using Android.Graphics;
using Android;
using Android.Graphics.Drawables;

namespace IntroSliderEndy
{
    [Activity(Label = "SliderForTheFirstLaunch")]
    public class MainActivity : AppCompatActivity
    {
        ViewPager viewPager;
        LinearLayout dotsLayout;
        TextView[] dots;
        public int[] layouts;
        Button btnNext, btnSkip;

        protected override void OnCreate(Bundle savedInstanceState)
        {
            base.OnCreate(savedInstanceState);

            SetContentView(Resource.Layout.Main);

            layouts = new int[]
            {
                        Resource.Layout.LayoutSlide1,
                        Resource.Layout.LayoutSlide2,
                        Resource.Layout.LayoutSlide3,
                        Resource.Layout.LayoutSlide4
            };

            viewPager = (ViewPager)FindViewById(Resource.Id.viewPager);
            dotsLayout = (LinearLayout)FindViewById(Resource.Id.layoutPanel);
            btnNext = (Button)FindViewById(Resource.Id.btn_next);
            btnSkip = (Button)FindViewById(Resource.Id.btn_skip);

            addDots(0);

            ViewPagerAdapter adapter = new ViewPagerAdapter(layouts);
            viewPager.Adapter = adapter;

            viewPager.PageSelected += ViewPager_PageSelected;
            //viewPager.AddOnPageChangeListener(new ViewPager.IOnPageChangeListener());


            btnNext.Click += (sender, e) =>
            {
                int current = GetItem(+1);
                if (current < layouts.Length)
                    //Pomakni se u drugi screen
                    viewPager.CurrentItem = current;
                else
                {
                    //Pokreni prvi screen - inace ce se tu otvoriti aplikacija
                    Intent intent = new Intent(this, typeof(MainActivity));
                    StartActivity(intent);

                }
            };

            btnSkip.Click += (sender, e) =>
            {
                Intent intent = new Intent(this, typeof(MainActivity));
                StartActivity(intent);

            };
        }

        void ViewPager_PageSelected(object sender, ViewPager.PageSelectedEventArgs e)
        {
            addDots(e.Position);

            if (e.Position == layouts.Length - 1)
            {
                //Ako je zadnja stranica stavi "GOT IT"
                btnNext.Text = (GetString(Resource.String.start));
                btnSkip.Visibility = ViewStates.Gone;

            }
            else
            {
                //Ako nije zadnja stranica
                btnNext.Text = (GetString(Resource.String.next));
                btnSkip.Visibility = ViewStates.Visible;
            }
        }

        private void addDots(int currentPage)
        {
            dots = new TextView[layouts.Length];


            string[] colorsActive = { "#6A2D4E", "#6A2D4E", "#6A2D4E", "#6A2D4E" };
            string[] colorsInactive = { "#C099AE", "#C099AE", "#C099AE", "#C099AE" };


            dotsLayout.RemoveAllViews();
            for (int i = 0; i < dots.Length; i++)
            {
                dots[i] = new TextView(this);
                dots[i].Text = (Html.FromHtml("•")).ToString();
                dots[i].TextSize = 35;
                dots[i].SetTextColor(Color.ParseColor(colorsActive[currentPage]));
                dotsLayout.AddView(dots[i]);
            }

            if (dots.Length > 0)
            {
                dots[currentPage].SetTextColor(Color.ParseColor(colorsInactive[currentPage]));
            }
        }

        int GetItem(int i)
        {
            return viewPager.CurrentItem + i;
        }

        public class ViewPagerAdapter : PagerAdapter
        {
            LayoutInflater layoutInflater;
            int[] _layout;

            public ViewPagerAdapter(int[] layout)
            {
                _layout = layout;
            }

            public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
            {
                layoutInflater = (LayoutInflater)Android.App.Application.Context.GetSystemService(Context.LayoutInflaterService);
                View view = layoutInflater.Inflate(_layout[position], container, false);
                container.AddView(view);

                return view;
            }

            public override int Count
            {
                get
                {
                    return _layout.Length;
                }
            }

            public override bool IsViewFromObject(View view, Java.Lang.Object objectValue)
            {
                return view == objectValue;
            }

            public override void DestroyItem(ViewGroup container, int position, Java.Lang.Object objectValue)
            {
                View view = (View)objectValue;

                container.RemoveView(view);
            }
        }
    }
 }

主布局:

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
  <android.support.v4.view.ViewPager
      android:id="@+id/viewPager"
      android:layout_width="match_parent"
      android:layout_height="match_parent" />
  <LinearLayout
      android:id="@+id/layoutPanel"
      android:layout_width="match_parent"
      android:layout_alignParentBottom="true"
      android:layout_height="40dp"
      android:gravity="center"
      android:layout_marginBottom="15dp"
      android:orientation="horizontal" />
  <View
      android:layout_width="match_parent"
      android:layout_height="1dp"
      android:alpha="0.5"
      android:layout_above="@id/layoutPanel"
      android:background="@android:color/white" />
  <Button
      android:id="@+id/btn_next"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentRight="true"
      android:background="@android:color/transparent"
      android:text="@string/next"
      android:textColor="#6A2D4E" />
  <Button
      android:id="@+id/btn_skip"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentBottom="true"
      android:layout_alignParentLeft="true"
      android:background="@android:color/transparent"
      android:text="@string/skip"
      android:textColor="#6A2D4E" />
</RelativeLayout>

LayoutSlide1(这只是第一屏的例子,其他的都是一样的,因为我只使用了不同的背景):

    <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@drawable/screen1">
    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:gravity="center"
        android:orientation="vertical">
    </LinearLayout>
</RelativeLayout>

最后是FirstScreenAnimated(SecondScreen和Third和Fourth的代码是一样的,只是图片不同):

    <?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true">
  <item android:drawable="@drawable/BoyIntroFirst01"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst02"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst03"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst04"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst05"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst06"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst07"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst08"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst09"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst10"
        android:duration="150"  />
  <item android:drawable="@drawable/BoyIntroFirst11"
        android:duration="150"  />
</animation-list> 

感谢任何帮助!

【问题讨论】:

    标签: c# android animation xamarin xamarin.android


    【解决方案1】:

    根据您的代码,我猜您想在用户滑动您的ViewPager 时在页面之间显示动画,然后您可以简单地将Transformer 设置为您的ViewPager。例如:

    ...
    viewpager.Adapter = adapter;
    viewpager.SetPageTransformer(true, new ZoomOutPageTransformer());
    

    由于你没有要求具体的动画,ZoomOutPageTransformer只是我根据官方文档修改的一个示例:Customize the Animation with PageTransformer

    public class ZoomOutPageTransformer : Java.Lang.Object, IPageTransformer
    {
        private static float MIN_SCALE = 0.85f;
        private static float MIN_ALPHA = 0.5f;
    
        public void TransformPage(View page, float position)
        {
            int pageWidth = page.Width;
            int pageHeight = page.Height;
    
            if (position < -1)
            {
                page.Alpha = 0;
            }
            else if (position <= 1)
            {
                float scaleFactor = Math.Max(MIN_SCALE, 1 - Math.Abs(position));
                float vertMargin = pageHeight * (1 - scaleFactor) / 2;
                float horzMargin = pageWidth * (1 - scaleFactor) / 2;
                if (position < 0)
                    page.TranslationX = (horzMargin - vertMargin) / 2;
                else
                    page.TranslationX = (vertMargin - horzMargin) / 2;
    
                //Scale the page down
                page.ScaleX = scaleFactor;
                page.ScaleY = scaleFactor;
    
                page.Alpha = (MIN_ALPHA + scaleFactor - MIN_SCALE) / (1 - MIN_SCALE) * (1 - MIN_ALPHA);
            }
            else
            {
                page.Alpha = 0;
            }
        }
    }
    

    【讨论】:

    • 我想你可能误解了我的意思。在页面之间滑动时我不需要动画,我需要 DrawableAnimations(请参阅底部的“可绘制动画”)-> developer.xamarin.com/guides/android/application_fundamentals/… 在每个屏幕上播放,而不是我现在只有图像而不是动画的代码(在 LayoutSlide1-> android:background="screen1" 中,screen1 为 .jpg)。因此,我需要播放我制作的 DrawableAnimation(FirstScreenAnimated 文件),而不是显示那张图片。这次我更清楚了吗? :)
    • 因此,我们尝试采用的这种方法是BAD。它需要很多内存,看起来很糟糕,总而言之,不是很有用。我会将其设置为已回答,因为我在我的 TO-DO 应用程序中使用了此代码进行转换。 :D 谢谢。