这两天项目比较紧,本来打算完成以后再写博客的,今天终于实现了一个炫的功能,怀着激动的心情,趁热打铁,把项目经验记录一下,效果图如下: 
 
对功能的几点说明: 
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_default, 
wave_1 
 
首先使用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);

我这里设置了匀速旋转

水波效果的实现

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

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 水纹上涨与水滴滴下效果的更多相关文章

  1. Android -- 常见控件的小效果

    1,EditText控件 ① 修改光标颜色 自定义drawable 创建cursor.xml文件 <?xml version="1.0" encoding="utf ...

  2. 制作Android Demo GIF:程序演示效果GIF图录制

    [转] 制作Android Demo GIF:程序演示效果GIF图录制   在平时写博客或者分享自己写的程序效果的时候经常需要做成GIF图,以下就是介绍几种常用的GIF录制方法: 一.录制工具 1.( ...

  3. IOS7上呈现IOS6的水滴刷新效果

    IOS7上呈现IOS6的水滴刷新效果    到了IOS7 发现自带的刷新 不再是 IOS6自带的水滴效果了 你是否怀念那IOS6的效果呢? 哈哈,于是收集各方资料,整理编写一个属于自己的水滴刷新效果 ...

  4. Android UI - 实现广告Banner旋转木马效果

    Android UI - 实现广告Banner旋转木马效果 前言 本篇博客要分享的一个效果是实现广告Banner轮播效果,这个效果也比較常见,一些视频类应用就常常有,就拿360影视大全来举例吧: 用红 ...

  5. Android状态栏透明(沉浸式效果)

    Android状态栏透明(沉浸式效果) 默认效果 沉浸式效果 方式一 源码 下载地址(Android Studio工程):http://download.csdn.net/detail/q487880 ...

  6. Android MaterialDesign之水波点击效果的几种实现方法

    什么是水波点击的效果? 下面是几种不同的实现方法的效果图以及实现方法   Video_2016-08-31_003846 如何实现? 方法一 使用官方提供的RippleDrawable类 优点:使用方 ...

  7. Android利用温度传感器实现带动画效果的电子温度计

    概述 Android利用温度传感器实现带动画效果的电子温度计. 详细 代码下载:http://www.demodashi.com/demo/10631.html 一.准备工作 需要准备一部带有温度传感 ...

  8. 我的Android进阶之旅------>Android利用温度传感器实现带动画效果的电子温度计

    要想实现带动画效果的电子温度计,需要以下几个知识点: 1.温度传感器相关知识. 2.ScaleAnimation动画相关知识,来进行水印刻度的缩放效果. 3.android:layout_weight ...

  9. 【转】Android实现伸缩弹力分布菜单效果

    本文介绍下在Android中实现伸缩弹力分布菜单效果.关于这种菜单效果在IPhone中比较常见,效果比较酷.那么在Android中实现只是一种简单的模仿. 这两天无意间看到一园友的博文实现Path2. ...

随机推荐

  1. python和C语言的差别

    之前在公司一直做的是C语言的开发,然后做的都是业务方面的东西,做的是sdk,因为最近在找工作,然后今天面试的时候被问到C语言和Python的区别,自己只是简单的说了C是静态语言,在变量在使用前进行声明 ...

  2. python类的继承和多态

    现在属于是老年人的脑子,东西写着写着就忘了,东西记着记着就不知道了.之前学C++的时候就把类.对象这块弄得乱七八糟,现在是因为很想玩python,所以就看看python的类和对象. 就像说的,类有三个 ...

  3. c#元组举例

    元组的概要: 数组合并了相同类型的对象,而元组合并了不同类型的对象.元组起源于函数编程语言(如F#) ,在 这些语言中频繁使用元组.在N盯4中,元组可通过.NET Fmmework用于所有的NET语言 ...

  4. csu 1598(KMP)

    1598: 最长公共前缀 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 109  Solved: 92[Submit][Status][Web Boar ...

  5. Pandas DataFrame构造简析

    参考书籍:<利用Python进行数据分析> DataFrame简介: DataFrame是一个表格型的数据结构,它含有一组有序的列,每列可以是不同的值类型(数值.字符串.布尔值等).Dat ...

  6. 洛谷P1554 梦中的统计 题解

    题目传送门 这道题暴力又让我过了...数据真的很水(luogu) 暴力枚举n~m的每个数,再统计一次,交付评测...AC #include<bits/stdc++.h> using nam ...

  7. Web APi入门之Self-Host(二)

    这篇来讲讲WebApi的自托管,WebApi可以托管到控制台/winform/服务上,并不是一定要依赖IIS才行. 1.首先新建控制台项目,在通过Nuget搜索Microsoft.AspNet.Web ...

  8. JavaScript 中的原型(总则)

    1. 一切函数都是对象 2. 一切对象都是由函数创建的,所有函数都是由Function创建的,每个函数都是一个Function对象. 3. 对象.__proto__ === 函数.prototype ...

  9. HDU - 4777 离线树状数组

    离线树状数组搞一搞. #include<bits/stdc++.h> #define LL long long #define fi first #define se second #de ...

  10. JAVA编程思想读书笔记(五)--多线程

    接上篇JAVA编程思想读书笔记(四)--对象的克隆 No1: daemon Thread(守护线程) 参考http://blog.csdn.net/pony_maggie/article/detail ...