Home PC Games Linux Windows Database Network Programming Server Mobile  
           
  Home \ Programming \ Android realize RippleEffect water     - Ubuntu set Swap Space Tutorial (Linux)

- Source code to compile and install MySQL 5.7.9 (Database)

- Linux Shell Understanding and Learning (Linux)

- Install Firefox 32 official version of the Linux system (Linux)

- Linux add a new hard disk (Linux)

- Ubuntu 14.10 Install Ubuntu Touch Music App 2.0 (Linux)

- How to install the latest version of the Eclipse in Ubuntu 14.04 (Linux)

- Linux user groups, file permissions Detailed (Linux)

- Raspberry Pi 2 to install the latest version of the FPC and Lazarus 1.5 (Linux)

- NIC configuration parameters under Linux (Linux)

- Caffe + Ubuntu 14.04 64bit + CUDA 6.5 configuration instructions (Linux)

- Log4j configuration file Explanation (Linux)

- Alien Magic: RPM and DEB Mutual Convert (Linux)

- Manually generate AWR reports (Database)

- Linux support exFAT and NTFS (Linux)

- Easy to install Ubuntu 15.04 and Ubuntu 15.04 GNOME on Wayland trial (Linux)

- SQLite3 simple operation (Database)

- Oracle multi-user concurrency and transaction processing (Database)

- TL-WR703N to install OpenWrt process notes (Linux)

- Security: set limits on password (Linux)

 
         
  Android realize RippleEffect water
     
  Add Date : 2018-11-21      
         
         
         
  Recently seen 360, UC, Netease news client application with water ripple effect, in privately study a little, with reference to the GIT large share of God, and he is followed made a ripple Android realize RippleEffect example, look at the following effect:

1.RippleEffect core implementation class

package com.example.RippleEffect;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Handler;
import android.support.annotation.ColorRes;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.RelativeLayout;
 
 
/ **
 * RippleView custom layout
 *
 * Custom Layout that allows to use Ripple UI pattern above API 21
 * /
public class RippleView extends RelativeLayout {
 
    private int WIDTH;
    private int HEIGHT;
    private int frameRate = 10;
    private int rippleDuration = 400;
    private int rippleAlpha = 90;
    private Handler canvasHandler;
    private float radiusMax = 0;
    private boolean animationRunning = false;
    private int timer = 0;
    private int timerEmpty = 0;
    private int durationEmpty = -1;
    private float x = -1;
    private float y = -1;
    private int zoomDuration;
    private float zoomScale;
    private ScaleAnimation scaleAnimation;
    private Boolean hasToZoom;
    private Boolean isCentered;
    private Integer rippleType;
    private Paint paint;
    private Bitmap originBitmap;
    private int rippleColor;
    private int ripplePadding;
    private GestureDetector gestureDetector;
    private final Runnable runnable = new Runnable () {
        @Override
        public void run () {
            invalidate ();
        }
    };
 
    private OnRippleCompleteListener onCompletionListener;
 
    public RippleView (Context context) {
        super (context);
    }
 
    public RippleView (Context context, AttributeSet attrs) {
        super (context, attrs);
        init (context, attrs);
    }
 
    public RippleView (Context context, AttributeSet attrs, int defStyle) {
        super (context, attrs, defStyle);
        init (context, attrs);
    }
 
