Closed. This question needs details or clarity。它当前不接受答案。
                            
                        
                    
                
                            
                                
                
                        
                            
                        
                    
                        
                            想改善这个问题吗?添加详细信息并通过editing this post阐明问题。
                        
                        3年前关闭。
                                                                                            
                
        
我最近找到了以下代码:

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;

public class RippleViewCreator extends FrameLayout {
    private float duration = 150;
    private int frameRate = 15;
    private float speed = 1;
    private float radius = 0;
    private Paint paint = new Paint();
    private float endRadius = 0;
    private float rippleX = 0;
    private float rippleY = 0;
    private int width = 0;
    private int height = 0;
    private Handler handler = new Handler();
    private int touchAction;

    public RippleViewCreator(Context context) {
        this(context, null, 0);
    }

    public RippleViewCreator(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public RippleViewCreator(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        if (isInEditMode())
            return;

        paint.setStyle(Paint.Style.FILL);
        paint.setColor(getResources().getColor(R.color.control_highlight_color));
        paint.setAntiAlias(true);

        setWillNotDraw(true);
        setDrawingCacheEnabled(true);
        setClickable(true);
    }

    public static void addRippleToView(View v) {
        ViewGroup parent = (ViewGroup) v.getParent();
        int index = -1;
        if (parent != null) {
            index = parent.indexOfChild(v);
            parent.removeView(v);
        }
        RippleViewCreator rippleViewCreator = new RippleViewCreator(v.getContext());
        rippleViewCreator.setLayoutParams(v.getLayoutParams());
        if (index == -1)
            parent.addView(rippleViewCreator, index);
        else
            parent.addView(rippleViewCreator);
        rippleViewCreator.addView(v);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        width = w;
        height = h;
    }

    @Override
    protected void dispatchDraw(@NonNull Canvas canvas) {
        super.dispatchDraw(canvas);

        if (radius > 0 && radius < endRadius) {
            canvas.drawCircle(rippleX, rippleY, radius, paint);
            if (touchAction == MotionEvent.ACTION_UP)
                invalidate();
        }
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return true;
    }

    @Override
    public boolean onTouchEvent(@NonNull MotionEvent event) {
        rippleX = event.getX();
        rippleY = event.getY();

        touchAction = event.getAction();
        switch (event.getAction()) {
            case MotionEvent.ACTION_UP: {
                getParent().requestDisallowInterceptTouchEvent(false);

                radius = 1;
                endRadius = Math.max(Math.max(Math.max(width - rippleX, rippleX), rippleY), height - rippleY);
                speed = endRadius / duration * frameRate;
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (radius < endRadius) {
                            radius += speed;
                            paint.setAlpha(90 - (int) (radius / endRadius * 90));
                            handler.postDelayed(this, frameRate);
                        } else if (getChildAt(0) != null) {
                            getChildAt(0).performClick();
                        }
                    }
                }, frameRate);
                break;
            }
            case MotionEvent.ACTION_CANCEL: {
                getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
            case MotionEvent.ACTION_DOWN: {
                getParent().requestDisallowInterceptTouchEvent(true);
                endRadius = Math.max(Math.max(Math.max(width - rippleX, rippleX), rippleY), height - rippleY);
                paint.setAlpha(90);
                radius = endRadius / 3;
                invalidate();
                return true;
            }
            case MotionEvent.ACTION_MOVE: {
                if (rippleX < 0 || rippleX > width || rippleY < 0 || rippleY > height) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                    touchAction = MotionEvent.ACTION_CANCEL;
                    break;
                } else {
                    invalidate();
                    return true;
                }
            }
        }
        invalidate();
        return false;
    }

    @Override
    public final void addView(@NonNull View child, int index, ViewGroup.LayoutParams params) {
        //limit one view
        if (getChildCount() > 0) {
            throw new IllegalStateException(this.getClass().toString() + " can only have one child.");
        }
        super.addView(child, index, params);
    }
}


谁能给我解释一下这种涟漪效应代码是如何工作的,因为我已经尝试了至少一天了,但是我仍然无法理解它是如何工作的。

正是我不明白:

public static void addRippleToView(View v) {
    ViewGroup parent = (ViewGroup) v.getParent();
    int index = -1;
    if (parent != null) {
        index = parent.indexOfChild(v);
        parent.removeView(v);
    }
    RippleViewCreator rippleViewCreator = new RippleViewCreator(v.getContext());
    rippleViewCreator.setLayoutParams(v.getLayoutParams());
    if (index == -1)
        parent.addView(rippleViewCreator, index);
    else
        parent.addView(rippleViewCreator);
    rippleViewCreator.addView(v);
}

最佳答案

我不知道该类是否真正起作用,但是如果起作用,则可能是这样的:

此自定义视图将FrameLayout子类化,这意味着它希望具有子视图。因此,您可以在视图XML中声明它,并为其赋予一个子级以使其位于其边界内。

当在onTouchEVent中接收到触摸事件时,它将绘制动画波纹效果,该效果将出现在它包含的视图的后面。

开发人员还可以通过调用addRippleToView来告诉此RippleViewCreator在其包含的特定视图后呈现涟漪效果。看起来此方法似乎从视图层次结构中删除了目标子视图,将其包装在另一个RippleViewCreator中,并将其添加回其自己的视图层次结构中以进行波纹动画处理。

疯狂的东西,伙计。

关于java - 涟漪效应源代码如何工作? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35306054/

10-10 09:12