zoukankan      html  css  js  c++  java
  • android 水纹上涨与水滴滴下效果

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

     
     
  • 相关阅读:
    window下eclipse4.5+hadoop2.6.1开发环境配置
    sqoop1.4.6从mysql导入hdfshivehbase实例
    sqoop1.9.7安装和使用
    sqoop1.4.6导出oracle实例
    sqoop1.4.6配置安装
    java 操作hbase1.2
    hbase-1.2.5完全分布式部署
    hadoop2.6环境中部署hive1.2.2的错误
    hive 创建表和导入数据实例
    hive1.2.2部署
  • 原文地址:https://www.cnblogs.com/android-blogs/p/5177644.html
Copyright © 2011-2022 走看看