Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Model Center   Code  
»áÔ±   
   
 
     
   
 ¶©ÔÄ
  ¾èÖú
×Ô¶¨ÒåViewÖ®°¸ÁÐÆª£º·ÂQQСºìµã
 
  2213  次浏览      27
 2018-1-15
 
±à¼­ÍƼö:
±¾ÎÄÀ´×ÔÓÚ³ÌÐòÔ±´ó¿§£¬±¾ÎÄÊôÓÚ»ù´¡ÎÄÕ£¬ÏêϸµÄ½éÉÜÁË·ÂÕÕqqСºìµã×ö³öµÄ¸÷ÖÖÀ­ÉìЧ¹ûÖÐÉæ¼°µÄ¼¸¸ö֪ʶµã£¬¶ÔÓÚ³õѧÕß»áÓкܴóµÄ°ïÖú¡£

Ò»Ö±¾õµÃ QQ µÄСºìµã·Ç³£¾ßÓд´Ð£¬ÐÂÓ±¡£ÒªÊÇ×Ô¼ºÒ²ÄÜʵÏÖÀàËÆµÄЧ¹û£¬ÄÇÔõÒ»¸öˬ×ÖÁ˵á£

ÏÈÀ´¿´¿´ËüµÄ×îÖÕЧ¹û£º

Ч¹ûͼ¾ßÓÐÄÄЩЧ¹û£º

1.ÔÚÀ­É췶ΧÄÚµÄÀ­ÉìЧ¹û

2.δÀ­³öÀ­É췶ΧÊͷźóµÄЧ¹û

3.À­³öÀ­É췶ΧÔÙÀ­»ØµÄÊͷźóµÄЧ¹û

4.À­³öÀ­É췶ΧÊͷźóµÄ±¬Õ¨Ð§¹û

Éæ¼°µÄÏà¹ØÖªÊ¶µã£º

1.onLayout ÊÓͼλÖÃ

2.saveLayer ͼ²ãÏà¹ØÖªÊ¶

3.Path µÄ±´Èü¶ûÇúÏß

4.ÊÖÊÆ¼àÌý

5.ValueAnimator ÊôÐÔ¶¯»­

À­ÉìЧ¹û

ÎÒÃÇÏÈÀ´½²½âµÚÒ»¸ö֪ʶµã£¬onLayout ·½·¨£º

·½·¨Ô¤ÀÀ£º

onLayout(boolean changed,
int left,
int top,
int right,
int bottom)

ÎҼǵÃÎÒµÚÒ»´Î½Ó´¥Õâ¸ö·½·¨µÄʱºò¶ÔºóÃæÁ½¸ö²ÎÊýÊÇÀí½â´íÁË£¬»¹¾À½áÁ˺ܾá£ÏÈÀ´¿´¿´Ò»ÕÅʾÒâͼ¾ÍһĿÁËÈ»ÁË£º

ÄÇôÎÒÃÇ¿ÉÒԵóö£º

right = left + view.getWidth();
bottom = top + view.getHeight();

×¢Ò⣺ right ²»ÒªÀí½â³ÉÊÓͼ¿Ø¼þÓұ߾àÀëÆÁÄ»ÓұߵľàÀ룻bottom ²»ÒªÀí½â³ÉÊÓͼ¿Ø¼þµ×²¿¾àÀëÆÁÄ»µ×²¿µÄ¾àÀë¡£

1¡¢ÔÚÆÁÄ»ÖÐÐÄ»æÖÆÐ¡Ô²µã

ÏÈÀ´à±à±Ð§¹ûͼ£¬·Ç³£¼òµ¥£º

