Android 组件之ViewFlipper

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是一样的,都有自己的设置添加动画的方法,具体操作业相似

猜你喜欢

转载自blog.csdn.net/qq_32648731/article/details/78215291