    / **
    * Method that initializes all fields and sets listeners
    *
    * @param Context Context used to create this view
    * @param Attrs Attribute used to initialize fields
    * /
    private void init (final Context context, final AttributeSet attrs) {
        if (isInEditMode ())
            return;
 
        final TypedArray typedArray = context.obtainStyledAttributes (attrs, R.styleable.RippleView);
        rippleColor = typedArray.getColor (R.styleable.RippleView_rv_color, getResources () getColor (R.color.rippelColor).);
        rippleType = typedArray.getInt (R.styleable.RippleView_rv_type, 0);
        hasToZoom = typedArray.getBoolean (R.styleable.RippleView_rv_zoom, false);
        isCentered = typedArray.getBoolean (R.styleable.RippleView_rv_centered, false);
        rippleDuration = typedArray.getInteger (R.styleable.RippleView_rv_rippleDuration, rippleDuration);
        frameRate = typedArray.getInteger (R.styleable.RippleView_rv_framerate, frameRate);
        rippleAlpha = typedArray.getInteger (R.styleable.RippleView_rv_alpha, rippleAlpha);
        ripplePadding = typedArray.getDimensionPixelSize (R.styleable.RippleView_rv_ripplePadding, 0);
        canvasHandler = new Handler ();
        zoomScale = typedArray.getFloat (R.styleable.RippleView_rv_zoomScale, 1.03f);
        zoomDuration = typedArray.getInt (R.styleable.RippleView_rv_zoomDuration, 200);
        typedArray.recycle ();
        paint = new Paint ();
        paint.setAntiAlias (true);
        paint.setStyle (Paint.Style.FILL);
        paint.setColor (rippleColor);
        paint.setAlpha (rippleAlpha);
        this.setWillNotDraw (false);
 
        gestureDetector = new GestureDetector (context, new GestureDetector.SimpleOnGestureListener () {
            @Override
            public void onLongPress (MotionEvent event) {
                super.onLongPress (event);
                animateRipple (event);
                sendClickEvent (true);
            }
 
            @Override
            public boolean onSingleTapConfirmed (MotionEvent e) {
                return true;
            }
 
            @Override
            public boolean onSingleTapUp (MotionEvent e) {
                return true;
            }
        });
 
        this.setDrawingCacheEnabled (true);
        this.setClickable (true);
    }
 
    @Override
    public void draw (Canvas canvas) {
        super.draw (canvas);
        if (animationRunning) {
            if (rippleDuration <= timer * frameRate) {
                animationRunning = false;
                timer = 0;
                durationEmpty = -1;
                timerEmpty = 0;
                canvas.restore ();
                invalidate ();
                if (onCompletionListener = null!) onCompletionListener.onComplete (this);
                return;
            } Else
                canvasHandler.postDelayed (runnable, frameRate);
 
            if (timer == 0)
                canvas.save ();
 
 
            canvas.drawCircle (x, y, (radiusMax * (((float) timer * frameRate) / rippleDuration)), paint);
 
            paint.setColor (Color.parseColor ( "# ffff4444"));
 
            if (rippleType == 1 && originBitmap! = null && (((float) timer * frameRate) / rippleDuration)> 0.4f) {
                if (durationEmpty == -1)
                    durationEmpty = rippleDuration - timer * frameRate;
 
                timerEmpty ++;
                final Bitmap tmpBitmap = getCircleBitmap ((int) ((radiusMax) * (((float) timerEmpty * frameRate) / (durationEmpty))));
                canvas.drawBitmap (tmpBitmap, 0, 0, paint);
                tmpBitmap.recycle ();
            }
 
            paint.setColor (rippleColor);
 
            if (rippleType == 1) {
                if ((((float) timer * frameRate) / rippleDuration)> 0.6f)
                    paint.setAlpha ((int) (rippleAlpha - ((rippleAlpha) * (((float) timerEmpty * frameRate) / (durationEmpty)))));
                else
                    paint.setAlpha (rippleAlpha);
            }
            else
                paint.setAlpha ((int) (rippleAlpha - ((rippleAlpha) * (((float) timer * frameRate) / rippleDuration))));
 
            timer ++;
        }
    }
 
    @Override
    protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        super.onSizeChanged (w, h, oldw, oldh);
        WIDTH = w;
        HEIGHT = h;
 