public class QQ_RedPoint extends View { private Paint mPaint; //»­±Ê private int mRadius; private PointF mCenterPoint; public QQ_RedPoint(Context context) { this(context, null); } public QQ_RedPoint(Context context, AttributeSet attrs) { this(context, attrs, 0); } public QQ_RedPoint(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.setAntiAlias(true); mPaint.setStyle(Paint.Style.FILL); mRadius = 20; mCenterPoint = new PointF(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); mCenterPoint.x = w / 2; mCenterPoint.y = h / 2; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint); }}

2¡¢Ð¡Ô²µãµÄÀ­ÉìЧ¹û

ÏÈÀ´¿´¿´À­ÉìµÄЧ¹ûͼ£º

ÕâÀï¾ÍÒª½²½âµÚ¶þ¸ö֪ʶµã£¬Path ·¾¶±´Èû¶ûÇúÏß¡£

À­ÉìµÄЧ¹ûͼÓÒÈý²¿·Ö×é³É£º

1.ÖÐÐÄСԲ

2.¸úÊÖÖ¸ÒÆ¶¯µÄСԲ

3.Á½¸öÔ²Ö®¼äʹÓñ´Èû¶ûÇúÏßÌî³ä

ÎÒÃÇ°ÑÆ´½Ó¹ý³Ì·Å´óÀ´¿´¿´£º

ß×£¬Õâ¸öÐÎ×´ºÃÊìϤ°¡£¬Ã÷Ã÷ÎÒÔÚʲôµØ·½¼û¹ý¡£ÔõôԽ¿´Ô½¾õµÃÏñÅ®ÉúÓõÄÒÌÂè½íÄØ£¿Ô­À´£¬QQ ÕâôÓÐÉîÒâ¡£

ÖмäÔ²µÄЧ¹ûÒѾ­ÊµÏÖÁË£¬½Ó×ÅʵÏÖ¸úÊÖÖ¸ÒÆ¶¯µÄСԲЧ¹û£º

ΪÁËʵÏÖÊÖÖ¸´¥ÃþÆÁÄ»¸úËæÊÖÖ¸ÒÆ¶¯µÄСԲЧ¹û£¬ÖØÐ´ onTouchEvent ·½·¨£¨Ê¼þ²»Íù¸¸¿Ø¼þ´«µÝ£©£º

@Override public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN: {
mTouch = true; }
break;
case MotionEvent.ACTION_UP: {
mTouch = false; } }
mCurPoint.set(event.getX(), event.getY());
postInvalidate();
return true; }

×¢Ò⣺onTouchEvent ·½·¨µÄ·µ»ØÖµÎª true£¬ÈôΪ false ²¶»ñ²»µ½ ACTION_DOWN ÒÔºóµÄÊÖָ״̬¡£

½Ó×ÅʵÏÖ±´Èû¶ûÇúÏßÌî³äЧ¹û£¬ÕâÒ²ÊDZ¾ÆªµÄÄѵ㣬ºóÃæµÄʵÏÖ¾ÍÇáËÉ¡£

Ps ¼¼ÊõºÜ²Ë£¬Ï£Íû»æÖƵIJÝͼÄܹ»°ïÖúµ½Äú¡£

´ÓÉÏЧ¹ûͼÖзÖÎö¿ÉµÃ£º

±´Èû¶ûÇúÏß P1P2£¬Æðµã P1£¬¿ØÖƵã C1C2 µÄÖеã Q0£¬½áÊøµã P2

ÄÇôÎÒÃÇËùÐèÒªµÄ¾ÍÊÇÇóµ½ P1 , P2 , Q0 µãµÄ×ø±êϵ£¬Q0 µÄ×ø±êºÜÈÝÒ׵õ½£¬ÄÇôÎÒÃÇÔõôÀ´Çó P1 , P2 ×ø±êÄØ£¿ÏÂÃæÎÒ»­³öÁËÔõôÇó P1 , P2 ×ø±êµÄʾÒâͼ£º

 

¸ù¾ÝʾÒâͼµÃµ½£º

P1x = x0 + r * sina
P1y = y0 - r * cosa

½øÒ»²½ÍƵã¬ÐèÒªÇóµÃ P1 µÄ×ø±ê£¬ÐèÒªÖªµÀ a µÄ½Ç¶È¡£¸ù¾ÝÊýѧ¹«Ê½£º tan(a) = dy / dx ¡£dx£¬dy ΪÁ½Ð¡Ô²ºá×Ý×ø±ê²îÖµ¡£ËùÒÔÍÆµÃ a = arctan(dy / dx) ¡£Í¬Àí¿ÉÒÔÇóµÃ P2 , P3 , P4 ×ø±ê¡£

