android 水纹上涨与水滴滴下效果

这两天项目比较紧,本来打算完成以后再写博客的,今天终于实现了一个炫的功能,怀着激动的心情,趁热打铁,把项目经验记录一下,效果图如下: 
android 水纹上涨与水滴滴下效果_第1张图片 
对功能的几点说明: 
1.圆形边框旋转 
2.水纹上涨 
3.水滴滴下 
4.方向始终朝向重力 
先分析一下思路,首先旋转比较好实现,只需要旋转动画就可以了,第二个水纹效果,参考了一篇博客,http://www.jianshu.com/p/e711e22e053e 
在源码基础上进行了修改。第三个水滴滴下效果,参考了这个源码: https://github.com/recruit-lifestyle/WaveSwipeRefreshLayout 
并且根据功能在源码基础上进行了修改,第四个方向始终朝向重力方向,需要判断重力方向,然后根据角度旋转图片,感谢这篇博客,里边角度的换算非常有用, http://www.cnblogs.com/bpasser/archive/2011/10/17/2214517.html 
现在就一步一步实现这个功能吧

布局文件

现在先把这块功能的布局文件贴上,所有操作都在这个布局上进行。


    <LinearLayout
        android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:gravity="center" android:orientation="vertical"> <FrameLayout android:id="@+id/id_framelayout" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:background="@mipmap/wave_default"> <ImageView android:id="@+id/id_imageRota" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:src="@mipmap/wave_1" /> <jp.co.recruit_lifestyle.android.widget.WaveSwipeRefreshLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/main_swipe" android:layout_gravity="center" > <View android:layout_width="1dp" android:layout_height="1dp" /> </jp.co.recruit_lifestyle.android.widget.WaveSwipeRefreshLayout> <com.gelitenight.waveview.library.WaveView android:id="@+id/wave" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" /> <TextView android:id="@+id/id_textViewProgress" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:textSize="40sp" android:textColor="#5aa828" android:textStyle="bold"/> </FrameLayout> </LinearLayout>

先解释一下布局,两张图片:wave_defaultandroid 水纹上涨与水滴滴下效果_第2张图片, 
wave_1 
android 水纹上涨与水滴滴下效果_第3张图片 
首先使用FrameLayout布局,将两个图片重叠,对wave_1进行旋转操作,实现动画。WaveSwipeRefreshLayout控件是水滴效果,因为不允许布局内为空,所以设置一个view,WaveView则是水滴效果,id_textViewProgress是水滴上写的进度数字,说明一下,这里都写成自适应的,wrap_content,具体宽高则在代码中进行控制。

旋转图片的实现

这个比较简单,只需要给view进行旋转动画的操作就可以了,贴一下这部分功能的代码

 final RotateAnimation ra = new RotateAnimation(0, 359, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); ra.setDuration(1000); ra.setRepeatCount(-1); //匀速 LinearInterpolator lin = new LinearInterpolator(); ra.setInterpolator(lin); imageViewRota.startAnimation(ra);

我这里设置了匀速旋转

水波效果的实现

这个需要导入第三方库,导入方法我就不说了,然后在源代码基础上进行修改,具体的效果是这样的,android 水纹上涨与水滴滴下效果_第4张图片颜色和透明度之类的,在源代码中进行修改,修改的部分比较多,我把修改后的源码贴一下

