Android Gallery3D
MainActivity
package org.wp.activity; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.view.ViewConfiguration; import android.widget.FrameLayout; import android.widget.ImageView; public class MainActivity extends Activity { /** 图片资源ID **/ private Integer[] mImageIds = { R.drawable.image1, R.drawable.image2, R.drawable.image3, R.drawable.image4, R.drawable.image5, R.drawable.image6 }; private static final int LEFT = 0x10; private static final int RIGHT = 0x11; /** FreamLayout **/ private FrameLayout mContainer; /** 第一个ImageView **/ private ImageView myIv1; /** 第二个ImageView **/ private ImageView myIv2; /** 底部圆圈 **/ private PageControlView pageControlView = null; /** 抖动动画 **/ private Animation shake; /** 手势识别对象GestureDetector **/ private GestureDetector gestureDetector = null; /** Handler对象 **/ public Handler iHandler; /** 标识是否动画正在执行 **/ private boolean flag = false; /** 定时开始时间 **/ private long start; /** 当前时间 **/ private long end; /** 显示图片的数量 **/ private final int childCount = 6; /** 当前屏幕索引 **/ private int currentScreenIndex = 0; /** ImageView先后顺序 **/ private int currentIndex = 0; private final int iv1Index = 1; private final int iv2Index = 2; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); addBtnEvent(); addMessageHandler(); } private void addBtnEvent() { // 抖动动画 shake = AnimationUtils.loadAnimation(this, R.anim.shake); // 手势识别 gestureDetector = new GestureDetector(new FlingGestureDetector()); mContainer = (FrameLayout) this.findViewById(R.id.mContainer); mContainer.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View arg0, MotionEvent arg1) { // 如果没有动画正在执行 if (!flag) { // 当前时间记录为开始时间 start = System.currentTimeMillis(); // 判断用户手势 gestureDetector.onTouchEvent(arg1); } return false; } }); myIv1 = (ImageView) this.findViewById(R.id.myIv1); myIv2 = (ImageView) this.findViewById(R.id.myIv2); // 初始化显示图片 myIv2.setImageResource(mImageIds[0]); // 初始化当前图片所以为0 currentScreenIndex = 0; // 当前先后索引为iv2Index currentIndex = iv2Index; pageControlView = (PageControlView) this.findViewById(R.id.myPageControlView); /** 设置圆圈的数量 **/ pageControlView.setCount(childCount); /** 初始化圆圈 **/ pageControlView.generatePageControl(0); // 启动监听线程 new OnFlingListener().start(); } private void addMessageHandler() { iHandler = new Handler() { public void handleMessage(android.os.Message msg) { switch (msg.what) { case LEFT: scrollToScreen(currentScreenIndex - 1, 90.0f); break; case RIGHT: scrollToScreen(currentScreenIndex + 1, -90.0f); break; } } }; } /** 手势识别 **/ private class FlingGestureDetector extends GestureDetector.SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // 判断是否达到最小轻松速度,取绝对值的 if (Math.abs(velocityX) > ViewConfiguration.get(MainActivity.this) .getScaledMinimumFlingVelocity()) { if (velocityX > 0 && currentScreenIndex > 0) { // 上一张图片 scrollToScreen(currentScreenIndex - 1, 90.0f); } else if (velocityX < 0 && currentScreenIndex < childCount - 1) { // 下一张图片 scrollToScreen(currentScreenIndex + 1, -90.0f); } else { // 如果没有,抖动 mContainer.startAnimation(shake); } } return false; } } /** 切换到指定屏 **/ public void scrollToScreen(int whichScreen, float degrees) { // 更新当前屏幕索引 currentScreenIndex = whichScreen; // 重绘底部圆圈 pageControlView.callback(currentScreenIndex); if (currentIndex == iv1Index) { // 如果myIv1在前 currentIndex = iv2Index; // 设置myIv2图片资源 myIv2.setImageResource(mImageIds[whichScreen]); // 旋转myIv1 applyRotation(myIv1, 0, degrees); // 旋转myIv2 applyRotation(myIv2, -degrees, 0); } else if (currentIndex == iv2Index) { // 如果myIv2在前 currentIndex = iv1Index; // 设置myIv1图片资源 myIv1.setImageResource(mImageIds[whichScreen]); // 旋转myIv2 applyRotation(myIv2, 0, degrees); // 旋转myIv1 applyRotation(myIv1, -degrees, 0); } } /** 实现旋转 **/ private void applyRotation(ImageView iv, float start, float end) { final float centerX = mContainer.getWidth() / 2.0f; final float centerY = mContainer.getHeight() / 2.0f; final Rotate3dAnimation rotation = new Rotate3dAnimation(start, end, centerX, centerY); rotation.setDuration(500); rotation.setFillAfter(true); // 监听第二个动画 if (start == 90.0f || start == -90.0f) rotation.setAnimationListener(new DisplayNextView()); iv.startAnimation(rotation); } /** 动画监听器 **/ private final class DisplayNextView implements Animation.AnimationListener { @Override public void onAnimationEnd(Animation arg0) { flag = false; } @Override public void onAnimationRepeat(Animation arg0) { } @Override public void onAnimationStart(Animation arg0) { flag = true; } } /** 定时旋转线程 **/ private final class OnFlingListener extends Thread { private boolean isRunning = true; @Override public void run() { start = System.currentTimeMillis(); end = start; // 标识是否到达最后 boolean bol = false; while (isRunning) { end = System.currentTimeMillis(); // 如果没有动画正在进行且用户空闲操作时间超过3秒 if (!flag && (end - start > 3000)) { if (!bol) { if (currentScreenIndex < childCount - 1) { start = end; iHandler.sendEmptyMessage(RIGHT); } else if (currentScreenIndex == childCount - 1) { bol = true; } } else { if (currentScreenIndex > 0) { start = end; iHandler.sendEmptyMessage(LEFT); } else if (currentScreenIndex == 0) { bol = false; } } } } } // 关闭监听线程 @SuppressWarnings("unused") public void shutDown() { isRunning = false; } } /** 底部圆圈显示回调接口 **/ interface ScrollToScreenCallback { public void callback(int currentIndex); } }
PageControlView
package org.wp.activity; import org.wp.activity.MainActivity.ScrollToScreenCallback; import android.content.Context; import android.util.AttributeSet; import android.widget.ImageView; import android.widget.LinearLayout; public class PageControlView extends LinearLayout implements ScrollToScreenCallback { /** Context对象 **/ private Context context; /** 圆圈的数量 **/ private int count; public PageControlView(Context context, AttributeSet attrs) { super(context, attrs); this.context = context; } @Override public void callback(int currentIndex) { generatePageControl(currentIndex); } public void generatePageControl(int currentIndex) { this.removeAllViews(); for (int i = 0; i < this.count; i++) { ImageView iv = new ImageView(context); if (currentIndex == i) { iv.setImageResource(R.drawable.page_indicator_focused); } else { iv.setImageResource(R.drawable.page_indicator); } this.addView(iv); } } /** 设置圆圈数量 **/ public void setCount(int count) { this.count = count; } }
Rotate3dAnimation
package org.wp.activity; import android.graphics.Camera; import android.graphics.Matrix; import android.view.animation.Animation; import android.view.animation.Transformation; public class Rotate3dAnimation extends Animation { /** 开始旋转的角度 **/ private final float mFromDegrees; /** 旋转结束的角度 **/ private final float mToDegrees; /** 图片中心X坐标 **/ private final float mCenterX; /** 图片中心Y坐标 **/ private final float mCenterY; /** 视角 **/ private Camera mCamera; public Rotate3dAnimation(float fromDegrees, float toDegrees, float centerX, float centerY) { this.mFromDegrees = fromDegrees; this.mToDegrees = toDegrees; this.mCenterX = centerX; this.mCenterY = centerY; } @Override public void initialize(int width, int height, int parentWidth, int parentHeight) { super.initialize(width, height, parentWidth, parentHeight); mCamera = new Camera(); } @Override protected void applyTransformation(float interpolatedTime, Transformation t) { final float fromDegrees = mFromDegrees; // 生成中间角度 float degrees = fromDegrees + ((mToDegrees - fromDegrees) * interpolatedTime); final float centerX = mCenterX; final float centerY = mCenterY; final Camera camera = mCamera; final Matrix matrix = t.getMatrix(); if (degrees >= 76.0f) { // 旋转角度大于76度保持90度 degrees = 90.0f; camera.save(); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); } else if (degrees <= -76.0f) { // 旋转角度小于-76度保持-90度 degrees = -90.0f; camera.save(); camera.rotateY(degrees); camera.getMatrix(matrix); camera.restore(); } else { camera.save(); // 缩小 camera.translate(0, 0, centerX); camera.rotateY(degrees); // 旋转产生偏移效果 camera.translate(0, 0, -centerX); camera.getMatrix(matrix); camera.restore(); } matrix.preTranslate(-centerX, -centerY); matrix.postTranslate(centerX, centerY); } }
anim
shake.xml
<?xml version="1.0" encoding="utf-8"?> <!-- fromXDelta x轴开始位置 toXDelta x轴结束位置 duration 执行时间 interpolator 动画变化率 --> <translate xmlns:android="http://schemas.android.com/apk/res/android" android:fromXDelta="0" android:toXDelta="10" android:duration="850" android:interpolator="@anim/cycle_5" />
cycle_5.xml
<?xml version="1.0" encoding="utf-8"?> <cycleInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:cycles="5" />
相关推荐
huha 2020-10-16
xfcyhades 2020-11-20
sgafdsg 2020-11-04
Michael 2020-11-03
fengyeezju 2020-10-14
ziyexiaoxiao 2020-10-14
业余架构师 2020-10-09
OuNuo0 2020-09-29
moses 2020-09-22
Angelia 2020-09-11
qinxu 2020-09-10
刘炳昭 2020-09-10
Nostalgiachild 2020-09-07
Nostalgiachild 2020-08-17
leavesC 2020-08-14
一青年 2020-08-13
AndroidAiStudy 2020-08-07
ydc0 2020-07-30
绿豆饼 2020-07-28