´úÂëʵÏÖ£º

P1 , P2 , P3 , P4 µÄ×ø±êΪ£º

float x = mCurPoint.x;
float y = mCurPoint.y;
float startX = mCenterPoint.x;
float startY = mCenterPoint.y;
float dx = x - startX;
float dy = y - startY;
double a = Math.atan(dy / dx);
float offsetX = (float) (mRadius * Math.sin(a));
float offsetY = (float) (mRadius * Math.cos(a));

// ¸ù¾Ý½Ç¶È¼ÆËãËıßÐεÄËĸöµã
float p1x = startX + offsetX;
float p1y = startY - offsetY;
float p2x = x + offsetX;
float p2y = y - offsetY;
float p3x = startX - offsetX;
float p3y = startY + offsetY;
float p4x = x - offsetX;
float p4y = y + offsetY;

Á½Ð¡Ô²Ô²ÐÄÁ¬ÏßÖеã Q0 µÄ×ø±ê£¨±¾Èü¶ûÇúÏß¿ØÖƵã×ø±ê£©£º

float controlX = (startX + x) / 2;
float controlY = (startY + y) / 2;

Ч¹ûÖÐ Path µÄ·¾¶ÇøÓòÊǸö·â±ÕµÄÇøÓò£º

mPath.reset();
mPath.moveTo(p1x, p1y);
mPath.quadTo(controlX, controlY, p2x, p2y);
mPath.lineTo(p4x, p4y);
mPath.quadTo(controlX, controlY, p3x, p3y);
mPath.lineTo(p1x, p1y);
mPath.close();·¾¶»æÖÆÍê±Ï£¬ÎÒÃÇÀ´¿´¿´ onDraw ·½·¨µÄ»æÖÆ£º

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.saveLayer(new RectF(0, 0, getWidth(), getHeight()), mPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint);
if (mTouch) {
calculatePath();
canvas.drawCircle(mCurPoint.x, mCurPoint.y, mRadius, mPaint);
canvas.drawPath(mPath, mPaint); }
canvas.restore();
super.dispatchDraw(canvas);//»æ³ö¸Ã¿Ø¼þµÄËùÓÐ×ӿؼþ }

 

×¢Ò⣺ÎÒÃÇÔÚ onTouchEvent ·½·¨ÖУ¬ÎÒÃDz¢Ã»ÓжԶàµã´¥Ãþ½øÐд¦Àí¡£Èç¹ûÄã¸ÐÐËȤ£¬Çë¼ÌÐø¹Ø×¢ÎҵIJ©¿Í¡£

ÔÚ onTouchEvent ·½·¨Öе÷ÓõÄÊÇ postInvalidate() ´ÓлæÖÆ£¬´ÓлæÖÆÓÐÁ½¸ö·½·¨£ºpostInvalidate £¬invadite ¡£

invadite ±ØÐëÔÚ UI Ïß³ÌÖе÷Ó㬶ø postInvalidate ÄÚ²¿ÊÇÓÉHandlerµÄÏûÏ¢»úÖÆÊµÏֵģ¬¿ÉÒÔÔÚÈκÎÏß³ÌÖе÷Óã¬Ð§ÂÊûÓÐ invadite ¸ß ¡£

À­É췶ΧÄÚÊÍ·ÅЧ¹û

ÔÚÀ­É췶ΧÄÚÊÖÖ¸ÊͷźóµÄЧ¹û£º

1.³õʼλÖÃÖ»ÏÔʾ TextView ¿Ø¼þ¡£Ìæ»»µôÁËÒÔǰµÄСԲµã¡£

2.µã»÷ TextView ËùÔÚÇøÓò²ÅÄÜÒÆ¶¯ TextView ¡£

3.Í϶¯ TextView ÇÒÓëÖÐÐÄСԲµãÒÔ±´Èû¶ûÇúÏßÁ¬½ÓÐγɱպϵÄ·¾¶¡£

4.¾àÀëµÄÀ­É죬СԲµÄ°ë¾¶Öð½¥¼õÉÙ¡£