public class WaveView extends View { /** * +------------------------+ * |<--wave length-> |______ * | /\ | /\ | | * | / \ | / \ | amplitude * | / \ | / \ | | * |/ \ |/ \|__|____ * | \ / | | * | \ / | | * | \ / | | * | \/ | water level * | | | * | | | * +------------------------+__|____ */ private static final float DEFAULT_AMPLITUDE_RATIO = 0.05f; private static final float DEFAULT_WATER_LEVEL_RATIO = 0.5f; private static final float DEFAULT_WAVE_LENGTH_RATIO = 1.0f; private static final float DEFAULT_WAVE_SHIFT_RATIO = 0.0f; public static final int DEFAULT_BEHIND_WAVE_COLOR = Color.parseColor("#addef8"); public static final int DEFAULT_FRONT_WAVE_COLOR = Color.parseColor("#addef8"); public static final ShapeType DEFAULT_WAVE_SHAPE = ShapeType.CIRCLE; public enum ShapeType { CIRCLE, SQUARE } // if true, the shader will display the wave private boolean mShowWave; // shader containing repeated waves private BitmapShader mWaveShader; // shader matrix private Matrix mShaderMatrix; // paint to draw wave private Paint mViewPaint; // paint to draw border private Paint mBorderPaint; private float mDefaultAmplitude; private float mDefaultWaterLevel; private float mDefaultWaveLength; private double mDefaultAngularFrequency; private float mAmplitudeRatio = DEFAULT_AMPLITUDE_RATIO; private float mWaveLengthRatio = DEFAULT_WAVE_LENGTH_RATIO; private float mWaterLevelRatio = DEFAULT_WATER_LEVEL_RATIO; private float mWaveShiftRatio = DEFAULT_WAVE_SHIFT_RATIO; private int mBehindWaveColor = DEFAULT_BEHIND_WAVE_COLOR; private int mFrontWaveColor = DEFAULT_FRONT_WAVE_COLOR; private ShapeType mShapeType = DEFAULT_WAVE_SHAPE; public WaveView(Context context) { super(context); init(); } public WaveView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public WaveView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { mShaderMatrix = new Matrix(); mViewPaint = new Paint(); mViewPaint.setAntiAlias(true); } public float getWaveShiftRatio() { return mWaveShiftRatio; } /** * Shift the wave horizontally according to <code>waveShiftRatio</code>. * * @param waveShiftRatio Should be 0 ~ 1. Default to be 0. * <br/>Result of waveShiftRatio multiples width of WaveView is the length to shift. */ public void setWaveShiftRatio(float waveShiftRatio) { if (mWaveShiftRatio != waveShiftRatio) { mWaveShiftRatio = waveShiftRatio; invalidate(); } } public float getWaterLevelRatio() { return mWaterLevelRatio; } /** * Set water level according to <code>waterLevelRatio</code>. * * @param waterLevelRatio Should be 0 ~ 1. Default to be 0.5. * <br/>Ratio of water level to WaveView height. */ public void setWaterLevelRatio(float waterLevelRatio){ if (mWaterLevelRatio != waterLevelRatio) { mWaterLevelRatio = waterLevelRatio; invalidate(); } } public float getAmplitudeRatio() { return mAmplitudeRatio; } /** * Set vertical size of wave according to <code>amplitudeRatio</code> * * @param amplitudeRatio Default to be 0.05. Result of amplitudeRatio + waterLevelRatio should be less than 1. * <br/>Ratio of amplitude to height of WaveView. */ public void setAmplitudeRatio(float amplitudeRatio) { if (mAmplitudeRatio != amplitudeRatio) { mAmplitudeRatio = amplitudeRatio; invalidate(); } } public float getWaveLengthRatio() { return mWaveLengthRatio; } /** * Set horizontal size of wave according to <code>waveLengthRatio</code> * * @param waveLengthRatio Default to be 1. * <br/>Ratio of wave length to width of WaveView. */ public void setWaveLengthRatio(float waveLengthRatio) { mWaveLengthRatio = waveLengthRatio; } public boolean isShowWave() { return mShowWave; } public void setShowWave(boolean showWave) { mShowWave = showWave; } public void setBorder(int width, int color) { if (mBorderPaint == null) { mBorderPaint = new Paint(); mBorderPaint.setAntiAlias(true); mBorderPaint.setStyle(Style.STROKE); } mBorderPaint.setColor(color); mBorderPaint.setStrokeWidth(width); invalidate(); } public void setWaveColor(int behindWaveColor, int frontWaveColor) { mBehindWaveColor = behindWaveColor; mFrontWaveColor = frontWaveColor; // need to recreate shader when color changed mWaveShader = null; createShader(); invalidate(); } public void setShapeType(ShapeType shapeType) { mShapeType = shapeType; invalidate(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); createShader(); } /** * Create the shader with default waves which repeat horizontally, and clamp vertically */ private void createShader() { mDefaultAngularFrequency = 2.0f * Math.PI / DEFAULT_WAVE_LENGTH_RATIO / getWidth(); mDefaultAmplitude = getHeight() * DEFAULT_AMPLITUDE_RATIO; mDefaultWaterLevel = getHeight() * DEFAULT_WATER_LEVEL_RATIO; mDefaultWaveLength = getWidth(); Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888); Canvas canvas = new Canvas(bitmap); Paint wavePaint = new Paint(); wavePaint.setStrokeWidth(2); wavePaint.setAntiAlias(true); wavePaint.setAlpha(178); // Draw default waves into the bitmap // y=Asin(ωx+φ)+h final int endX = getWidth() + 1; final int endY = getHeight() + 1; float[] waveY = new float[endX]; wavePaint.setColor(mBehindWaveColor); wavePaint.setAlpha(127); for (int beginX = 0; beginX < endX; beginX++) { double wx = beginX * mDefaultAngularFrequency; float beginY = (float) (mDefaultWaterLevel + mDefaultAmplitude * Math.sin(wx)); canvas.drawLine(beginX, beginY, beginX, endY, wavePaint); waveY[beginX] = beginY; } wavePaint.setColor(mFrontWaveColor); final int wave2Shift = (int) (mDefaultWaveLength / 4); for (int beginX = 0; beginX < endX; beginX++) { canvas.drawLine(beginX, waveY[(beginX + wave2Shift) % endX], beginX, endY, wavePaint); } // use the bitamp to create the shader mWaveShader = new BitmapShader(bitmap, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP); mViewPaint.setShader(mWaveShader); } @Override protected void onDraw(Canvas canvas) { // modify paint shader according to mShowWave state if (mShowWave && mWaveShader != null) { // first call after mShowWave, assign it to our paint if (mViewPaint.getShader() == null) { mViewPaint.setShader(mWaveShader); } // sacle shader according to mWaveLengthRatio and mAmplitudeRatio // this decides the size(mWaveLengthRatio for width, mAmplitudeRatio for height) of waves mShaderMatrix.setScale( mWaveLengthRatio / DEFAULT_WAVE_LENGTH_RATIO, mAmplitudeRatio / DEFAULT_AMPLITUDE_RATIO, 0, mDefaultWaterLevel); // translate shader according to mWaveShiftRatio and mWaterLevelRatio // this decides the start position(mWaveShiftRatio for x, mWaterLevelRatio for y) of waves mShaderMatrix.postTranslate( mWaveShiftRatio * getWidth(), (DEFAULT_WATER_LEVEL_RATIO - mWaterLevelRatio) * getHeight()); // assign matrix to invalidate the shader mWaveShader.setLocalMatrix(mShaderMatrix); float borderWidth = mBorderPaint == null ? 0f : mBorderPaint.getStrokeWidth(); switch (mShapeType) { case CIRCLE: if (borderWidth > 0) { canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, (getWidth() - borderWidth) / 2f - 1f, mBorderPaint); } float radius = getWidth() / 2f - borderWidth; canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, radius, mViewPaint); break; case SQUARE: if (borderWidth > 0) { canvas.drawRect( borderWidth / 2f, borderWidth / 2f, getWidth() - borderWidth / 2f - 0.5f, getHeight() - borderWidth / 2f - 0.5f, mBorderPaint); } canvas.drawRect(borderWidth, borderWidth, getWidth() - borderWidth, getHeight() - borderWidth, mViewPaint); break; } } else { mViewPaint.setShader(null); } } }

还有这个waterHelper类,对不需要的功能进行了注释

public class WaveHelper { private WaveView mWaveView; private AnimatorSet mAnimatorSet; List<Animator> animators = new ArrayList<>(); public WaveHelper(WaveView waveView) { mWaveView = waveView; initAnimation(); } public void start() { mWaveView.setShowWave(true); if (mAnimatorSet != null) { mAnimatorSet.start(); } } private void initAnimation() { // horizontal animation. // wave waves infinitely. ObjectAnimator waveShiftAnim = ObjectAnimator.ofFloat( mWaveView, "waveShiftRatio", 0f, 1f); waveShiftAnim.setRepeatCount(ValueAnimator.INFINITE); waveShiftAnim.setDuration(1000); waveShiftAnim.setInterpolator(new LinearInterpolator()); animators.add(waveShiftAnim); /* // vertical animation. // 水位从0到设置的水位高度 ObjectAnimator waterLevelAnim = ObjectAnimator.ofFloat( mWaveView, "waterLevelRatio", 0f, waterLevel); waterLevelAnim.setDuration(10000); waterLevelAnim.setInterpolator(new DecelerateInterpolator()); animators.add(waterLevelAnim);*/ // amplitude animation. // wave grows big then grows small, repeatedly /* ObjectAnimator amplitudeAnim = ObjectAnimator.ofFloat( mWaveView, "amplitudeRatio", 0.0001f, 0.05f); amplitudeAnim.setRepeatCount(ValueAnimator.INFINITE); amplitudeAnim.setRepeatMode(ValueAnimator.REVERSE); amplitudeAnim.setDuration(5000); amplitudeAnim.setInterpolator(new LinearInterpolator()); animators.add(amplitudeAnim);*/ mAnimatorSet = new AnimatorSet(); mAnimatorSet.playTogether(animators); } public void cancel() { if (mAnimatorSet != null) { // mAnimatorSet.cancel(); mAnimatorSet.end(); } } }

在我代码中对这个类的引用

