<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手勢(shì)效果-水果忍者 刀鋒效果/光刀效果

    Posted on 2011-09-23 11:29 oathleo 閱讀(3974) 評(píng)論(5)  編輯  收藏 所屬分類(lèi): Android
    請(qǐng)保留:
    http://m.tkk7.com/oathleo/archive/2011/09/23/android_Fruit_Ninja.html


    android手勢(shì)加上了,比如左右滑動(dòng)
    但是用戶經(jīng)常不能感受到是否滑動(dòng)了,
    水果忍者刀鋒效果/光刀效果就相當(dāng)不錯(cuò)

    網(wǎng)上搜了下,大多是ios的實(shí)現(xiàn),想想原理可能不是很復(fù)雜,就實(shí)現(xiàn)了個(gè)最簡(jiǎn)單的。
    原理
    1.在背景view上再加一層view專(zhuān)門(mén)負(fù)責(zé)draw刀鋒
    2.刀鋒就是隨著手勢(shì)move,動(dòng)態(tài)畫(huà)shape
    3.接受到事件得dispatchTouchEvent,否則下面的組件無(wú)法獲得事件了
    4.下面的組件事件等無(wú)需更改,互不耦合
    5.一個(gè)類(lèi)實(shí)現(xiàn),不涉及其他第三方
    6.只實(shí)現(xiàn)了一個(gè)最簡(jiǎn)單的形狀,水果忍者里面實(shí)現(xiàn)了很多復(fù)雜形狀,可以在這個(gè)基礎(chǔ)上進(jìn)行擴(kuò)展
    效果如圖



    代碼:
    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;
        
    //刀鋒長(zhǎng)度
        private static final int shape_length = 40;
        
    //刀鋒截短時(shí)間
        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外側(cè)點(diǎn)高度
                float h = w > 7 ? 7 : w;
                
    //填充shape外側(cè)點(diǎn)高度
                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();
                    
                    
    //刀鋒截短時(shí)間,則截短至一半
                    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消費(fèi)了event,所以下層的view必須dispatchTouchEvent才能獲得事件
            MotionEvent newEvent = MotionEvent.obtain(event);
            viewer.dispatchTouchEvent(newEvent);
            
    return true;
        }

    }

    Feedback

    # re: android手勢(shì)效果-水果忍者 刀鋒效果/光刀效果  回復(fù)  更多評(píng)論   

    2011-09-25 23:23 by tbw
    不錯(cuò)啊

    # re: android手勢(shì)效果-水果忍者 刀鋒效果/光刀效果  回復(fù)  更多評(píng)論   

    2011-09-28 16:45 by 優(yōu)美科

    ViewUtils.getGap(startX, startY, endX, endY);
    函數(shù)呢 怎么沒(méi)有

    # re: android手勢(shì)效果-水果忍者 刀鋒效果/光刀效果  回復(fù)  更多評(píng)論   

    2011-10-13 13:44 by oathleo
    @優(yōu)美科
    /**
    * 獲得兩點(diǎn)間距離
    */
    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手勢(shì)效果-水果忍者 刀鋒效果/光刀效果[未登錄](méi)  回復(fù)  更多評(píng)論   

    2012-03-24 20:22 by tobe
    那請(qǐng)問(wèn)怎樣在一層view上加入這層半透明的view呢?

    # re: android手勢(shì)效果-水果忍者 刀鋒效果/光刀效果  回復(fù)  更多評(píng)論   

    2012-04-07 21:17 by banxi
    請(qǐng)問(wèn)下,我想實(shí)現(xiàn)水果忍者的切按鈕的效果。也就是更進(jìn)一步的效果如果處理。特向您請(qǐng)教下!
    主站蜘蛛池模板: 在线v片免费观看视频| 成人精品一区二区三区不卡免费看 | 婷婷亚洲综合一区二区| 亚洲国产综合专区电影在线| 国产zzjjzzjj视频全免费| 好男人视频社区精品免费| 久久狠狠躁免费观看2020| 国产VA免费精品高清在线| 亚洲成a人片在线不卡一二三区 | 免费在线观看h片| 1000部拍拍拍18勿入免费视频下载 | 四虎永久免费网站免费观看| 永久免费av无码不卡在线观看| 国产高清免费视频| 成年女人看片免费视频播放器| 亚洲免费网站观看视频| 毛片a级毛片免费观看免下载| 成年午夜视频免费观看视频| 在线观看的免费网站无遮挡| 在线观看免费人成视频| 国产禁女女网站免费看| 亚洲中久无码不卡永久在线观看| 亚洲欧洲中文日韩久久AV乱码| 男人的天堂亚洲一区二区三区 | 成人毛片免费观看视频大全| 久久久久免费看黄A片APP| 免费一级成人毛片| 亚洲国产精品无码成人片久久 | 亚洲免费观看视频| 91精品免费久久久久久久久| 午夜a级成人免费毛片| 精品亚洲一区二区三区在线观看| 激情内射亚洲一区二区三区| 中文字幕乱码亚洲无线三区| 福利免费在线观看| 久久这里只有精品国产免费10| 亚洲成A人片在线观看无码3D| 精品国产亚洲一区二区三区| 国产精品亚洲片在线va| 免费国产污网站在线观看| 免费看www视频|