📜  在 Android 中使用 ViewPager 缩放动画中的立方体

📅  最后修改于: 2022-05-13 01:54:50.963000             🧑  作者: Mango

在 Android 中使用 ViewPager 缩放动画中的立方体

Android ViewPager 已经成为 Android 应用程序中一个非常有趣的概念。它使用户能够在具有通用 UI 的片段之间平滑切换,这是使您的应用程序与众不同的最佳方式。 ViewPagers 提供视觉连续性。他们基本上跟踪哪个页面是可见的,然后要求 PageAdapter 显示层次结构中的下一个页面。不仅如此,它甚至可以让您创建各种很棒的幻灯片效果和动画!

我们将在本文中构建什么?

在本文中,我们将使用 ViewPager 实现立方体缩放动画。下面给出了一个示例 GIF,以了解我们将在本文中做什么。请注意,我们将使用Kotlin语言来实现这个项目。

ViewPager 的完整实现有 3 个基本组件:

  • 一个包含 ViewPager 和主 UI 的活动。
  • 在 ViewPager 中作为单独页面查看的一组 Fragment。
  • FragmentPageAdapter 或 FragmentStatePageAdapter 返回接下来需要显示的正确片段。

例如参考文章——ViewPager Using Fragments in Android with Example。



分步实施

在这里,我们将使用 ViewPager 制作一个图像滑块,然后应用立方体缩放动画。

第 1 步:创建一个新项目

要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。请注意,选择Kotlin作为编程语言。

第 2 步:设计 UI

下面是activity_main.xml文件的代码。我们只添加了一个 ViewPager 来显示图像。下面是 activity_main.xml 文件的完整代码。

XML


  
    
    
  


XML


  
    
    
  


Kotlin
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.viewpager.widget.PagerAdapter
import java.util.*
  
internal class ViewPagerAdapter(private val context: Context, private val images: IntArray) : PagerAdapter() {
  
    // Layout Inflater
    var mLayoutInflater: LayoutInflater
    override fun getCount(): Int {
        // return the number of images
        return images.size
    }
  
    init {
        mLayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    }
  
    override fun isViewFromObject(view: View, `object`: Any): Boolean {
        return view === `object` as LinearLayout
    }
  
    override fun instantiateItem(container: ViewGroup, position: Int): Any {
          
        // inflating the item.xml
        val itemView: View = mLayoutInflater.inflate(R.layout.item, container, false)
  
        // referencing the image view from the item.xml file
        val imageView: ImageView = itemView.findViewById(R.id.imageViewMain)
  
        // setting the image in the imageView
        imageView.setImageResource(images[position])
  
        // Adding the View
        Objects.requireNonNull(container).addView(itemView)
        return itemView
    }
  
    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
        container.removeView(`object` as LinearLayout)
    }
}


Kotlin
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
  
class MainActivity : AppCompatActivity() {
      
    // creating object of ViewPager
    lateinit var mViewPager: ViewPager
  
    // images array
    private var images = intArrayOf(R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4)
  
    // Creating Object of ViewPagerAdapter
    private lateinit var mViewPagerAdapter: ViewPagerAdapter
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // Initializing the ViewPager Object
        mViewPager = findViewById(R.id.viewPagerMain)
  
        mViewPager.setPageTransformer(true, CubeInScalingAnimation())
  
        // Initializing the ViewPagerAdapter
        mViewPagerAdapter = ViewPagerAdapter(this@MainActivity, images)
  
        // Adding the Adapter to the ViewPager
        mViewPager.adapter = mViewPagerAdapter
    }
}


Kotlin
import android.view.View
import androidx.viewpager.widget.ViewPager
import kotlin.math.abs
  
class CubeInScalingAnimation : ViewPager.PageTransformer {
  
    override fun transformPage(page: View, position: Float) {
        page.cameraDistance = 20000F
        when {
            position < -1 -> {   //{-infinity,-1}
                // page offset to left side
                page.alpha = 0F
            }
            position <= 0 -> {
                // transition from left 
                // side of page to current page
                page.alpha = 1F
                page.pivotX = page.width.toFloat()
                page.rotationY = 90F * abs(position)
            }
            position <= 1 -> {
                // transition form current 
                // page to right side
                page.alpha = 1F
                page.pivotX = 0F
                page.rotationY = -90F * abs(position)
            }
            //{1,+infinity}
            else -> { //Page offset to right side
                page.alpha = 0F
            }
        }
  
        when {
            // transition between page1 and page2
            abs(position) <= 0.5 -> {
                page.scaleY = Math.max(0.4f, 1 - abs(position))
            }
            abs(position) <= 1 -> {
                page.scaleY = Math.max(0.4f, abs(position))
            }
        }
    }
}


