`

ImageView翻转效果

 
阅读更多
点击图中的星星开始翻转

源码:
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Camera;
import android.graphics.Matrix;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.Transformation;
import android.widget.ImageView;

import fr.castorflex.android.flipimageview.R;

/**
 * Created with IntelliJ IDEA. User: castorflex Date: 30/12/12 Time: 16:25
 */
public class FlipImageView extends ImageView implements View.OnClickListener,
        Animation.AnimationListener {

    private static final int FLAG_ROTATION_X = 1 << 0;

    private static final int FLAG_ROTATION_Y = 1 << 1;

    private static final int FLAG_ROTATION_Z = 1 << 2;

    private static final Interpolator fDefaultInterpolator = new DecelerateInterpolator();

    private static int sDefaultDuration;

    private static int sDefaultRotations;

    private static boolean sDefaultAnimated;

    private static boolean sDefaultFlipped;


    public interface OnFlipListener {

        public void onClick(boolean flipped);

        public void onFlipStart();

        public void onFlipEnd();
    }

    private OnFlipListener mListener;

    private boolean mIsFlipped;

    private boolean mIsDefaultAnimated;

    private Drawable mDrawable;

    private Drawable mFlippedDrawable;

    private FlipAnimator mAnimation;

    private boolean mIsRotationXEnabled;

    private boolean mIsRotationYEnabled;

    private boolean mIsRotationZEnabled;

    public FlipImageView(Context context) {
        super(context);
        init(context, null, 0);
    }

    public FlipImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs, 0);
    }

    public FlipImageView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context, attrs, defStyle);
    }

    private void init(Context context, AttributeSet attrs, int defStyle) {
        sDefaultDuration = context.getResources().getInteger(R.integer.default_fiv_duration);
        sDefaultRotations = context.getResources().getInteger(R.integer.default_fiv_rotations);
        sDefaultAnimated = context.getResources().getBoolean(R.bool.default_fiv_isAnimated);
        sDefaultFlipped = context.getResources().getBoolean(R.bool.default_fiv_isFlipped);

        TypedArray a = context
                .obtainStyledAttributes(attrs, R.styleable.FlipImageView, defStyle, 0);
        mIsDefaultAnimated = a.getBoolean(R.styleable.FlipImageView_isAnimated, sDefaultAnimated);
        mIsFlipped = a.getBoolean(R.styleable.FlipImageView_isFlipped, sDefaultFlipped);
        mFlippedDrawable = a.getDrawable(R.styleable.FlipImageView_flipDrawable);
        int duration = a.getInt(R.styleable.FlipImageView_flipDuration, sDefaultDuration);
        int interpolatorResId = a.getResourceId(R.styleable.FlipImageView_flipInterpolator, 0);
        Interpolator interpolator = interpolatorResId > 0 ? AnimationUtils
                .loadInterpolator(context, interpolatorResId) : fDefaultInterpolator;
        int rotations = a.getInteger(R.styleable.FlipImageView_flipRotations, sDefaultRotations);
        mIsRotationXEnabled = (rotations & FLAG_ROTATION_X) != 0;
        mIsRotationYEnabled = (rotations & FLAG_ROTATION_Y) != 0;
        mIsRotationZEnabled = (rotations & FLAG_ROTATION_Z) != 0;

        mDrawable = getDrawable();

        mAnimation = new FlipAnimator();
        mAnimation.setAnimationListener(this);
        mAnimation.setInterpolator(interpolator);
        mAnimation.setDuration(duration);

        setOnClickListener(this);

        setImageDrawable(mIsFlipped ? mFlippedDrawable : mDrawable);

        a.recycle();
    }

    public boolean isRotationXEnabled() {
        return mIsRotationXEnabled;
    }

    public void setRotationXEnabled(boolean enabled) {
        mIsRotationXEnabled = enabled;
    }

    public boolean isRotationYEnabled() {
        return mIsRotationYEnabled;
    }

    public void setRotationYEnabled(boolean enabled) {
        mIsRotationYEnabled = enabled;
    }

    public boolean isRotationZEnabled() {
        return mIsRotationZEnabled;
    }

    public void setRotationZEnabled(boolean enabled) {
        mIsRotationZEnabled = enabled;
    }

    public FlipAnimator getFlipAnimation() {
        return mAnimation;
    }

    public void setInterpolator(Interpolator interpolator) {
        mAnimation.setInterpolator(interpolator);
    }

    public void setDuration(int duration) {
        mAnimation.setDuration(duration);
    }

    public boolean isFlipped() {
        return mIsFlipped;
    }

    public boolean isAnimated() {
        return mIsDefaultAnimated;
    }

    public void setAnimated(boolean animated) {
        mIsDefaultAnimated = animated;
    }

    public void setFlipped(boolean flipped) {
        setFlipped(flipped, mIsDefaultAnimated);
    }

    public void setFlipped(boolean flipped, boolean animated) {
        if (flipped != mIsFlipped) {
            toggleFlip(animated);
        }
    }

    public void toggleFlip() {
        toggleFlip(mIsDefaultAnimated);
    }

    public void toggleFlip(boolean animated) {
        if (animated) {
            mAnimation.setToDrawable(mIsFlipped ? mDrawable : mFlippedDrawable);
            startAnimation(mAnimation);
        } else {
            setImageDrawable(mIsFlipped ? mDrawable : mFlippedDrawable);
        }
        mIsFlipped = !mIsFlipped;
    }


    public void setOnFlipListener(OnFlipListener listener) {
        mListener = listener;
    }


    @Override
    public void onClick(View v) {
        toggleFlip();
        if (mListener != null) {
            mListener.onClick(mIsFlipped);
        }
    }

    @Override
    public void onAnimationStart(Animation animation) {
        if (mListener != null) {
            mListener.onFlipStart();
        }
    }

    @Override
    public void onAnimationEnd(Animation animation) {
        if (mListener != null) {
            mListener.onFlipEnd();
        }
    }

    @Override
    public void onAnimationRepeat(Animation animation) {
    }

    /**
     * Animation part All credits goes to coomar
     */
    public class FlipAnimator extends Animation {

        private Camera camera;

        private Drawable toDrawable;

        private float centerX;

        private float centerY;

        private boolean forward = true;

        private boolean visibilitySwapped;

        public void setToDrawable(Drawable to) {
            toDrawable = to;
            visibilitySwapped = false;
        }

        public FlipAnimator() {
            setFillAfter(true);
        }


        @Override
        public void initialize(int width, int height, int parentWidth, int parentHeight) {
            super.initialize(width, height, parentWidth, parentHeight);
            camera = new Camera();
            this.centerX = width / 2;
            this.centerY = height / 2;
        }

        @Override
        protected void applyTransformation(float interpolatedTime, Transformation t) {
            // Angle around the y-axis of the rotation at the given time. It is
            // calculated both in radians and in the equivalent degrees.
            final double radians = Math.PI * interpolatedTime;
            float degrees = (float) (180.0 * radians / Math.PI);

            // Once we reach the midpoint in the animation, we need to hide the
            // source view and show the destination view. We also need to change
            // the angle by 180 degrees so that the destination does not come in
            // flipped around. This is the main problem with SDK sample, it does not
            // do this.
            if (interpolatedTime >= 0.5f) {
                degrees -= 180.f;

                if (!visibilitySwapped) {
                    setImageDrawable(toDrawable);
                    visibilitySwapped = true;
                }
            }

            if (forward) {
                degrees = -degrees;
            }

            final Matrix matrix = t.getMatrix();

            camera.save();
            camera.translate(0.0f, 0.0f, (float) (150.0 * Math.sin(radians)));
            camera.rotateX(mIsRotationXEnabled ? degrees : 0);
            camera.rotateY(mIsRotationYEnabled ? degrees : 0);
            camera.rotateZ(mIsRotationZEnabled ? degrees : 0);
            camera.getMatrix(matrix);
            camera.restore();

            matrix.preTranslate(-centerX, -centerY);
            matrix.postTranslate(centerX, centerY);
        }
    }
}


使用方法:
import android.app.Activity;
import android.os.Bundle;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AnticipateOvershootInterpolator;
import android.view.animation.BounceInterpolator;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.view.animation.OvershootInterpolator;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.SeekBar;
import android.widget.Spinner;
import android.widget.TextView;

import fr.castorflex.android.flipimageview.R;
import fr.castorflex.android.flipimageview.library.FlipImageView;

public class SampleActivity extends Activity implements FlipImageView.OnFlipListener,
        SeekBar.OnSeekBarChangeListener {

    private static final String[] fData = new String[]{
            "Decelerate",
            "Accelerate",
            "AccelerateDecelerate",
            "Bounce",
            "Overshoot",
            "AnticipateOvershoot"

    };

    private static final Interpolator[] fInterpolators = new Interpolator[]{
            new DecelerateInterpolator(),
            new AccelerateInterpolator(),
            new AccelerateDecelerateInterpolator(),
            new BounceInterpolator(),
            new OvershootInterpolator(),
            new AnticipateOvershootInterpolator()
    };

    private SeekBar mSeekBar;

    private Spinner mSpinner;

    private TextView mTextViewDuration;

    private FlipImageView mFlipImageView;

    private CheckBox mCheckBoxX;

    private CheckBox mCheckBoxY;

    private CheckBox mCheckBoxZ;

    private TextView mTextViewAnimationListener;

    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mTextViewAnimationListener = (TextView) findViewById(R.id.textview);
        mFlipImageView = (FlipImageView) findViewById(R.id.imageview);
        mSpinner = (Spinner) findViewById(R.id.spinner);
        mTextViewDuration = (TextView) findViewById(R.id.textview_duration);
        mSeekBar = (SeekBar) findViewById(R.id.seekbar);
        mCheckBoxX = (CheckBox) findViewById(R.id.checkedtextview_x);
        mCheckBoxY = (CheckBox) findViewById(R.id.checkedtextview_y);
        mCheckBoxZ = (CheckBox) findViewById(R.id.checkedtextview_z);

        mSpinner.setAdapter(
                new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, fData));

        mSeekBar.setOnSeekBarChangeListener(this);

        mFlipImageView.setOnFlipListener(this);
    }

    /////////////////////FLIP IMAGE VIEW///////////////////

    @Override
    public void onClick(boolean flipped) {
        mFlipImageView.setInterpolator(fInterpolators[mSpinner.getSelectedItemPosition()]);
        mFlipImageView.setDuration(mSeekBar.getProgress());
        mFlipImageView.setRotationXEnabled(mCheckBoxX.isChecked());
        mFlipImageView.setRotationYEnabled(mCheckBoxY.isChecked());
        mFlipImageView.setRotationZEnabled(mCheckBoxZ.isChecked());
    }

    @Override
    public void onFlipStart() {
        mTextViewAnimationListener.setText("OnFlipStart");
    }

    @Override
    public void onFlipEnd() {
        mTextViewAnimationListener.setText("OnFlipEnd");
    }

    ////////////////////////SEEK BAR/////////////////////////

    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        mTextViewDuration.setText("" + progress);
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }
}



生动的喜欢与收藏按钮MaterialFavoriteButton
http://www.jcodecraeer.com/a/opensource/2015/1009/3555.html
  • 大小: 38.7 KB
分享到:
评论

相关推荐

    左右翻转的ImageView

    总的来说,"ImageRotate"是一个方便实用的框架,它为Android开发者提供了轻松实现ImageView左右翻转效果的解决方案。通过引入和配置这个框架,你可以节省大量的开发时间,并且可以专注于为用户提供更富有趣味性和...

    Android 利用Camera实现中轴3D卡牌翻转效果

    "Android 利用Camera实现中轴3D卡牌翻转效果"是一种创新且视觉上吸引人的技术,它能够为用户带来更丰富的交互体验。这个效果常用于卡片式设计的应用,如社交应用中的消息展示或者游戏中的卡牌翻转等场景。下面我们将...

    图片花式3D翻转效果

    "图片花式3D翻转效果"是一个实现动态、炫酷图片切换功能的技术主题,它通过自定义View来实现各种3D视觉效果,包括百叶窗、3D轮转、3D开合、3D翻转以及2D平移。下面将详细讲解这些技术点及其实现原理。 首先,自定义...

    图像翻转效果的源代码资源

    在图像处理领域,图像翻转效果是一种常见的视觉特效,它能改变图像的朝向或镜像展示,使得图像呈现出不同的视觉感受。这个压缩包文件"图像翻转效果"可能包含了实现这种效果的源代码资源,这对于我们理解图像翻转原理...

    android图片翻转效果

    android卡片翻转效果,使用view的draw方法直接绘制,节省性能,如果放到liestview或者recycleview中的话,请自行稍加修改,不要使用bitmap来做存储即可,本想0分,但是目前至少要选1分,没法办

    Android3D翻转效果源码

    在Android开发中,3D翻转效果是一种常见的动画过渡手段,可以为用户界面带来生动而富有立体感的视觉体验。这种效果通常应用于Activity之间的切换,使得应用的交互更加吸引人。本文将深入探讨如何实现Android的3D翻转...

    android翻转效果(诚信工作室)[借鉴].pdf

    在Android开发中,实现物体翻转效果是一种常见的动画需求,比如在卡片翻转、界面切换等场景中。这里介绍的是一种基于自定义`Animation`类`Rotate3d`实现的二维翻转效果,而非直接使用`Matrix`进行图像变换。 `...

    图片翻转动画效果

    在本案例中,我们将使用补间动画来实现图片翻转效果。 补间动画是Android早期版本(API level 8 及以下)中使用的一种动画机制,它通过改变对象在一定时间内的属性值来创建动画效果。要实现图片翻转,我们可以继承`...

    Gallery倒影效果+滑动翻转

    2. **滑动翻转效果**: - 滑动翻转特效是指在用户滑动`Gallery`时,当前显示的图片进行3D翻转动画,以过渡到下一个或上一个图片。这可以通过自定义`Adapter`和使用`Animation`类来实现。 - 创建滑动翻转动画可能...

    安卓Android源码——模拟立体翻转效果,非Gallery实现.rar

    2. **选择目标视图**:确定要应用翻转效果的视图,这可能是布局中的一个子视图,例如ImageView或LinearLayout。 3. **设置动画属性**:使用`ObjectAnimator.ofFloat()`方法为视图的特定属性(如rotationY)设置动画...

    Android ImageView实现照片墙效果(卡片式滑出效果) 源码

    本示例中的"Android ImageView实现照片墙效果(卡片式滑出效果) 源码"是一个很好的案例,它展示了如何通过自定义控件来构建一个美观且互动性强的照片浏览功能。这个功能的核心在于卡片式滑出效果,它使得图片在切换...

    Android 翻转动画 ,像硬币一样的翻转动画

    在这个案例中,我们将关注补间动画,因为它们更适合实现翻转效果。补间动画可以通过XML文件定义,并在代码中应用到视图上。 要创建翻转动画,我们需要创建两个XML文件,分别定义翻转前后的状态。这两个文件应放在`...

    android图片翻转动画

    视图动画在API 16及以下版本中广泛使用,而属性动画自API 11引入,提供了更强大的功能,包括3D翻转效果。考虑到Android设备的广泛性,我们通常会使用属性动画来实现3D图片翻转,以便支持更多的设备。 在实现3D翻转...

    android中进行图片的3D效果以及倒影效果

    我们可以创建一个新的`Bitmap`对象,对原图进行翻转,然后将其与原图拼接。以下是一个简单的实现: ```java Bitmap bitmap = ... // 原始图片 Bitmap reflectionBitmap = createReflection(bitmap); Bitmap ...

    ImageView.zip

    8. **android:rotation**、`android:rotationX`和`android:rotationY`:这些属性允许你对ImageView进行旋转和平面翻转。 9. **android:translationX**和`android:translationY`:这两个属性用于在父容器内平移...

    android 动态旋转图片 Bitmap与Matrix旋转ImageView

    在Android开发中,图片...开发者需要理解这两个类的使用方法,以及如何在ImageView中应用Matrix变换,以实现丰富的图像操作和动态效果。同时,考虑到性能和内存管理,合理地处理Bitmap和Matrix的生命周期是非常重要的。

    android 自定义ImageView实现图片手势滑动,多点触摸放大缩小效果

    本文将深入探讨如何自定义一个ImageView,以实现在屏幕上通过手势滑动图片以及支持多点触摸进行图片的放大和缩小效果。这个自定义ImageView的实现,通常会涉及到Android的触摸事件处理、Matrix变换以及手势识别等...

    可放大缩小的ImageView

    为了实现类似Instagram那样可以放大缩小图片的效果,开发者通常会使用扩展了`ImageView`功能的库,如`ImageViewTouch`。这个库提供了对图片的平移、缩放、旋转等手势操作的支持,极大地提升了用户体验。 `...

    Gallery的小demo倒影效果滑动翻转

    滑动翻转效果通常涉及到动画的使用。在Android中,可以使用`Animation`类或`ObjectAnimator`类来实现。当用户滑动`Gallery`时,我们可以监听`OnItemSelectedListener`的回调,当选中项改变时,启动一个翻转动画。这...

Global site tag (gtag.js) - Google Analytics