ViewFlipper和ViewPager 的区别及作用
ViewFlipper和ViewPager 都是一个切换控件,一般用来切换图片资源,用于轮播以及binder展示,ViewPager大家都很熟悉 ,可以展示本地图片也可展示网络图片,说所以说很牛逼,这个ViewFlipper相比较ViewPager 同样可以完成,并且也能添加动画,最主要的是使用相当简单,就比如说是轮播一句代码就搞定,(以下所有mViewFlipper为ViewFlipper的组件对象变量名)
mViewFlipper.startFlipping()
并且不管你是几张图片(打破了ViewPager小于三张图片而crash的现象)这是一个比较好的现象,来看一下效果,(This is my goddess)
由于CSDN上传图片不能超过2M,我将这篇文章放在了简书 可以点击查看,但是我现在习惯了CSDN的编辑软件,又爱又恨啊,好了下面看代码
首先布局很简单
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.android.viewflipperdemo.MainActivity">
<ViewFlipper
android:id="@+id/mViewFlipper"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="40dp"
android:flipInterval="2000">
<!--android:flipInterval="2000" 每隔2000 单位毫秒进行下一张资源播放 -->
</ViewFlipper>
</LinearLayout>
属性不做过多解释
一、轮播图代码
class MainActivity : AppCompatActivity(), View.OnTouchListener {
private var images = arrayOf(
R.mipmap.a,
R.mipmap.b,
R.mipmap.f)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
addResources()
mViewFlipper.startFlipping()
}
private fun addResources() {
for (i in 0 until images.size) {
mViewFlipper.addView(getImageView(decodeSampledBitmapFromResource(resources, images[i], 400, 400)))
}
}
private fun getImageView(bitmap: Bitmap): View? {
val imageView = ImageView(this)
imageView.setImageBitmap(bitmap)
imageView.scaleType = ImageView.ScaleType.FIT_XY
return imageView
}
/**
* 图片的二次采样
*
* @param resources
* @param width
* @param height
*/
private fun decodeSampledBitmapFromResource(resources: Resources, resId: Int, width: Int, height: Int): Bitmap {
val options = BitmapFactory.Options()
//只解析图片的宽高 而不加载真正的图片
options.inJustDecodeBounds = true
BitmapFactory.decodeResource(resources, resId, options)
options.inSampleSize = calculateInSampleSize(options, width, height)
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false
return BitmapFactory.decodeResource(resources, resId, options)
}
/**
* 计算inSampleSize 值
* @param options
* @param width
* @param height
* @return
*/
private fun calculateInSampleSize(options: BitmapFactory.Options, width: Int, height: Int): Int {
if (width == 0 || height == 0) {
return 1
}
//图片的原始宽高
val outHeight = options.outHeight
val outWidth = options.outWidth
var inSampleSize = 1
//如果宽和高有一个不符合 就进行调整
if (outHeight > height || outWidth > width) {
// inSampleSize 为 1 没有作用,使从 2 开始增加
val newWidth = outWidth / 2
val newHeight = outHeight / 2
while (newHeight / inSampleSize >= height && newWidth / inSampleSize >= width) {
inSampleSize *= 2
}
}
return inSampleSize
}
上面的代码就是轮播图的代码很简单的一句代码(但是本地的图片过大,所以对图片进行了二次采样)
二、在现实开发环境中,我们是需要轮播的时候可以手动滑动的
当然,这个在ViewFlipper 中也是可以实现的,布局不发生变化,代码中添加以下代码
package com.android.viewflipperdemo
import android.content.res.Resources
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.view.GestureDetector
import android.view.MotionEvent
import android.view.View
import android.widget.ImageView
import android.widget.ViewFlipper
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), View.OnTouchListener {
private var images = arrayOf(
R.mipmap.a,
R.mipmap.b,
R.mipmap.f)
private lateinit var detector: GestureDetector
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onStart() {
super.onStart()
addResources()
***mViewFlipper.setOnTouchListener(this)***
mViewFlipper.startFlipping()
***detector = GestureDetector(SimpleGestureDetector(mViewFlipper))***
}
***private class SimpleGestureDetector : GestureDetector.SimpleOnGestureListener {
companion object {
val FLING_MIN_DISTANCE: Int = 100
val FLING_MIN_VELOCITY: Int = 200
}
private var mViewFlipper: ViewFlipper? = null
constructor(mViewFlipper: ViewFlipper) {
this.mViewFlipper = mViewFlipper
}
override fun onDown(e: MotionEvent?): Boolean {
return true
}
override fun onFling(e1: MotionEvent?, e2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean {
if (e2?.x?.let { e1?.x?.minus(it) }!! > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
mViewFlipper?.showNext()
} else if (e1 != null) {
if (e2?.x.minus(e1.x) > FLING_MIN_DISTANCE
&& Math.abs(velocityX) > FLING_MIN_VELOCITY) {
mViewFlipper?.showPrevious()
}
}
return true
}
}***
private fun addResources() {
for (i in 0 until images.size) {
mViewFlipper.addView(getImageView(decodeSampledBitmapFromResource(resources, images[i], 400, 400)))
}
}
private fun getImageView(bitmap: Bitmap): View? {
val imageView = ImageView(this)
imageView.setImageBitmap(bitmap)
imageView.scaleType = ImageView.ScaleType.FIT_XY
return imageView
}
/**
* 图片的二次采样
*
* @param resources
* @param width
* @param height
*/
private fun decodeSampledBitmapFromResource(resources: Resources, resId: Int, width: Int, height: Int): Bitmap {
val options = BitmapFactory.Options()
//只解析图片的宽高 而不加载真正的图片
options.inJustDecodeBounds = true
BitmapFactory.decodeResource(resources, resId, options)
options.inSampleSize = calculateInSampleSize(options, width, height)
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false
return BitmapFactory.decodeResource(resources, resId, options)
}
/**
* 计算inSampleSize 值
* @param options
* @param width
* @param height
* @return
*/
private fun calculateInSampleSize(options: BitmapFactory.Options, width: Int, height: Int): Int {
if (width == 0 || height == 0) {
return 1
}
//图片的原始宽高
val outHeight = options.outHeight
val outWidth = options.outWidth
var inSampleSize = 1
//如果宽和高有一个不符合 就进行调整
if (outHeight > height || outWidth > width) {
// inSampleSize 为 1 没有作用,使从 2 开始增加
val newWidth = outWidth / 2
val newHeight = outHeight / 2
while (newHeight / inSampleSize >= height && newWidth / inSampleSize >= width) {
inSampleSize *= 2
}
}
return inSampleSize
}
***override fun onTouch(v: View?, event: MotionEvent?): Boolean {
return detector.onTouchEvent(event)
}***
}
OK ,这就是ViewFlipper的简单的用法,至于它的动画等操作,和ViewPager是一样的,都有自己的设置添加动画的方法,具体操作业相似