5.À­ÉìÒ»¶¨µÄ·¶Î§ÄÚ£¬ÊÍ·ÅÊÖÖ¸£¬°´×ÅÔ­À´µÄ·¾¶·µ»Ø£¬ÇÒÔ˶¯µ½ÖÐÐĵãÓз´µ¯Ð§¹û¡£

6.ÎÒÃǰ¤×ÅÀ´ÊµÏÖÒÔÉÏЧ¹û¡£

ÏÔʾTextView

µ±Ç°¿Ø¼þ¼Ì³Ð ViewGroup £¬ÎÒÕâÀï¼Ì³ÐµÄÊÇ FrameLayout ¡£ÎÒÃÇÔÚ³õʼ»¯µÄʱºòÌí¼Ó TextView ¿Ø¼þ£º

private void init() { mPaint = new Paint(); mPaint.setColor(Color.RED); mPaint.

setAntiAlias(true); mPaint.setStyle

(Paint.Style.FILL); mRadius = 20;

mCenterPoint = new PointF(); mCurPoint

= new PointF(); mPath = new Path();

mDragTextView = new TextView(getContext()); LayoutParams lp = new LayoutParams(ViewGroup.LayoutParams.

WRAP_CONTENT, ViewGroup.LayoutParams.

WRAP_CONTENT); mDragTextView.setLayout

Params(lp); mDragTextView.setPadding

(10, 10, 10, 10); mDragTextView.set

BackgroundResource

(R.drawable.tv_bg); mDragTextView.

setText("99+"); addView(mDragTextView); }

ÔÚ FrameLayout ÖÐÌí¼ÓÁË mDragTextView ¿Ø¼þ£¬²¢¶Ô mDragTextView ¿Ø¼þ×öÁËһЩ»ù´¡µÄÉèÖ᣶ÔÓ¦µÄ tv_bg ×ÊÔ´Îļþ£º

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.

com/apk/res/android">
<corners android:radius="10dp"/>
<solid android:color="#ff0000"/>
<stroke android:color="#0f000000"

android:width="1dp"/>
</shape>

ÎÒÃÇÖØÐ´ dispatchDraw ·½·¨£¨view ÖØÐ´ onDraw ·½·¨ £¬viewgroup ÖØÐ´ dispatchDraw ·½·¨£©£º

@Override
protected void dispatchDraw(Canvas canvas) {
canvas.saveLayer(new RectF(0, 0, getWidth(), getHeight()), mPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint);
canvas.restore();
super.dispatchDraw(canvas); }

Ч¹ûͼ£º

ÕâÀïÎÒÃÇÐèҪעÒâ super.dispatchDraw(canvas); µÄλÖ㬷ÅÔÚ×îºóÓë·ÅÔÚ×îǰЧ¹ûÊDz»Ò»ÑùµÄ¡£

@Override
protected void dispatchDraw(Canvas canvas) { //....»æÖƲÙ×÷
super.dispatchDraw(canvas);
//»æÖÆ×ÔÉíÈ»ºó»æÖÆ×ÓÔªËØ ¿ÉÒÔÀí½â×ӿؼþ¸²¸ÇÔÚ¸¸¿Ø¼þ»æÖÆÖ®ÉÏ }

Óë

@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
//....»æÖƲÙ×÷ //»æÖÆ×ӿؼþÈ»ºó»æÖÆ×ÔÉí ¿ÉÒÔÀí½â³É¸¸¿Ø¼þ»æÖƸ²¸Ç×ӿؼþµÄ»æÖÆ }

Àý£¬ÎÒÕâÀïµ÷ÕûһϠsuper.dispatchDraw(canvas) µÄλÖãº

@Override
protected void dispatchDraw(Canvas canvas) {
super.dispatchDraw(canvas);
mPaint.setColor(Color.GREEN);//Ö÷ÒªÊÇΪÁËÇø·ÖºìÉ«
canvas.saveLayer(new RectF(0, 0, getWidth(), getHeight()), mPaint, Canvas.ALL_SAVE_FLAG);
canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint);
canvas.restore(); }

Ч¹ûͼ£º

µã»÷TextViewÍ϶¯Ð§¹û