现在,在app > res > layout文件夹中创建一个新的布局资源文件item.xml。下面是item.xml文件的代码。

XML





  
    
    
  

步骤 3:使用 ViewPagerAdapter.kt 和 MainActivity.kt 文件

首先,创建一个ViewPagerAdapter类,一个 ViewPager 的 Adapter。下面是 ViewPagerAdapter.kt类的完整代码。代码中添加了注释以了解代码的每一行。

科特林

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.viewpager.widget.PagerAdapter
import java.util.*
  
internal class ViewPagerAdapter(private val context: Context, private val images: IntArray) : PagerAdapter() {
  
    // Layout Inflater
    var mLayoutInflater: LayoutInflater
    override fun getCount(): Int {
        // return the number of images
        return images.size
    }
  
    init {
        mLayoutInflater = context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater
    }
  
    override fun isViewFromObject(view: View, `object`: Any): Boolean {
        return view === `object` as LinearLayout
    }
  
    override fun instantiateItem(container: ViewGroup, position: Int): Any {
          
        // inflating the item.xml
        val itemView: View = mLayoutInflater.inflate(R.layout.item, container, false)
  
        // referencing the image view from the item.xml file
        val imageView: ImageView = itemView.findViewById(R.id.imageViewMain)
  
        // setting the image in the imageView
        imageView.setImageResource(images[position])
  
        // Adding the View
        Objects.requireNonNull(container).addView(itemView)
        return itemView
    }
  
    override fun destroyItem(container: ViewGroup, position: Int, `object`: Any) {
        container.removeView(`object` as LinearLayout)
    }
}

下面是 MainActivity.kt文件的完整代码。代码中添加了注释以了解代码的每一行。

科特林

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.viewpager.widget.ViewPager
  
class MainActivity : AppCompatActivity() {
      
    // creating object of ViewPager
    lateinit var mViewPager: ViewPager
  
    // images array
    private var images = intArrayOf(R.drawable.a1, R.drawable.a2, R.drawable.a3, R.drawable.a4)
  
    // Creating Object of ViewPagerAdapter
    private lateinit var mViewPagerAdapter: ViewPagerAdapter
  
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // Initializing the ViewPager Object
        mViewPager = findViewById(R.id.viewPagerMain)
  
        mViewPager.setPageTransformer(true, CubeInScalingAnimation())
  
        // Initializing the ViewPagerAdapter
        mViewPagerAdapter = ViewPagerAdapter(this@MainActivity, images)
  
        // Adding the Adapter to the ViewPager
        mViewPager.adapter = mViewPagerAdapter
    }
}

第 4 步:创建一个新类CubeInScalingAnimation.kt以应用 Cube-in-scaling-animation。下面是 CubeInScalingAnimation.kt文件的完整代码。代码中添加了注释以了解代码的每一行。

科特林

import android.view.View
import androidx.viewpager.widget.ViewPager
import kotlin.math.abs
  
class CubeInScalingAnimation : ViewPager.PageTransformer {
  
    override fun transformPage(page: View, position: Float) {
        page.cameraDistance = 20000F
        when {
            position < -1 -> {   //{-infinity,-1}
                // page offset to left side
                page.alpha = 0F
            }
            position <= 0 -> {
                // transition from left 
                // side of page to current page
                page.alpha = 1F
                page.pivotX = page.width.toFloat()
                page.rotationY = 90F * abs(position)
            }
            position <= 1 -> {
                // transition form current 
                // page to right side
                page.alpha = 1F
                page.pivotX = 0F
                page.rotationY = -90F * abs(position)
            }
            //{1,+infinity}
            else -> { //Page offset to right side
                page.alpha = 0F
            }
        }
  
        when {
            // transition between page1 and page2
            abs(position) <= 0.5 -> {
                page.scaleY = Math.max(0.4f, 1 - abs(position))
            }
            abs(position) <= 1 -> {
                page.scaleY = Math.max(0.4f, abs(position))
            }
        }
    }
}

现在,运行应用程序

输出:

源代码:点击这里

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!