<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    咖啡伴侶

    呆在上海
    posts - 163, comments - 156, trackbacks - 0, articles - 2

    android手勢效果-水果忍者 刀鋒效果/光刀效果

    Posted on 2011-09-23 11:29 oathleo 閱讀(3957) 評論(5)  編輯  收藏 所屬分類: Android
    請保留:
    http://www.tkk7.com/oathleo/archive/2011/09/23/android_Fruit_Ninja.html


    android手勢加上了,比如左右滑動
    但是用戶經常不能感受到是否滑動了,
    水果忍者刀鋒效果/光刀效果就相當不錯

    網上搜了下,大多是ios的實現,想想原理可能不是很復雜,就實現了個最簡單的。
    原理
    1.在背景view上再加一層view專門負責draw刀鋒
    2.刀鋒就是隨著手勢move,動態畫shape
    3.接受到事件得dispatchTouchEvent,否則下面的組件無法獲得事件了
    4.下面的組件事件等無需更改,互不耦合
    5.一個類實現,不涉及其他第三方
    6.只實現了一個最簡單的形狀,水果忍者里面實現了很多復雜形狀,可以在這個基礎上進行擴展
    效果如圖



    代碼:
    import android.content.Context;
    import android.graphics.Canvas;
    import android.graphics.Color;
    import android.graphics.Paint;
    import android.graphics.Path;
    import android.view.MotionEvent;
    import android.view.View;



    /**
     * 
     * 模仿水果忍者刀鋒效果
     * 
    @author leooath@gmail.com
     *
     
    */
    public class GestureView extends View {

        
    private Paint paint;

        
    private float startX = Float.NaN;
        
    private float startY = Float.NaN;
        
    private float endX = Float.NaN;
        
    private float endY = Float.NaN;

        
    //下層view
        private View viewer;
        
    private static final int gestureColor = Color.rgb(153153153);
        
    private static final int alpha = 220;
        
    private static final int alpha_full = 255;
        
    //刀鋒長度
        private static final int shape_length = 40;
        
    //刀鋒截短時間
        private static final int shape_cut_time = 150;
        
        
    public GestureView(Context context, View viewer) {
            
    super(context);
            
    this.viewer = viewer;
            paint 
    = new Paint();
            paint.setStyle(Paint.Style.FILL);
        }

        
    public void draw(Canvas canvas) {
            
    super.draw(canvas);
            
    if (!Float.isNaN(startX) && !Float.isNaN(endY)) {
                
    float gap = ViewUtils.getGap(startX, startY, endX, endY);
                
    float w = gap / 10;
                
    //背景shape外側點高度
                float h = w > 7 ? 7 : w;
                
    //填充shape外側點高度
                float h2 = h * 2 / 3

                
    double length = Math.pow(Math.pow(w, 2+ Math.pow((h), 2), 0.5);
                
    double length2 = Math.pow(Math.pow(w, 2+ Math.pow((h2), 2), 0.5);
                
                
    double ang1_1 = Math.atan((endY - startY) / (endX - startX));
                
    double ang1_2 = Math.atan(h / w);
                
    double angle1_1 = ang1_1 + ang1_2;
                
    double angle1_2 = ang1_1 - ang1_2;
                
                
    double ang2_2 = Math.atan(h2 / w);
                
    double angle2_1 = ang1_1 + ang2_2;
                
    double angle2_2 = ang1_1 - ang2_2;
                
    if (endX > startX) {
                    
    float xx1 = endX - (float) (length * Math.cos(angle1_1));
                    
    float yy1 = endY - (float) (length * Math.sin(angle1_1));
                    
    float xx2 = endX - (float) (length * Math.cos(angle1_2));
                    
    float yy2 = endY - (float) (length * Math.sin(angle1_2));

                    
    float xx12 = endX - (float) (length2 * Math.cos(angle2_1));
                    
    float yy12 = endY - (float) (length2 * Math.sin(angle2_1));
                    
    float xx22 = endX - (float) (length2 * Math.cos(angle2_2));
                    
    float yy22 = endY - (float) (length2 * Math.sin(angle2_2));
                    
                    Path backPath 
    = new Path();
                    backPath.moveTo(startX, startY);
                    backPath.lineTo(xx1, yy1);
                    backPath.lineTo(endX, endY);
                    backPath.lineTo(xx2, yy2);
                    backPath.close();
                    
                    Path fillPath 
    = new Path();
                    fillPath.moveTo(startX, startY);
                    fillPath.lineTo(xx12, yy12);
                    fillPath.lineTo(endX, endY);
                    fillPath.lineTo(xx22, yy22);
                    fillPath.close();

                    paint.setColor(gestureColor);
                    paint.setAlpha(alpha);
                    canvas.drawPath(backPath, paint);
                    
                    paint.setColor(Color.WHITE);
                    paint.setAlpha(alpha_full);
                    canvas.drawPath(fillPath, paint);
                } 
    else {
                    
    float xx1 = endX + (float) (length * Math.cos(angle1_1));
                    
    float yy1 = endY + (float) (length * Math.sin(angle1_1));
                    
    float xx2 = endX + (float) (length * Math.cos(angle1_2));
                    
    float yy2 = endY + (float) (length * Math.sin(angle1_2));

                    
    float xx12 = endX + (float) (length2 * Math.cos(angle2_1));
                    
    float yy12 = endY + (float) (length2 * Math.sin(angle2_1));
                    
    float xx22 = endX + (float) (length2 * Math.cos(angle2_2));
                    
    float yy22 = endY + (float) (length2 * Math.sin(angle2_2));
                    
                    Path backPath 
    = new Path();
                    backPath.moveTo(startX, startY);
                    backPath.lineTo(xx1, yy1);
                    backPath.lineTo(endX, endY);
                    backPath.lineTo(xx2, yy2);
                    backPath.close();

                    Path fillPath 
    = new Path();
                    fillPath.moveTo(startX, startY);
                    fillPath.lineTo(xx12, yy12);
                    fillPath.lineTo(endX, endY);
                    fillPath.lineTo(xx22, yy22);
                    fillPath.close();

                    paint.setColor(gestureColor);
                    paint.setAlpha(alpha);
                    canvas.drawPath(backPath, paint);
                    
                    paint.setColor(Color.WHITE);
                    paint.setAlpha(alpha_full);
                    canvas.drawPath(fillPath, paint);
                }
            }
        }

        
    public boolean onTouchEvent(android.view.MotionEvent event) {
            
    if(event.getPointerCount() == 1){
                
    int action = event.getAction();
                
    if (MotionEvent.ACTION_DOWN == action) {
                    startX 
    = event.getX();
                    startY 
    = event.getY();
                } 
    else if (MotionEvent.ACTION_MOVE == action) {
                    endX 
    = event.getX();
                    endY 
    = event.getY();
                    
                    
    //刀鋒截短時間,則截短至一半
                    if ((event.getEventTime() - event.getDownTime()) > shape_cut_time) {
                        
    if(Math.abs(endX - startX) > shape_length && Math.abs(endY - startY) > shape_length){
                            startX 
    = (float) (startX + (endX - startX) * 0.5);
                            startY 
    = (float) (startY + (endY - startY) * 0.5);
                        }
                    }

                    invalidate();
                } 
    else if (MotionEvent.ACTION_UP == action) {
                    startX 
    = Float.NaN;
                    startY 
    = Float.NaN;
                    endX 
    = Float.NaN;
                    endY 
    = Float.NaN;
                    invalidate();
                }
            }
            
    //該view消費了event,所以下層的view必須dispatchTouchEvent才能獲得事件
            MotionEvent newEvent = MotionEvent.obtain(event);
            viewer.dispatchTouchEvent(newEvent);
            
    return true;
        }

    }

    Feedback

    # re: android手勢效果-水果忍者 刀鋒效果/光刀效果  回復  更多評論   

    2011-09-25 23:23 by tbw
    不錯啊

    # re: android手勢效果-水果忍者 刀鋒效果/光刀效果  回復  更多評論   

    2011-09-28 16:45 by 優美科

    ViewUtils.getGap(startX, startY, endX, endY);
    函數呢 怎么沒有

    # re: android手勢效果-水果忍者 刀鋒效果/光刀效果  回復  更多評論   

    2011-10-13 13:44 by oathleo
    @優美科
    /**
    * 獲得兩點間距離
    */
    public static final float getGap(float x0, float y0, float x1, float y1) {
    return (float) Math.pow(Math.pow((x0 - x1), 2) + Math.pow((y0 - y1), 2), 0.5);
    }

    # re: android手勢效果-水果忍者 刀鋒效果/光刀效果[未登錄]  回復  更多評論   

    2012-03-24 20:22 by tobe
    那請問怎樣在一層view上加入這層半透明的view呢?

    # re: android手勢效果-水果忍者 刀鋒效果/光刀效果  回復  更多評論   

    2012-04-07 21:17 by banxi
    請問下,我想實現水果忍者的切按鈕的效果。也就是更進一步的效果如果處理。特向您請教下!
    主站蜘蛛池模板: 亚洲欧洲无码一区二区三区| 亚洲精品无码不卡| 亚洲aⅴ无码专区在线观看| 国产h视频在线观看免费| 亚洲日韩乱码中文无码蜜桃臀| 久久国产精品2020免费m3u8| 久久综合图区亚洲综合图区| 人妻无码一区二区三区免费| 亚洲最大视频网站| 亚洲欧洲免费无码| MM1313亚洲精品无码久久| 国产免费观看青青草原网站| 一级毛片免费播放视频| 久久久久亚洲AV无码专区网站| 免费在线黄色电影| 亚洲黄色网址大全| 成人免费视频试看120秒| 精品免费AV一区二区三区| 伊人久久亚洲综合| 免费一级毛片在线播放视频| 亚洲国产成人精品青青草原| 成全视频免费高清| sss日本免费完整版在线观看| 狠狠亚洲婷婷综合色香五月排名| 香蕉免费一区二区三区| 亚洲伊人久久大香线蕉在观| 成在线人永久免费视频播放| 国产高清对白在线观看免费91| 亚洲AV日韩AV鸥美在线观看| 亚洲精品动漫免费二区| 日本精品久久久久久久久免费| 国产国拍亚洲精品mv在线观看 | 日韩精品免费视频| 亚洲国产午夜电影在线入口| 在线日韩av永久免费观看| 国产精品免费看久久久香蕉| 亚洲福利一区二区三区| 国产乱子伦片免费观看中字| 亚洲免费人成在线视频观看| 亚洲色欲啪啪久久WWW综合网| 伊人久久大香线蕉亚洲|