µã»÷ TextView ²ÅÄÜÍ϶¯Îı¾£¬ËµÃ÷Òª´¥Ãþµ½ TextView µÄ¾ØÐÎÇøÓò¡£¿ÉÒÔͨ¹ý£º

int x= (int) event.getX();
int y= (int) event.getY();

if(x>=mDragTextView.getLeft()&&x<

=mDragTextView.getRight()&&y<=mDrag

TextView.getBottom()
&&y>=mDragTextView.getTop()){
mTouch = true; }

Ò²¿ÉÒÔͨ¹ý£º

Rect rect = new Rect();
rect.left = mDragTextView.getLeft();
rect.top = mDragTextView.getTop();
rect.right = mDragTextView.getWidth() + rect.left;
rect.bottom = mDragTextView.getHeight() + rect.top;
if (rect.contains((int) event.getX(), (int) event.getY())) { mTouch = true; }

»ñÈ¡µ½Ëùµã»÷ÇøÓòÔÚ TextView µÄ¾ØÐÎÖ®ÄÚ¡£

»æÖƱ´Èû¶ûÇúÏߣ¬ÐγɱպϵÄ·¾¶

ÎÒÃÇÒѾ­Çó³öÁ˸÷¸öµãµÄ×ø±ê£¬Á¬½ÓÐγɱպϵÄ·¾¶¡£ so easy ¡­

private void calculatePath() {
float x = mCurPoint.x;
float y = mCurPoint.y;
float startX = mCenterPoint.x;
float startY = mCenterPoint.y;
float dx = x - startX;
float dy = y - startY;
double a = Math.atan(dy / dx);
float offsetX = (float) (mRadius * Math.sin(a));
float offsetY = (float) (mRadius * Math.cos(a));

// ¸ù¾Ý½Ç¶È¼ÆËãËıßÐεÄËĸöµã
float p1x = startX + offsetX;
float p1y = startY - offsetY;
float p2x = x + offsetX;
float p2y = y - offsetY;
float p3x = startX - offsetX;
float p3y = startY + offsetY;
float p4x = x - offsetX;
float p4y = y + offsetY;
float controlX = (startX + x) / 2;
float controlY = (startY + y) / 2;
mPath.reset();
mPath.moveTo(p1x, p1y);
mPath.quadTo(controlX, controlY, p2x, p2y);
mPath.lineTo(p4x, p4y);
mPath.quadTo(controlX, controlY, p3x, p3y);
mPath.lineTo(p1x, p1y);
mPath.close(); }

à±à±Ð§¹ûͼ£º

ÔÚÀ­ÉìµÄ¹ý³Ìµ±ÖУ¬Ð¡ÇòµÄ´óСÊÇûÓб仯µÄ¡£

Ô½À­É죬СÇòԽС

ÎÒÃÇ¿ÉÒÔ¸ù¾ÝÀ­ÉìµÄ¾àÀ붯̬¸Ä±äСÇòµÄ°ë¾¶£¬À´´ïµ½Ð¡Çò±äСµÄЧ¹û¡£

1¡¢¼ÆËãÖÐÐÄСÇòÓëÎı¾µÄ¾àÀ루Èý½Çº¯Êý£©£º

float distance = (float) Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));

2¡¢¾àÀëÔ½´ó£¬Ð¡Çò°ë¾¶Ô½Ð¡£º