  //手机屏幕密度 private float density; private int chargingProgress = 0; private float currentDegree = 0f; //重力感应,让水滴效果不随着屏幕旋转变化 private FrameLayout frameLayoutWater; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0x123) { if (chargingProgress <= 100) { textViewProgress.setText(chargingProgress + "%"); float level = chargingProgress / 100.0f; waveView.setWaterLevelRatio(level); chargingProgress++; } } } }; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { density = getActivity().getResources().getDisplayMetrics().density; //水纹效果 waveView = (WaveView) view.findViewById(R.id.wave); Bitmap bitmapWave = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wave_1); //代码设置控件宽高,不超过默认图片 ViewGroup.LayoutParams lp; lp = waveView.getLayoutParams(); lp.width = bitmapWave.getWidth() - (int) (30 * density); lp.height = bitmapWave.getHeight() - (int) (30 * density); waveView.setLayoutParams(lp); waveView.setBorder(mBorderWidth, mBorderColor); waveView.setWaterLevelRatio(0); mWaveHelper = new WaveHelper(waveView); Button button = (Button) view.findViewById(R.id.id_buttonWave); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mWaveHelper.start(); final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(0x123); if (chargingProgress >= 100) { timer.cancel(); } } }, 0, 1000); } }); } @Override public void onPause() { super.onPause(); mWaveHelper.cancel(); }

这个需要解释一下,我没有在布局中将控件宽高写死,怕影响到自适应,想了个办法,就是以背景图片的宽高在代码中进行设置控件的宽高,需要用到手机屏幕的密度density,然后定义一个handler进行更新演示,更新水波高度以及修改水波进度数字,在button按钮中启动水波效果。

水滴滴下效果

这个我也是借助了第三方的类库,我只是取了一个方法,onDropPhase(),并且取消了源码中的阴影效果,因为不美观,然后将水滴滴下时显示的水平线也取消了。源码中修改的代码我就不贴了,第一是因为太多了,第二是我也忘记修改了什么了,在文章最后我把修改过的源码传一下吧,有兴趣的可以自己修改着看看效果,直接上我实现水滴效果的代码吧

