手機QQ5.0紅點拖拽消除的實現

來源:互聯網
上載者:User

標籤:android   拖拽   紅點   qq   

新版手機QQ5.+上新增了一種“一鍵退朝”的功能,即在頁面上的紅點可進行拖拽消除。在[知乎](http://www.zhihu.com/question/26382740)上可參考紅點的設計過程。按照設計思路在Android上模仿手Q實現下拖拽的過程。

代碼地址:https://github.com/chenupt/BezierDemo





整體的思路,封裝好一個view。在介面上找到四個點,即框出手勢拖動點與紅點之間的範圍,利用貝茲路徑修飾邊框,計算紅點和手勢拖動點間的距離,判斷紅點的消除與回彈。
借用下設計圖:


首先確定以紅點為座標原點,在座標上所要計算的就是p1, p2, p3, p4四個點,其中..為貝茲路徑,在p1p2和p3p4之間需要繪製半徑為R和r的圓。


接下來需要的就是在拖動過程中計算(0,0)和(x0, y0)兩點間的距離,通過距離控制貝茲路徑的弧度和圓的大小,實現類比現實生活中彈性效果。

在代碼中通過Path來控制p1, p2, p3, p4四個點所圍成的範圍,並填充相應地色值:

1.確定四個點,這裡簡單地將兩個圓起始半徑設定相等

        float x1 = startX - offsetX;        float y1 = startY + offsetY;        float x2 = x - offsetX;        float y2 = y + offsetY;        float x3 = x + offsetX;        float y3 = y - offsetY;        float x4 = startX + offsetX;        float y4 = startY - offsetY;        path.reset();        path.moveTo(x1, y1);        path.quadTo(anchorX, anchorY, x2, y2);        path.lineTo(x3, y3);        path.quadTo(anchorX, anchorY, x4, y4);        path.lineTo(x1, y1);
2.填充範圍和繪製圓形:

canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.MULTIPLY);canvas.drawPath(path, paint);canvas.drawCircle(startX, startY, radius, paint);canvas.drawCircle(x, y, radius, paint);
3.在調用super.onDraw(canvas);方法繪製在canvas層上面的訊息點表徵圖imageView
通過在代碼中的onTouchEvent方法進行控制觸摸點的相應位置,實現拖動的效果。

@Override    public boolean onTouchEvent(MotionEvent event) {        if(event.getAction() == MotionEvent.ACTION_DOWN){            // 判斷觸摸點是否在tipImageView中            Rect rect = new Rect();            int[] location = new int[2];            tipImageView.getDrawingRect(rect);            tipImageView.getLocationOnScreen(location);            rect.left = location[0];            rect.top = location[1];            rect.right = rect.right + location[0];            rect.bottom = rect.bottom + location[1];            if (rect.contains((int)event.getRawX(), (int)event.getRawY())){                isTouch = true;            }        }else if(event.getAction() == MotionEvent.ACTION_UP || event.getAction() == MotionEvent.ACTION_CANCEL){            isTouch = false;            tipImageView.setX(startX - tipImageView.getWidth()/2);            tipImageView.setY(startY - tipImageView.getHeight()/2);        }        invalidate();        if(isAnimStart){            return super.onTouchEvent(event);        }        anchorX =  (event.getX() + startX)/2;        anchorY =  (event.getY() + startY)/2;        x =  event.getX();        y =  event.getY();        return true;    }

4.拖動過程中計算兩個圓心之間的距離,通過圓心間的距離調整圓心為(0, 0)圓的半徑大小

float distance = (float) Math.sqrt(Math.pow(y-startY, 2) + Math.pow(x-startX, 2));radius = -distance/15+DEFAULT_RADIUS;
用新的半徑去繪製(0, 0)的圓,這樣隨著距離的增加,圓相應變小就給人如同快要沾不住黏黏的感覺。

5.距離超過設定的最大範圍,則設定為紅點掙脫狀態,如果手指抬起,則開始播放相應爆炸動畫。

exploredImageView.setVisibility(View.VISIBLE);exploredImageView.setImageResource(R.drawable.tip_anim);((AnimationDrawable) exploredImageView.getDrawable()).stop();((AnimationDrawable) exploredImageView.getDrawable()).start();

6.在Activity布局中引用相應封裝好的view即可。

<github.chenupt.bezier.BezierView        android:layout_width="match_parent"        android:layout_height="match_parent"        android:background="@android:color/transparent" />


最開始設想的view在類似於紅點範圍的一個控制項,但是這樣實現就達不到拖動到父類控制項的範圍之外,比如拖動紅點超過頁簽布局範圍時,紅點則無法繪製。因此在QQ的訊息列表中是將其設定相應全屏的一個view。背景為的上個背景,這樣在最上一層實則只有紅點的控制項。這樣就能相應地拖動紅點到螢幕的各個位置。所以才會在紅點列表爆照動畫結束之前頁簽是不可點擊,並且拖動紅點的時候列表資料沒有重新整理。

也許是還有更好地實現方式,歡迎大家進行交流。


代碼地址:https://github.com/chenupt/BezierDemo

QQ:753785666

Email:[email protected]


手機QQ5.0紅點拖拽消除的實現

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.