int radius = DEFAULT_RADIUS - (int) (distance / 18); //18 ¸ù¾ÝÀ­ÉìÇé¿ö
if (radius < 8) { //À­ÉìÒ»¶¨Öµ ¹Ì¶¨µ½×îСֵ radius = 8; }

È»ºó°ÑЧ¹û»æÖƵ½»­²¼ÉÏÃæ£º

protected void dispatchDraw(Canvas canvas) {
canvas.saveLayer(new RectF(0, 0, getWidth(), getHeight()),
mPaint, Canvas.ALL_SAVE_FLAG);
if (mTouch) {
calculatePath();
canvas.drawCircle(mCenterPoint.x, mCenterPoint.y, mRadius, mPaint);
canvas.drawCircle(mCurPoint.x, mCurPoint.y, mRadius, mPaint);
canvas.drawPath(mPath, mPaint);//½«textviewµÄÖÐÐÄ·ÅÔÚµ±Ç°ÊÖָλÖÃ
mDragTextView.setX(mCurPoint.x - mDragTextView.getWidth() / 2);
mDragTextView.setY(mCurPoint.y - mDragTextView.getHeight() / 2);
}else {
mDragTextView.setX(mCenterPoint.x - mDragTextView.getWidth() / 2);
mDragTextView.setY(mCenterPoint.y - mDragTextView.getHeight() / 2);

}
canvas.restore();
super.dispatchDraw(canvas); }

¿´¿´Ð§¹û£º

À­É췶ΧÄÚ£¬ÊÍ·ÅÊÖÖ¸ºóµÄÔ˶¯Ð§¹û

ÊÖÖ¸ÊÍ·Å£¬ÔÚ onTouchEvent·½·¨ MotionEvent.ACTION_UP ÖнøÐд¦Àí¡£

1¡¢Åж¨µ±Ç°ÊÇ·ñÍ϶¯Îı¾£º

if (rect.contains((int) event.getRawX(), (int) event.getRawY())) {
mTouch = true;
mTouchText = true;
} else {
mTouchText = false;
}

2¡¢ÔÚ MotionEvent.ACTION_UP ÖпªÆôÊͷŵ͝»­£º

case MotionEvent.ACTION_UP:
mTouch = false;
if (mTouchText) {
startReleaseAnimator();
}
break;

3¡¢ÊͷŶ¯»­Ð§¹û£º

private Animator getReleaseAnimator() {
final ValueAnimator animator = ValueAnimator.ofFloat(1.0f, 0.0f);
animator.setDuration(500);
animator.setRepeatMode(ValueAnimator.RESTART);
animator.addUpdateListener(new MyAnimatorUpdateListener(this) {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mReleaseValue = (float) animation.getAnimatedValue();
postInvalidate();
}
}
);
animator.setInterpolator(new OvershootInterpolator());
return animator; }

·Ç³£¾­µäµÄÊôÐÔ¶¯»­ÏµÁн²½â¡£

animator.setInterpolator(new OvershootInterpolator()); ÉèÖÃÁ˲åÖµÆ÷£¬OvershootInterpolator Ïòǰ˦һ¶¨ÖµºóÔٻص½Ô­À´Î»Ö㬾ͿÉÒÔʵÏÖ·´µ¯µÄЧ¹û¡£

ͨ¹ý (float) animation.getAnimatedValue() »ñÈ¡¶¯»­Ô˵½µ½Ä³Ò»Ê±¿ÌµÄÊôÐÔÖµ£¬È»ºóˢнçÃæ£º

1¡¢¸ù¾ÝÊôÐÔÖµÀ´¼ÆËãÎı¾µÄλÖãº

Ê×ÏÈ»ñÈ¡Îı¾¾àÀëÖÐÐÄСԲµÄºá×Ý×ø±ê²îÖµ£º

float dx = mCurPoint.x - mCenterPoint.x;
float dy = mCurPoint.y - mCenterPoint.y;

Îı¾µÄλÖãº

float x = mCurPoint.x - dx * (1.0f - mReleaseValue);
float y = mCurPoint.y - dy * (1.0f - mReleaseValue);

dx (1.0f - mReleaseValue) £¬ dy (1.0f - mReleaseValue) ±íʾÔÚ x Öᣬy ÖáÉϵÄÔ˶¯¾àÀ룬¸ù¾Ýµ±Ç°µÄλÖà - Ô˵½µÄ¾àÀë = Îı¾µÄλÖÃ

»ñÈ¡µ½Îı¾µÄλÖÃ×ø±ê£¬ÓÖÖªµÀÖÐÐĵã×ø±ê£¬¸ù¾ÝÉÏÃæµÄ¹«Ê½»æÖƳö±ÕºÏµÄ±´Èû¶ûÇúÏߣ¬¾ÍºÜÈÝÒ×ÁË¡£

2¡¢ÊͷŶ¯»­¹ý³ÌÖУ¬·ÀÖ¹¶à´ÎÍ϶¯Îı¾£º

animator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mMoreDragText = true; }
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mMoreDragText = false;
}
}
);