 private Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0x123) { if (chargingProgress <= 100) { mWaveSwipeRefreshLayout.onDropPhase(); textViewProgress.setText(chargingProgress + "%"); float level = chargingProgress / 100.0f; waveView.setWaterLevelRatio(level); chargingProgress++; } } } }; //水滴 mWaveSwipeRefreshLayout = (WaveSwipeRefreshLayout) view.findViewById(R.id.main_swipe); mWaveSwipeRefreshLayout.setColorSchemeColors(Color.TRANSPARENT, Color.TRANSPARENT); mWaveSwipeRefreshLayout.setWaveColor(Color.parseColor("#addef8")); //设置水滴效果控件宽高 ViewGroup.LayoutParams lp2; lp2 = mWaveSwipeRefreshLayout.getLayoutParams(); lp2.width = bitmapWave.getWidth() - (int) (30 * density); lp2.height = bitmapWave.getHeight() - (int) (30 * density); mWaveSwipeRefreshLayout.setMaxDropHeight(mWaveSwipeRefreshLayout.getHeight()); mWaveSwipeRefreshLayout.setLayoutParams(lp2);

实现始终朝向重力方向的功能

这个功能需要用到传感器,唉,也是各种纠结,参考了其他几篇文章,主要是判断重力角度,要继承 implements SensorEventListener ,然后使用动画进行旋转,直接上代码吧

  // 传感器管理器 SensorManager sm = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); // 注册传感器(Sensor.TYPE_ORIENTATION(方向传感器);SENSOR_DELAY_FASTEST(0毫秒延迟); // SENSOR_DELAY_GAME(20,000毫秒延迟)、SENSOR_DELAY_UI(60,000毫秒延迟)) sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST); @Override public void onSensorChanged(SensorEvent event) { if (Sensor.TYPE_ACCELEROMETER != event.sensor.getType()) { return; } float[] values = event.values; float ax = values[0]; float ay = values[1]; double g = Math.sqrt(ax * ax + ay * ay); double cos = ay / g; if (cos > 1) { cos = 1; } else if (cos < -1) { cos = -1; } double rad = Math.acos(cos); if (ax < 0) { rad = 2 * Math.PI - rad; } int uiRot = getActivity().getWindowManager().getDefaultDisplay().getRotation(); double uiRad = Math.PI / 2 * uiRot; rad -= uiRad; int degrees = (int) (180 * rad / Math.PI); //如果度数变化不超过5,不变化,防止频繁晃动 if(Math.abs(currentDegree-degrees)>5){ RotateAnimation ra = new RotateAnimation(currentDegree, degrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); ra.setFillAfter(true); frameLayoutWater.startAnimation(ra); currentDegree = degrees; }