        scaleAnimation = new ScaleAnimation (1.0f, zoomScale, 1.0f, zoomScale, w / 2, h / 2);
        scaleAnimation.setDuration (zoomDuration);
        scaleAnimation.setRepeatMode (Animation.REVERSE);
        scaleAnimation.setRepeatCount (1);
    }
 
    / **
    * Launch Ripple animation for the current view with a MotionEvent
    *
    * @param Event MotionEvent registered by the Ripple gesture listener
    * /
    public void animateRipple (MotionEvent event) {
        createAnimation (event.getX (), event.getY ());
    }
 
    / **
    * Launch Ripple animation for the current view centered at x and y position
    *
    * @param X Horizontal position of the ripple center
    * @param Y Vertical position of the ripple center
    * /
    public void animateRipple (final float x, final float y) {
        createAnimation (x, y);
    }
 
    / **
    * Create Ripple animation centered at x, y
    *
    * @param X Horizontal position of the ripple center
    * @param Y Vertical position of the ripple center
    * /
    private void createAnimation (final float x, final float y) {
        if (this.isEnabled () &&! animationRunning) {
            if (hasToZoom)
                this.startAnimation (scaleAnimation);
 
            radiusMax = Math.max (WIDTH, HEIGHT);
 
            if (rippleType! = 2)
                radiusMax / = 2;
 
            radiusMax - = ripplePadding;
 
            if (isCentered || rippleType == 1) {
                this.x = getMeasuredWidth () / 2;
                this.y = getMeasuredHeight () / 2;
            } Else {
                this.x = x;
                this.y = y;
            }
 
            animationRunning = true;
 
            if (rippleType == 1 && originBitmap == null)
                originBitmap = getDrawingCache (true);
 
            invalidate ();
        }
    }

 @Override
    public boolean onTouchEvent (MotionEvent event) {
        if (gestureDetector.onTouchEvent (event)) {
            animateRipple (event);
            sendClickEvent (false);
        }
        return super.onTouchEvent (event);
    }
 
    @Override
    public boolean onInterceptTouchEvent (MotionEvent event) {
        this.onTouchEvent (event);
        return super.onInterceptTouchEvent (event);
    }
 
    / **
    * Send a click event if parent view is a Listview instance
    *
    * @param IsLongClick Is the event a long click?
    * /
    private void sendClickEvent (final Boolean isLongClick) {
        if (getParent () instanceof AdapterView) {
            final AdapterView adapterView = (AdapterView) getParent ();
            final int position = adapterView.getPositionForView (this);
            final long id = adapterView.getItemIdAtPosition (position);
            if (isLongClick) {
                if (adapterView.getOnItemLongClickListener ()! = null)
                    adapterView.getOnItemLongClickListener () onItemLongClick (adapterView, this, position, id).;
            } Else {
                if (adapterView.getOnItemClickListener ()! = null)
                    adapterView.getOnItemClickListener () onItemClick (adapterView, this, position, id).;
            }
        }
    }
 
    private Bitmap getCircleBitmap (final int radius) {
        final Bitmap output = Bitmap.createBitmap (originBitmap.getWidth (), originBitmap.getHeight (), Bitmap.Config.ARGB_8888);
        final Canvas canvas = new Canvas (output);
        final Paint paint = new Paint ();
        final Rect rect = new Rect ((int) (x - radius), (int) (y - radius), (int) (x + radius), (int) (y + radius));
 
        paint.setAntiAlias (true);
        canvas.drawARGB (0, 0, 0, 0);
        canvas.drawCircle (x, y, radius, paint);
 
        paint.setXfermode (new PorterDuffXfermode (PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap (originBitmap, rect, rect, paint);
 
        return output;
    }
 
    / **
    * Set Ripple color, default is #FFFFFF
    *
    * @param RippleColor New color resource
    * /
    @ColorRes
    public void setRippleColor (int rippleColor) {
        this.rippleColor = getResources () getColor (rippleColor).;
    }
 
    public int getRippleColor () {
        return rippleColor;
    }
 
    public RippleType getRippleType ()
    {
        return RippleType.values () [rippleType];
    }
 
    / **
    * Set Ripple type, default is RippleType.SIMPLE
    *
    * @param RippleType New Ripple type for next animation
    * /
    public void setRippleType (final RippleType rippleType)
    {
        this.rippleType = rippleType.ordinal ();
    }
 
    public Boolean isCentered ()
    {
        return isCentered;
    }
 
    / **
    * Set if ripple animation has to be centered in its parent view or not, default is False
    *
    * @param IsCentered
    * /
    public void setCentered (final Boolean isCentered)
    {
        this.isCentered = isCentered;
    }
 
    public int getRipplePadding ()
    {
        return ripplePadding;
    }
 
    / **
    * Set Ripple padding if you want to avoid some graphic glitch
    *
    * @param RipplePadding New Ripple padding in pixel, default is 0px
    * /
    public void setRipplePadding (int ripplePadding)
    {
        this.ripplePadding = ripplePadding;
    }
 
    public Boolean isZooming ()
    {
        return hasToZoom;
    }
 
    / **
    * At the end of Ripple effect, the child views has to zoom
    *
    * @param HasToZoom Do the child views have to zoom? Default is False
    * /
    public void setZooming (Boolean hasToZoom)
    {
        this.hasToZoom = hasToZoom;
    }
 
    public float getZoomScale ()
    {
        return zoomScale;
    }
 
    / **
    * Scale of the end animation
    *
    * @param ZoomScale Value of scale animation, default is 1.03f
    * /
    public void setZoomScale (float zoomScale)
    {
        this.zoomScale = zoomScale;
    }
 
    public int getZoomDuration ()
    {
        return zoomDuration;
    }
 
    / **
    * Duration of the ending animation in ms
    *
    * @param ZoomDuration Duration, default is 200ms
    * /
    public void setZoomDuration (int zoomDuration)
    {
        this.zoomDuration = zoomDuration;
    }
 
    public int getRippleDuration ()
    {
        return rippleDuration;
    }
 
    / **
    * Duration of the Ripple animation in ms
    *
    * @param RippleDuration Duration, default is 400ms
    * /
    public void setRippleDuration (int rippleDuration)
    {
        this.rippleDuration = rippleDuration;
    }
 
    public int getFrameRate ()
    {
        return frameRate;
    }
 
    / **
    * Set framerate for Ripple animation
    *
    * @param FrameRate New framerate value, default is 10
    * /
    public void setFrameRate (int frameRate)
    {
        this.frameRate = frameRate;
    }
 
    public int getRippleAlpha ()
    {
        return rippleAlpha;
    }
 
    / **
    * Set alpha for ripple effect color
    *
    * @param RippleAlpha Alpha value between 0 and 255, default is 90
    * /
    public void setRippleAlpha (int rippleAlpha)
    {
        this.rippleAlpha = rippleAlpha;
    }
 
    public void setOnRippleCompleteListener (OnRippleCompleteListener listener) {
        this.onCompletionListener = listener;
    }
 
    / **
    * Defines a callback called at the end of the Ripple effect
    * /
    public interface OnRippleCompleteListener {
        void onComplete (RippleView rippleView);
    }
 
    public enum RippleType {
        SIMPLE (0),
        DOUBLE (1),
        RECTANGLE (2);
 
        int type;
 
        RippleType (int type)
        {
            this.type = type;
        }
    }
}

2. Custom Properties

< ? Xml version = "1.0" encoding = "utf-8"?>
< Resources>
    < Declare-styleable name = "RippleView"> rv_zoomDuration
        < Attr name = "rv_alpha" format = "integer" />
        < Attr name = "rv_framerate" format = "integer" />
        < Attr name = "rv_rippleDuration" format = "integer" />
        < Attr name = "rv_zoomDuration" format = "integer" />
        < Attr name = "rv_color" format = "color" />
        < Attr name = "rv_centered" format = "boolean" />
        < Attr name = "rv_type" format = "enum">
            < Enum name = "simpleRipple" value = "0" />
            < Enum name = "doubleRipple" value = "1" />
            < Enum name = "rectangle" value = "2" />
        < / Attr>
        < Attr name = "rv_ripplePadding" format = "dimension" />
        < Attr name = "rv_zoom" format = "boolean" />
        < Attr name = "rv_zoomScale" format = "float" />
  < / Declare-styleable>
< / Resources>

3. The main layout file

< LinearLayout xmlns: android = "http://schemas.android.com/apk/res/android"
    xmlns: ripple = "http://schemas.android.com/apk/res-auto"
    xmlns: tools = "http://schemas.android.com/tools"
    android: layout_width = "match_parent"
    android: layout_height = "match_parent"
    android: orientation = "vertical">
 
    < ScrollView
        android: layout_width = "match_parent"
        android: layout_height = "wrap_content">
 
        < LinearLayout
            android: layout_width = "match_parent"
            android: layout_height = "wrap_content"
            android: gravity = "center_horizontal"
            android: orientation = "vertical">
 
            < -! 1 rv_centered = "true" rv_type = "simpleRipple" ->
 
            < Com.example.RippleEffect.RippleView
                android: id = "@ + id / more"
                android: layout_width = "wrap_content"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_centered = "true">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 2 rv_centered = "false" rv_type = "simpleRipple" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "wrap_content"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_centered = "false"
                ripple: rv_type = "simpleRipple">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 3 rv_type = "doubleRipple" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "wrap_content"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_type = "doubleRipple">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 4 rv_type = "rectangle" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "match_parent"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_type = "doubleRipple">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 5 rv_zoom = "true" rv_ripplePadding = "20dp" ripple: rv_zoomScale = "1.25" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "wrap_content"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_centered = "false"
                ripple: rv_color = "# D91615"
                ripple: rv_rippleDuration = "2000"
                ripple: rv_ripplePadding = "20dp"
                ripple: rv_zoom = "true"
                ripple: rv_zoomDuration = "200"
                ripple: rv_zoomScale = "1.25">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 6 rv_type = "simpleRipple" rv_alpha = "10" rv_framerate = "100" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "match_parent"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_alpha = "200"
                ripple: rv_framerate = "100"
                ripple: rv_type = "simpleRipple">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 7 rv_type = "simpleRipple" rv_alpha = "10" rv_framerate = "2" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "match_parent"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_alpha = "200"
                ripple: rv_framerate = "2"
                ripple: rv_type = "simpleRipple">
 
                < ImageView
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: src = "@ drawable / ic_launcher" />
            < /com.example.RippleEffect.RippleView>
 
            < -! 8 rv_type = "simpleRipple" rv_alpha = "10" rv_framerate = "2" ->
 
            < Com.example.RippleEffect.RippleView
                android: layout_width = "match_parent"
                android: layout_height = "wrap_content"
                android: layout_margin = "5dp"
                ripple: rv_alpha = "200"
                ripple: rv_framerate = "2"
                ripple: rv_type = "simpleRipple">
 
                < Button
                    android: layout_width = "match_parent"
                    android: layout_height = "wrap_content"
                    android: layout_centerInParent = "true"
                    android: background = "# BAC9FF"
                    android: padding = "15dp"
                    android: text = "Button" />
            < /com.example.RippleEffect.RippleView>
        < / LinearLayout>
    < / ScrollView>

< / LinearLayout>

Thanks for the warm git large share God's help given, all the above is to achieve the implementation of water ripple effect, only for reference study, and welcome to the exchange ~
     
         
         
         
  More:      
 
- TeamCity continuous integration in the Linux installation (Linux)
- Python script running in the background (Programming)
- Linux firewall iptables beginner tutorial (Linux)
- How to remove the Linux memory Cache, Buffer and swap space (Linux)
- Installed in the desktop version of Ubuntu Unity Tweak Tool (Linux)
- Ubuntu Server security risk checks (Linux)
- Debian GNU / Linux service list acquisition, shutting down services or run (Linux)
- df show disk space usage (Linux)
- Analysis of Java reflection mechanism (Programming)
- Linux System Getting Started Tutorial: How do you know Shell which is currently being used (Linux)
- VMware11 virtual machine Ubuntu14.10 system partition sda1 disk expansion (Linux)
- Lua4.0 interpreter entrance (Programming)
- See Shell Script Linux Server network traffic (Server)
- Linux Nginx FastDFS integration module is installed Nginx and FastDFS (Server)
- How to use the internal network IP forwarding to connect to the Internet on Linux (Linux)
- Install Xshell on Mac OS X (Linux)
- VMware6 achieve nat Internet (Linux)
- Xtrabackup creates a slave node without downtime (Database)
- Linux script to copy the folder to all folders with the same name (Linux)
- Installation in lxml Python module (Linux)
     
           
     
  CopyRight 2002-2022 newfreesoft.com, All Rights Reserved.