À­É췶ΧÍâµÄЧ¹û

À­Éìµ½Ò»¶¨·¶Î§Í⣬ȻºóÔÙÀ­»ØÀ´ÊÍ·ÅÊÖÖ¸£¬»á·¢ÏÖÎı¾»Øµ½ÁËÖÐÐIJ¢»Øµ¯Ð§¹û£»À­Éìµ½·¶Î§ÍâÊÍ·ÅÊÖÖ¸£¬»á³öÏÖ±¬Õ¨Ð§¹û¡£

1.À­Éìµ½·¶Î§ÍâÔÙÀ­»ØÊÍ·ÅЧ¹û

2.À­Éìµ½·¶Î§ÍâÊͷű¬Õ¨Ð§¹û

3.À­Éìµ½·¶Î§ÍâÔÙÀ­»ØÊÍ·ÅЧ¹û

Ö»ÒªÓÐÒ»´ÎÀ­Éìµ½·¶Î§Í⣬ÔÙÀ­»ØÀ´ÊÍ·Å£¬¾Í²»»áÔÙ»æÖÆÖÐÐÄСԲÒÔ¼°±´Èû¶ûÇúÏߵıպÏ·¾¶¡£ËùÒÔÕâÀïÐèÒªÒ»¸ö²¼¶ûÖµµÄ±êʶ£¬Ö»ÒªÐ¡Ô²°ë¾¶¼õÉÙµ½Ò»¶¨Öµ¾Í°Ñ±êʶÉèÖÃΪ true

if (mRadius == 8) {
mOnlyOneMoreThan = true;
}

ÔÚ dispatchDraw ·½·¨ÀïÃæ»æÖÆÎı¾µÄλÖãº

mDragTextView.setX(mCenterPoint.x - mDragTextView.getWidth() / 2);
mDragTextView.setY(mCenterPoint.y - mDragTextView.getHeight() / 2);

À­Éìµ½·¶Î§ÍâÊͷű¬Õ¨Ð§¹û

±¬Õ¨Ð§¹û£¬ÊÇÓÃÒ»ÕÅÕÅͼƬʵÏֵġ£ÎÒÃÇÐèÒªÌí¼ÓÒ»¸ö ImageView ¿Ø¼þÀ´µ¥¶À²¥·Å±¬Õ¨µÄͼƬ£¬¾ßÌå²½ÖèÈçÏ£º

1¡¢ÐÂÔöͼƬÊý×飺

private int[] mExplodeImages = new int[]{
R.mipmap.idp,
R.mipmap.idq,
R.mipmap.idr,
R.mipmap.ids,
R.mipmap.idt}; //±¬Õ¨µÄͼƬ¼¯ºÏ

2¡¢ÐÂÔö ImageView ÓÃÓÚ²¥·Å±¬Õ¨Ð§¹û£º

mExplodeImage = new ImageView(getContext());
mExplodeImage.setLayoutParams(lp);
mExplodeImage.setImageResource(R.mipmap.idp);
mExplodeImage.setVisibility(View.INVISIBLE);
addView(mExplodeImage);

3¡¢·¶Î§Í⣬ÊÖÖ¸À뿪£¬²¥·Å±¬Õ¨Ð§¹û£º

ValueAnimator animator = ValueAnimator.

ofInt(0, mExplodeImages.length - 1);
animator.setInterpolator(new LinearIn

terpolator());
animator.setDuration(1000);
animator.addUpdateListener(new MyAnimatorUpdateListener(this) {
@Override
public void onAnimationUpdate(Value

Animator animation) {
mExplodeImage.setBackgroundResource

(mExplodeImages[(int) animation.

getAnimatedValue()]);
}
}
);
return animator;
}

mExplodeImage µÄλÖÃÓ¦¸ÃÊÇÊÖÖ¸À뿪µÄλÖãº

private void layoutExplodeImage() {
mExplodeImage.setX(mCurPoint.x - mDragTextView.getWidth() / 2);
mExplodeImage.setY(mCurPoint.y - mDragTextView.getHeight() / 2); }

   
2213 ´Îä¯ÀÀ       27
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì