android 数字翻转

2017-07-11 21:56:04 fan7983377 阅读数 3713


废话不多说,效果图:


这里写图片描述


自定义控件找自网络,使用相对简单,具体还没有来得及深入研究,只是先用笨方法大概实现了想要的效果,后续有空会仔细研究再更新文章,


本demo切换方法是用的笨方法,也就是由新数字和旧数字相比较来切换数字变换的,大致使用方法如下:

        //获取输入框中的数字
        int newNumber = Integer.parseInt(etInput.getText().toString());

        //获取个、十、百位数字
        int nbai = newNumber / 100;
        int nshi = newNumber % 100 / 10;
        int nge = newNumber % 10;

        //获取上次数字的个、十、百位数字
        int obai = oldNumber / 100;
        int oshi = oldNumber % 100 / 10;
        int oge = oldNumber % 10;

        //把当前的数字记录下来
        oldNumber = newNumber;

        //获取新数字与旧数字的个、十、百相差的数字
        int bai = nbai + 10 - obai;
        int shi = nshi + 10 - oshi;
        int ge = nge + 10 - oge;

        //如果值大于9,就减去10
        if(bai > 9){
            bai = bai - 10;
        }

        if(shi > 9){
            shi = shi - 10;
        }

        if(ge > 9){
            ge = ge - 10;
        }

        //把需要切换几次设置到自定义控件上
        bitflip1.smoothFlip(bai, false);
        bitflip2.smoothFlip(shi, false);
        bitflip3.smoothFlip(ge, false);




上面就是实现的过程,想要看更好点的算法,等待后续更新把




代码下载:点击下载



2014-09-30 21:55:04 hubianyu 阅读数 701

package basc.day003;

import java.util.Arrays;

public class RecNmmber {

/** * 翻转数字输出。例如123 输出321;

*/ public static void main(String[] args) {

/ TODO 自动生成的方法存根

System.out.println(rec(1234567));

}

public static String rec(int num){

String str = num +""; String[] str2 = new String [str.length()];

String backnum ; int a = 0;

for(int i=str.length()-1;i>=0;i--){

String str1 = String.valueOf(str.charAt(i)); str2[a] = str1; a+=1;

}

backnum = Arrays.toString(str2); return backnum;

}}------

2013-12-30 14:41:29 woaieillen 阅读数 849

本示例为接下来的“SurfaceView使用实例做铺垫。


先上效果图如下:



要求:
沿Y轴正方向看,数值减1时动画逆时针旋转,数值加1时动画顺时针旋转。

实现动画的具体细节见"RotateAnimation.java"。为方便查看动画旋转方向,可以将RotateAnimation.DEBUG值设置为true即可。

         
RotateAnimation参考自APIDemos的Rotate3DAnimation

         RotateAnimation的构造函数需有三个参数,分别说明动画组件的中心点位置及旋转方向。

         RotateAnimation.initialize()将初始化动画组件及其父容器的宽高;通常亦可进行另外的初始化工作,本例中用于执行对camera进行实例化赋值。

         RotateAnimation.applyTransformation()第一个参数为动画的进度时间值,取值范围为[0.0f,1.0f],第二个参数Transformation记录着动画某一帧中变形的原始数据。该方法在动画的每一帧显示过程中都会被调用。

         
在翻转过程中,为了避免在动画下半部分时图像为镜面效果影响数字的阅读,应将翻转角度做180度的减法。代码为RotateAnimation.applyTransformation()中的:

[java] view plaincopy
  1. if (overHalf) {  
  2.     // 翻转过半的情况下,为保证数字仍为可读的文字而非镜面效果的文字,需翻转180度。  
  3.     degree = degree - 180;  
  4. }  

动画翻转到一半后,应更新数字内容。为了得知翻转进度,于RotateAnimation中设计一内部静态接口类"InterpolatedTimeListener",该接口只有一个方法"interpolatedTime(float interpolatedTime)"可以将动画进度传递给监听发起者。

本文章由Sodino所有,转载请注明出处:http://blog.csdn.net/sodino/article/details/7703980


Java代码如下,XML请根据效果图自行实现:


ActRotate.java

[java] view plaincopy
  1. package lab.sodino.rotate;  
  2.   
  3. import lab.sodino.rotate.RotateAnimation.InterpolatedTimeListener;  
  4. import android.app.Activity;  
  5. import android.os.Bundle;  
  6. import android.util.Log;  
  7. import android.view.View;  
  8. import android.view.View.OnClickListener;  
  9. import android.widget.Button;  
  10. import android.widget.TextView;  
  11.   
  12. /** 
  13.  * @author Sodino E-mail:sodinoopen@hotmail.com 
  14.  * @version Time:2012-6-27 上午07:32:00 
  15.  */  
  16. public class ActRotate extends Activity implements OnClickListener, InterpolatedTimeListener {  
  17.     private Button btnIncrease, btnDecrease;  
  18.     private TextView txtNumber;  
  19.     private int number;  
  20.     /** TextNumber是否允许显示最新的数字。 */  
  21.     private boolean enableRefresh;  
  22.   
  23.     public void onCreate(Bundle savedInstanceState) {  
  24.         super.onCreate(savedInstanceState);  
  25.         setContentView(R.layout.main);  
  26.   
  27.         btnIncrease = (Button) findViewById(R.id.btnIncrease);  
  28.         btnDecrease = (Button) findViewById(R.id.btnDecrease);  
  29.         txtNumber = (TextView) findViewById(R.id.txtNumber);  
  30.   
  31.         btnIncrease.setOnClickListener(this);  
  32.         btnDecrease.setOnClickListener(this);  
  33.   
  34.         number = 3;  
  35.         txtNumber = (TextView) findViewById(R.id.txtNumber);  
  36.         txtNumber.setText(Integer.toString(number));  
  37.     }  
  38.   
  39.     public void onClick(View v) {  
  40.         enableRefresh = true;  
  41.         RotateAnimation rotateAnim = null;  
  42.         float cX = txtNumber.getWidth() / 2.0f;  
  43.         float cY = txtNumber.getHeight() / 2.0f;  
  44.         if (v == btnDecrease) {  
  45.             number--;  
  46.             rotateAnim = new RotateAnimation(cX, cY, RotateAnimation.ROTATE_DECREASE);  
  47.         } else if (v == btnIncrease) {  
  48.             number++;  
  49.             rotateAnim = new RotateAnimation(cX, cY, RotateAnimation.ROTATE_INCREASE);  
  50.         }  
  51.         if (rotateAnim != null) {  
  52.             rotateAnim.setInterpolatedTimeListener(this);  
  53.             rotateAnim.setFillAfter(true);  
  54.             txtNumber.startAnimation(rotateAnim);  
  55.         }  
  56.     }  
  57.   
  58.     @Override  
  59.     public void interpolatedTime(float interpolatedTime) {  
  60.         // 监听到翻转进度过半时,更新txtNumber显示内容。  
  61.         if (enableRefresh && interpolatedTime > 0.5f) {  
  62.             txtNumber.setText(Integer.toString(number));  
  63.             Log.d("ANDROID_LAB""setNumber:" + number);  
  64.             enableRefresh = false;  
  65.         }  
  66.     }  
  67. }  


RotateAnimation.java