这个角度是个难点,我就是因为这个纠结了半天,当时是忘记了这句换算int degrees = (int) (180 * rad / Math.PI); 
贴上完整代码

public class ChargeFragment extends Fragment implements SensorEventListener { private TextView textViewProgress;//充电进度 private int mBorderColor = Color.parseColor("#addef8"); private int mBorderWidth = 2; private WaveHelper mWaveHelper; private WaveView waveView; private WaveSwipeRefreshLayout mWaveSwipeRefreshLayout; //手机屏幕密度 private float density; //测试动画 private int chargingProgress = 0; private float currentDegree = 0f; //重力感应,让水滴效果不随着屏幕旋转变化 private FrameLayout frameLayoutWater; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { if (msg.what == 0x123) { if (chargingProgress <= 100) { mWaveSwipeRefreshLayout.onDropPhase(); textViewProgress.setText(chargingProgress + "%"); float level = chargingProgress / 100.0f; waveView.setWaterLevelRatio(level); chargingProgress++; } } } }; public ChargeFragment() { // Required empty public constructor } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_charge, container, false); density = getActivity().getResources().getDisplayMetrics().density; imageViewRota = (ImageView) view.findViewById(R.id.id_imageRota); textViewProgress = (TextView) view.findViewById(R.id.id_textViewProgress); Button button = (Button) view.findViewById(R.id.id_buttonWave); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mWaveHelper.start(); final Timer timer = new Timer(); timer.schedule(new TimerTask() { @Override public void run() { handler.sendEmptyMessage(0x123); if (chargingProgress >= 100) { timer.cancel(); } } }, 0, 1000); } }); final RotateAnimation ra = new RotateAnimation(0, 359, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); ra.setDuration(1000); ra.setRepeatCount(-1); //匀速 LinearInterpolator lin = new LinearInterpolator(); ra.setInterpolator(lin); imageViewRota.startAnimation(ra); //水滴 mWaveSwipeRefreshLayout = (WaveSwipeRefreshLayout) view.findViewById(R.id.main_swipe); mWaveSwipeRefreshLayout.setColorSchemeColors(Color.TRANSPARENT, Color.TRANSPARENT); mWaveSwipeRefreshLayout.setWaveColor(Color.parseColor("#addef8")); //水纹效果 waveView = (WaveView) view.findViewById(R.id.wave); Bitmap bitmapWave = BitmapFactory.decodeResource(getActivity().getResources(), R.mipmap.wave_1); //代码设置控件宽高,不超过默认图片 ViewGroup.LayoutParams lp; lp = waveView.getLayoutParams(); lp.width = bitmapWave.getWidth() - (int) (30 * density); lp.height = bitmapWave.getHeight() - (int) (30 * density); waveView.setLayoutParams(lp); //设置水滴效果控件宽高 ViewGroup.LayoutParams lp2; lp2 = mWaveSwipeRefreshLayout.getLayoutParams(); lp2.width = bitmapWave.getWidth() - (int) (30 * density); lp2.height = bitmapWave.getHeight() - (int) (30 * density); mWaveSwipeRefreshLayout.setMaxDropHeight(mWaveSwipeRefreshLayout.getHeight()); mWaveSwipeRefreshLayout.setLayoutParams(lp2); waveView.setBorder(mBorderWidth, mBorderColor); waveView.setWaterLevelRatio(0); mWaveHelper = new WaveHelper(waveView); frameLayoutWater = (FrameLayout) view.findViewById(R.id.id_framelayout); /* final RotateAnimation ra2 = new RotateAnimation(0, 360, RotateAnimation.RELATIVE_TO_SELF, 0.5f, RotateAnimation.RELATIVE_TO_SELF, 0.5f); ra2.setDuration(5000); ra2.setRepeatCount(-1); frameLayout.startAnimation(ra2);*/ // 传感器管理器 SensorManager sm = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); // 注册传感器(Sensor.TYPE_ORIENTATION(方向传感器);SENSOR_DELAY_FASTEST(0毫秒延迟); // SENSOR_DELAY_GAME(20,000毫秒延迟)、SENSOR_DELAY_UI(60,000毫秒延迟)) sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST); return view; } @Override public void onAttach(Context context) { super.onAttach(context); } @Override public void onDetach() { super.onDetach(); } @Override public void onDestroy() { super.onDestroy(); } @Override public void onPause() { super.onPause(); mWaveHelper.cancel(); } @Override public void onResume() { super.onResume(); } @Override public void onSensorChanged(SensorEvent event) { if (Sensor.TYPE_ACCELEROMETER != event.sensor.getType()) { return; } float[] values = event.values; float ax = values[0]; float ay = values[1]; double g = Math.sqrt(ax * ax + ay * ay); double cos = ay / g; if (cos > 1) { cos = 1; } else if (cos < -1) { cos = -1; } double rad = Math.acos(cos); if (ax < 0) { rad = 2 * Math.PI - rad; } int uiRot = getActivity().getWindowManager().getDefaultDisplay().getRotation(); double uiRad = Math.PI / 2 * uiRot; rad -= uiRad; int degrees = (int) (180 * rad / Math.PI); //如果度数变化不超过5,不变化,防止频繁晃动 if(Math.abs(currentDegree-degrees)>5){ RotateAnimation ra = new RotateAnimation(currentDegree, degrees, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); ra.setFillAfter(true); frameLayoutWater.startAnimation(ra); currentDegree = degrees; } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }

下边贴上修改过的资源地址 
http://download.csdn.net/detail/jifashihan/9384182 
http://download.csdn.net/detail/jifashihan/9384242

原始资源地址 
https://github.com/gelitenight/WaveView 
https://github.com/recruit-lifestyle/WaveSwipeRefreshLayout

 
 

你可能感兴趣的:(android 水纹上涨与水滴滴下效果)