[java] view plaincopy
  1. package lab.sodino.rotate;  
  2.   
  3. import android.graphics.Camera;  
  4. import android.graphics.Matrix;  
  5. import android.view.animation.Animation;  
  6. import android.view.animation.Transformation;  
  7.   
  8. /** 
  9.  * @author Sodino E-mail:sodinoopen@hotmail.com 
  10.  * @version Time:2012-6-27 上午07:32:00 
  11.  */  
  12. public class RotateAnimation extends Animation {  
  13.     /** 值为true时可明确查看动画的旋转方向。 */  
  14.     public static final boolean DEBUG = false;  
  15.     /** 沿Y轴正方向看,数值减1时动画逆时针旋转。 */  
  16.     public static final boolean ROTATE_DECREASE = true;  
  17.     /** 沿Y轴正方向看,数值减1时动画顺时针旋转。 */  
  18.     public static final boolean ROTATE_INCREASE = false;  
  19.     /** Z轴上最大深度。 */  
  20.     public static final float DEPTH_Z = 310.0f;  
  21.     /** 动画显示时长。 */  
  22.     public static final long DURATION = 800l;  
  23.     /** 图片翻转类型。 */  
  24.     private final boolean type;  
  25.     private final float centerX;  
  26.     private final float centerY;  
  27.     private Camera camera;  
  28.     /** 用于监听动画进度。当值过半时需更新txtNumber的内容。 */  
  29.     private InterpolatedTimeListener listener;  
  30.   
  31.     public RotateAnimation(float cX, float cY, boolean type) {  
  32.         centerX = cX;  
  33.         centerY = cY;  
  34.         this.type = type;  
  35.         setDuration(DURATION);  
  36.     }  
  37.   
  38.     public void initialize(int width, int height, int parentWidth, int parentHeight) {  
  39.         // 在构造函数之后、getTransformation()之前调用本方法。  
  40.         super.initialize(width, height, parentWidth, parentHeight);  
  41.         camera = new Camera();  
  42.     }  
  43.   
  44.     public void setInterpolatedTimeListener(InterpolatedTimeListener listener) {  
  45.         this.listener = listener;  
  46.     }  
  47.   
  48.     protected void applyTransformation(float interpolatedTime, Transformation transformation) {  
  49.         // interpolatedTime:动画进度值,范围为[0.0f,10.f]  
  50.         if (listener != null) {  
  51.             listener.interpolatedTime(interpolatedTime);  
  52.         }  
  53.         float from = 0.0f, to = 0.0f;  
  54.         if (type == ROTATE_DECREASE) {  
  55.             from = 0.0f;  
  56.             to = 180.0f;  
  57.         } else if (type == ROTATE_INCREASE) {  
  58.             from = 360.0f;  
  59.             to = 180.0f;  
  60.         }  
  61.         float degree = from + (to - from) * interpolatedTime;  
  62.         boolean overHalf = (interpolatedTime > 0.5f);  
  63.         if (overHalf) {  
  64.             // 翻转过半的情况下,为保证数字仍为可读的文字而非镜面效果的文字,需翻转180度。  
  65.             degree = degree - 180;  
  66.         }  
  67.         // float depth = 0.0f;  
  68.         float depth = (0.5f - Math.abs(interpolatedTime - 0.5f)) * DEPTH_Z;  
  69.         final Matrix matrix = transformation.getMatrix();  
  70.         camera.save();  
  71.         camera.translate(0.0f, 0.0f, depth);  
  72.         camera.rotateY(degree);  
  73.         camera.getMatrix(matrix);  
  74.         camera.restore();  
  75.         if (DEBUG) {  
  76.             if (overHalf) {  
  77.                 matrix.preTranslate(-centerX * 2, -centerY);  
  78.                 matrix.postTranslate(centerX * 2, centerY);  
  79.             }  
  80.         } else {  
  81.             //确保图片的翻转过程一直处于组件的中心点位置  
  82.             matrix.preTranslate(-centerX, -centerY);  
  83.             matrix.postTranslate(centerX, centerY);  
  84.         }  
  85.     }  
  86.   
  87.     /** 动画进度监听器。 */  
  88.     public static interface InterpolatedTimeListener {  
  89.         public void interpolatedTime(float interpolatedTime);  
  90.     }  
2015-04-08 16:25:32 yilip 阅读数 4945

     一般一个View只有一面,但是可以自定义一个View,实现像翻书那样的翻转效果。

    旋转View:

           

/**
 * 两种方式构造一个翻转卡片
 * 1:直接提供一个特定命名格式的View
 * 2:提供两个线性布局(正面和,反面)
 * Created by lip on 2015/4/8.
 */
public class FlipView extends LinearLayout implements View.OnClickListener,RotateAnimation.InterpolatedTimeListener
{
    private LinearLayout m_first_ll, m_second_ll;

    private boolean enableRefresh;
    private LinearLayout view;
    private View clickView;//当前的view
    private Context context;
    public FlipView(Context context)
    {
        super(context);
        this.context=context;
        //initViews();
    }
    public FlipView(Context context,AttributeSet attrs)
    {
        super(context,attrs);
        this.context=context;
        //initViews();
    }

    /**
     */
    public void initViews()
    {
        view=(LinearLayout)inflate(context,R.layout.flip_view,null);
        m_first_ll=(LinearLayout)view.findViewById(R.id.first_ll);
        m_second_ll=(LinearLayout)view.findViewById(R.id.second_ll);
        m_first_ll.setOnClickListener(this);
        m_second_ll.setOnClickListener(this);
        addView(view, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    }

    /**
     * @param ll1 正面
     * @param ll2  反面
     */
    public void addViews(LinearLayout ll1,LinearLayout ll2)
    {
        m_first_ll=ll1;
        m_second_ll=ll2;
        m_first_ll.setOnClickListener(this);
        m_second_ll.setOnClickListener(this);
        addView(m_first_ll, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
        addView(m_second_ll, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
    }

    /**
     * flag=0 翻到正面
     * flag=1 翻到反面
     * @param flag
     */
    public void show(int flag)
    {
        enableRefresh = true;
        RotateAnimation rotateAnim = null;
        float cX = this.getWidth() / 2.0f;
        float cY = this.getHeight() / 2.0f;
        if(flag==0)
        rotateAnim = new RotateAnimation(cX, cY,
                RotateAnimation.ROTATE_DECREASE);
        else if(flag==1)
            rotateAnim = new RotateAnimation(cX, cY,
                    RotateAnimation.ROTATE_INCREASE);
        if (rotateAnim != null) {
            rotateAnim.setInterpolatedTimeListener(this);
            rotateAnim.setFillAfter(true);
            this.startAnimation(rotateAnim);
        }
    }
    @Override
    public void onClick(View v) {
        Log.d("click:",v.toString());
        enableRefresh = true;
        clickView=v;
        RotateAnimation rotateAnim = null;
        float cX = this.getWidth() / 2.0f;
        float cY = this.getHeight() / 2.0f;
        if (m_first_ll==v) {
            rotateAnim = new RotateAnimation(cX, cY,
                    RotateAnimation.ROTATE_INCREASE);
        } else if (m_second_ll == v) {
            rotateAnim = new RotateAnimation(cX, cY,
                    RotateAnimation.ROTATE_DECREASE);
        }

        if (rotateAnim != null) {
            rotateAnim.setInterpolatedTimeListener(this);
            rotateAnim.setFillAfter(true);
            this.startAnimation(rotateAnim);
        }
    }

    @Override
    public void interpolatedTime(float interpolatedTime) {
        if (enableRefresh && interpolatedTime > 0.5f) {
            setHint();
            enableRefresh = false;
        }
    }

    public void setHint() {
        if (clickView == m_first_ll) {
            m_first_ll.setVisibility(View.GONE);
            m_second_ll.setVisibility(View.VISIBLE);
        } else if (clickView==m_second_ll) {
            m_second_ll.setVisibility(View.GONE);
            m_first_ll.setVisibility(View.VISIBLE);
        }

    }
}
 来看看使用方法:

      

public class FlipActivity extends Activity
{
    private FlipView flipView;
    LinearLayout firstLL,secondLL;
    LinearLayout root;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //setContentView(R.layout.activity_flip);
        initViews();
    }
    private void initViews()
    {
        root=(LinearLayout)LayoutInflater.from(this).inflate(R.layout.activity_flip,null);
        flipView=(FlipView)root.findViewById(R.id.flip_view);
        /*********第一种方式(要主动调用initViews)*************/
//        firstLL=(LinearLayout)LayoutInflater.from(this).inflate(R.layout.flip_view1,null);
//        secondLL=(LinearLayout)LayoutInflater.from(this).inflate(R.layout.flip_view2,null);
        /*********第二种方式*************/
        firstLL=(LinearLayout)root.findViewById(R.id.root_ll1);
        secondLL=(LinearLayout)root.findViewById(R.id.root_ll2);
        root.removeView(firstLL);
        root.removeView(secondLL);
        flipView.addViews(firstLL,secondLL);
        setContentView(root);
    }
}
  既然一个View 有两面,那当然需要主动去设置正面和反面的内容了。

   flipView.addViews(firstLL,secondLL);第一个参数就是正面的view,第二个参数是反面的view,这两个view都是线性布局。我提供了两种设置正反面的的方式,如果要是对于布局有一点了解,其实这是一样的
</pre><p>    旋转工具类(网上参考别人的):</p><p>          <pre name="code" class="java">public class RotateAnimation extends Animation {

	/** 值为true时可明确查看动画的旋转方向。 */
	public static final boolean DEBUG = false;
	/** 沿Y轴正方向看,数值减1时动画逆时针旋转。 */
	public static final boolean ROTATE_DECREASE = true;
	/** 沿Y轴正方向看,数值减1时动画顺时针旋转。 */
	public static final boolean ROTATE_INCREASE = false;
	/** Z轴上最大深度。 */
	public static final float DEPTH_Z = 310.0f;
	/** 动画显示时长。 */
	public static final long DURATION = 800l;
	/** 图片翻转类型。 */
	private final boolean type;
	private final float centerX;
	private final float centerY;
	private Camera camera;

	public RotateAnimation(float cX, float cY, boolean type) {
		centerX = cX;
		centerY = cY;
		this.type = type;
		// 设置动画时长
		setDuration(DURATION);
	}

	@Override
	public void initialize(int width, int height, int parentWidth,
			int parentHeight) {
		// 在构造函数之后、applyTransformation()之前调用本方法。
		super.initialize(width, height, parentWidth, parentHeight);
		camera = new Camera();
	}

	@Override
	protected void applyTransformation(float interpolatedTime,
			Transformation transformation) {
		// interpolatedTime:动画进度值,范围为0~1,0.5为正好翻转一半
		if (listener != null) {
			listener.interpolatedTime(interpolatedTime);
		}

		float from = 0.0f, to = 0.0f;
		if (type == ROTATE_DECREASE) {
			from = 0.0f;
			to = 180.0f;
		} else if (type == ROTATE_INCREASE) {
			from = 360.0f;
			to = 180.0f;
		}

		// 旋转的角度
		float degree = from + (to - from) * interpolatedTime;
		boolean overHalf = (interpolatedTime > 0.5f);
		if (overHalf) {
			// 翻转过半的情况下,为保证数字仍为可读的文字而非镜面效果的文字,需翻转180度。
			degree = degree - 180;
		}

		// 旋转深度
		float depth = (0.5f - Math.abs(interpolatedTime - 0.5f)) * DEPTH_Z;

		final Matrix matrix = transformation.getMatrix();
		camera.save();
		// 深度——》相当于与屏幕的距离
		camera.translate(0.0f, 0.0f, depth);
		// 以x轴旋转
		// camera.rotateX(degree);
		// 以y轴旋转
		camera.rotateY(degree);
		camera.getMatrix(matrix);
		camera.restore();

		if (DEBUG) {
			if (overHalf) {
				matrix.preTranslate(-centerX * 2, -centerY);
				matrix.postTranslate(centerX * 2, centerY);
			}
		} else {
			// 确保图片的翻转过程一直处于组件的中心点位置
			/*
			 * preTranslate是指在setScale前平移,postTranslate是指在setScale后平移,它们参数是平移的距离,
			 * 而不是平移目的地的坐标!
			 * 由于缩放是以(0,0)为中心的,所以为了把界面的中心与(0,0)对齐,就要preTranslate(-centerX,
			 * -centerY),setScale完成后, 调用postTranslate(centerX,
			 * centerY),再把图片移回来,这样看到的动画效果就是activity的界面图片从中心不停的缩放了
			 * 注:centerX和centerY是界面中心的坐标
			 */
			matrix.preTranslate(-centerX, -centerY);
			matrix.postTranslate(centerX, centerY);
		}
	}

	/** 用于监听动画进度。当值过半时需更新的内容。 */
	private InterpolatedTimeListener listener;

	public void setInterpolatedTimeListener(InterpolatedTimeListener listener) {
		this.listener = listener;
	}

	/** 动画进度监听器。 */
	public static interface InterpolatedTimeListener {
		public void interpolatedTime(float interpolatedTime);
	}

}
    xml布局:

     

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="match_parent">
    <cn.xindrace.viewflip.FlipView
        android:id="@+id/flip_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>
    <LinearLayout
        android:id="@+id/root_ll1"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="It is the first side"/>

    </LinearLayout>
    <LinearLayout
        android:id="@+id/root_ll2"
        android:orientation="vertical"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:text="It is the first side"/>

    </LinearLayout>

</LinearLayout>

    




2017-12-28 09:38:43 CrackgmKey 阅读数 363

最近项目右侧项目需要加动画,借用了一个博客地址的

很好的一个动画,希望能帮助到大家

http://blog.csdn.net/wood12943907/article/details/52190135