精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Android自定義控件:類QQ未讀消息拖拽效果

移動開發(fā) Android
QQ的未讀消息,算是一個比較好玩的效果,趁著最近時間比較多,參考了網(wǎng)上的一些資料之后,本次實現(xiàn)一個仿照QQ未讀消息的拖拽小紅點。

QQ的未讀消息,算是一個比較好玩的效果,趁著最近時間比較多,參考了網(wǎng)上的一些資料之后,本次實現(xiàn)一個仿照QQ未讀消息的拖拽小紅點:

首先我們從最基本的原理開始分析,看一張圖:

 

這個圖該怎么繪制呢?實際上我們這里是先繪制兩個圓,然后將兩個圓的切點通過貝塞爾曲線連接起來就達到這個效果了。至于貝塞爾曲線的概念,這里就不多做解釋了,百度一下就知道了。

 

切點怎么算呢,這里我們稍微復(fù)習(xí)一些初中的數(shù)學(xué)知識。看了這個圖之后,求出四個切點應(yīng)該是輕而易舉了。

 

現(xiàn)在思路已經(jīng)很清晰了,按照我們的思路,開擼。

首先是我們計算切點以及各坐標點的工具類

  1. public class GeometryUtils { 
  2.     /** 
  3.      * As meaning of method name
  4.      * 獲得兩點之間的距離 
  5.      * @param p0 
  6.      * @param p1 
  7.      * @return 
  8.      */ 
  9.     public static float getDistanceBetween2Points(PointF p0, PointF p1) { 
  10.         float distance = (float) Math.sqrt(Math.pow(p0.y - p1.y, 2) + Math.pow(p0.x - p1.x, 2)); 
  11.         return distance; 
  12.     } 
  13.  
  14.     /** 
  15.      * Get middle point between p1 and p2. 
  16.      * 獲得兩點連線的中點 
  17.      * @param p1 
  18.      * @param p2 
  19.      * @return 
  20.      */ 
  21.     public static PointF getMiddlePoint(PointF p1, PointF p2) { 
  22.         return new PointF((p1.x + p2.x) / 2.0f, (p1.y + p2.y) / 2.0f); 
  23.     } 
  24.  
  25.     /** 
  26.      * Get point between p1 and p2 by percent. 
  27.      * 根據(jù)百分比獲取兩點之間的某個點坐標 
  28.      * @param p1 
  29.      * @param p2 
  30.      * @param percent 
  31.      * @return 
  32.      */ 
  33.     public static PointF getPointByPercent(PointF p1, PointF p2, float percent) { 
  34.         return new PointF(evaluateValue(percent, p1.x , p2.x), evaluateValue(percent, p1.y , p2.y)); 
  35.     } 
  36.  
  37.     /** 
  38.      * 根據(jù)分度值,計算從start到end中,fraction位置的值。fraction范圍為0 -> 1 
  39.      * @param fraction 
  40.      * @param start 
  41.      * @param end 
  42.      * @return 
  43.      */ 
  44.     public static float evaluateValue(float fraction, Number start, Number end){ 
  45.         return start.floatValue() + (end.floatValue() - start.floatValue()) * fraction; 
  46.     } 
  47.  
  48.     /** 
  49.      * Get the point of intersection between circle and line. 
  50.      * 獲取 通過指定圓心,斜率為lineK的直線與圓的交點。 
  51.      * 
  52.      * @param pMiddle The circle center point. 
  53.      * @param radius The circle radius. 
  54.      * @param lineK The slope of line which cross the pMiddle. 
  55.      * @return 
  56.      */ 
  57.     public static PointF[] getIntersectionPoints(PointF pMiddle, float radius, Double lineK) { 
  58.         PointF[] points = new PointF[2]; 
  59.  
  60.         float radian, xOffset = 0, yOffset = 0; 
  61.         if(lineK != null){ 
  62.             radian= (float) Math.atan(lineK); 
  63.             xOffset = (float) (Math.sin(radian) * radius); 
  64.             yOffset = (float) (Math.cos(radian) * radius); 
  65.         }else { 
  66.             xOffset = radius; 
  67.             yOffset = 0; 
  68.         } 
  69.         points[0] = new PointF(pMiddle.x + xOffset, pMiddle.y - yOffset); 
  70.         points[1] = new PointF(pMiddle.x - xOffset, pMiddle.y + yOffset); 
  71.  
  72.         return points; 
  73.     } 
  74.  

然后下面看下我們的核心繪制代碼,代碼注釋比較全,此處就不多做解釋了。

  1. /** 
  2.      * 繪制貝塞爾曲線部分以及固定圓 
  3.      * 
  4.      * @param canvas 
  5.      */ 
  6.     private void drawGooPath(Canvas canvas) { 
  7.         Path path = new Path(); 
  8.         //1. 根據(jù)當前兩圓圓心的距離計算出固定圓的半徑 
  9.         float distance = (float) GeometryUtils.getDistanceBetween2Points(mDragCenter, mStickCenter); 
  10.         stickCircleTempRadius = getCurrentRadius(distance); 
  11.  
  12.         //2. 計算出經(jīng)過兩圓圓心連線的垂線的dragLineK(對邊比臨邊)。求出四個交點坐標 
  13.         float xDiff = mStickCenter.x - mDragCenter.x; 
  14.         Double dragLineK = null
  15.         if (xDiff != 0) { 
  16.             dragLineK = (double) ((mStickCenter.y - mDragCenter.y) / xDiff); 
  17.         } 
  18.  
  19.         //分別獲得經(jīng)過兩圓圓心連線的垂線與圓的交點(兩條垂線平行,所以dragLineK相等)。 
  20.         PointF[] dragPoints = GeometryUtils.getIntersectionPoints(mDragCenter, dragCircleRadius, dragLineK); 
  21.         PointF[] stickPoints = GeometryUtils.getIntersectionPoints(mStickCenter, stickCircleTempRadius, dragLineK); 
  22.  
  23.         //3. 以兩圓連線的0.618處作為 貝塞爾曲線 的控制點。(選一個中間點附近的控制點) 
  24.         PointF pointByPercent = GeometryUtils.getPointByPercent(mDragCenter, mStickCenter, 0.618f); 
  25.  
  26.         // 繪制兩圓連接閉合 
  27.         path.moveTo((float) stickPoints[0].x, (float) stickPoints[0].y); 
  28.         path.quadTo((float) pointByPercent.x, (float) pointByPercent.y, 
  29.                 (float) dragPoints[0].x, (float) dragPoints[0].y); 
  30.         path.lineTo((float) dragPoints[1].x, (float) dragPoints[1].y); 
  31.         path.quadTo((float) pointByPercent.x, (float) pointByPercent.y, 
  32.                 (float) stickPoints[1].x, (float) stickPoints[1].y); 
  33.         canvas.drawPath(path, mPaintRed); 
  34.         // 畫固定圓 
  35.         canvas.drawCircle(mStickCenter.x, mStickCenter.y, stickCircleTempRadius, mPaintRed); 
  36.     }  

此時我們已經(jīng)實現(xiàn)了繪制的核心代碼,然后我們加上touch事件的監(jiān)聽,達到動態(tài)的更新dragPoint的中心點位置以及stickPoint半徑的效果。當手抬起的時候,添加一個屬性動畫,達到回彈的效果。

  1. @Override 
  2.     public boolean onTouchEvent(MotionEvent event) { 
  3.         switch (MotionEventCompat.getActionMasked(event)) { 
  4.             case MotionEvent.ACTION_DOWN: { 
  5.                 isOutOfRange = false
  6.                 updateDragPointCenter(event.getRawX(), event.getRawY()); 
  7.                 break; 
  8.             } 
  9.             case MotionEvent.ACTION_MOVE: { 
  10.                 //如果兩圓間距大于***距離mMaxDistance,執(zhí)行拖拽結(jié)束動畫 
  11.                 PointF p0 = new PointF(mDragCenter.x, mDragCenter.y); 
  12.                 PointF p1 = new PointF(mStickCenter.x, mStickCenter.y); 
  13.                 if (GeometryUtils.getDistanceBetween2Points(p0, p1) > mMaxDistance) { 
  14.                     isOutOfRange = true
  15.                     updateDragPointCenter(event.getRawX(), event.getRawY()); 
  16.                     return false
  17.                 } 
  18.                 updateDragPointCenter(event.getRawX(), event.getRawY()); 
  19.                 break; 
  20.             } 
  21.             case MotionEvent.ACTION_UP: { 
  22.                 handleActionUp(); 
  23.                 break; 
  24.             } 
  25.             default: { 
  26.                 isOutOfRange = false
  27.                 break; 
  28.             } 
  29.         } 
  30.         return true
  31.     } 
  32.  
  33.     /** 
  34.      * 手勢抬起動作 
  35.      */ 
  36.     private void handleActionUp() { 
  37.         if (isOutOfRange) { 
  38.             // 當拖動dragPoint范圍已經(jīng)超出mMaxDistance,然后又將dragPoint拖回mResetDistance范圍內(nèi)時 
  39.             if (GeometryUtils.getDistanceBetween2Points(mDragCenter, mStickCenter) < mResetDistance) { 
  40.                 //reset 
  41.                 return
  42.             } 
  43.             // dispappear 
  44.         } else { 
  45.             //手指抬起時,彈回動畫 
  46.             mAnim = ValueAnimator.ofFloat(1.0f); 
  47.             mAnim.setInterpolator(new OvershootInterpolator(5.0f)); 
  48.  
  49.             final PointF startPoint = new PointF(mDragCenter.x, mDragCenter.y); 
  50.             final PointF endPoint = new PointF(mStickCenter.x, mStickCenter.y); 
  51.             mAnim.addUpdateListener(new AnimatorUpdateListener() { 
  52.                 @Override 
  53.                 public void onAnimationUpdate(ValueAnimator animation) { 
  54.                     float fraction = animation.getAnimatedFraction(); 
  55.                     PointF pointByPercent = GeometryUtils.getPointByPercent(startPoint, endPoint, fraction); 
  56.                     updateDragPointCenter((float) pointByPercent.x, (float) pointByPercent.y); 
  57.                 } 
  58.             }); 
  59.             mAnim.addListener(new AnimatorListenerAdapter() { 
  60.                 @Override 
  61.                 public void onAnimationEnd(Animator animation) { 
  62.                     //reset 
  63.                 } 
  64.             }); 
  65.  
  66.             if (GeometryUtils.getDistanceBetween2Points(startPoint, endPoint) < 10) { 
  67.                 mAnim.setDuration(100); 
  68.             } else { 
  69.                 mAnim.setDuration(300); 
  70.             } 
  71.             mAnim.start(); 
  72.         } 
  73.     }  

此時我們拖拽的核心代碼基本都已經(jīng)完成,實際效果如下:

 

現(xiàn)在小紅點的繪制基本告一段落,我們不得不去思考真正的難點。那就是如何將我們前面的這個GooView應(yīng)用到實際呢?看實際效果我們的小紅點是放在listView里面的,如果是這樣的話,就代表我們的GooView的拖拽范圍是肯定無法超過父控件item的區(qū)域的。

那么我們要如何實現(xiàn)小紅點可以隨便的在整個屏幕拖拽呢?我們這里稍微整理一下思路。

1.先在listView的item布局中先放入一個小紅點。

2.當我們touch到這個小紅點的時候,隱藏這個小紅點,然后根據(jù)我們布局中小紅點的位置初始化一個GooView并且添加到WindowManager中嗎,達到GooView可以全屏拖動的效果。

3.在添加GooView到WindowManager中的時候,記錄初始小紅點stickPoint的位置,然后根據(jù)stickPoint和dragPointde位置是否超出我們的消失界限來判斷接下來的邏輯。

4.根據(jù)GooView的最終狀態(tài),顯示回彈或者消失動畫。

思路有了,那么就上代碼,根據(jù)***步,我們完成listView的item布局。

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
  3.                 android:layout_width="match_parent" 
  4.                 android:layout_height="80dp" 
  5.                 android:minHeight="80dp"
  6.  
  7.     <ImageView 
  8.         android:id="@+id/iv_head" 
  9.         android:layout_width="50dp" 
  10.         android:layout_height="50dp" 
  11.         android:layout_centerVertical="true" 
  12.         android:layout_marginLeft="20dp" 
  13.         android:src="@mipmap/head"/> 
  14.  
  15.     <TextView 
  16.         android:id="@+id/tv_content" 
  17.         android:layout_width="wrap_content" 
  18.         android:layout_height="50dp" 
  19.         android:layout_centerVertical="true" 
  20.         android:gravity="center" 
  21.         android:layout_marginLeft="20dp" 
  22.         android:layout_toRightOf="@+id/iv_head" 
  23.         android:text="content - " 
  24.         android:textSize="25sp"/> 
  25.  
  26.     <LinearLayout 
  27.         android:id="@+id/ll_point" 
  28.         android:layout_width="80dp" 
  29.         android:layout_height="80dp" 
  30.         android:layout_alignParentEnd="true" 
  31.         android:layout_alignParentRight="true" 
  32.         android:layout_alignParentTop="true" 
  33.         android:gravity="center"
  34.  
  35.         <TextView 
  36.             android:id="@+id/point" 
  37.             android:layout_width="wrap_content" 
  38.             android:layout_height="18dp" 
  39.             android:background="@drawable/red_bg" 
  40.             android:gravity="center" 
  41.             android:singleLine="true" 
  42.             android:textColor="@android:color/white" 
  43.             android:textSize="12sp"/> 
  44.     </LinearLayout> 
  45. </RelativeLayout>  

效果如下,要注意的是,對比QQ的真實體驗,小紅點周邊范圍點擊的時候,都是可以直接拖拽小紅點的。考慮到紅點的點擊范圍比較小,所以給紅點增加了一個寬高80dp的父layout,然后我們將touch小紅點事件更改為touch小紅點父layout,這樣只要我們點擊了小紅點的父layout范圍,都會添加GooView到WindowManager中。 

 

接下來第二步,我們完成添加GooView到WindowManager中的代碼。

由于我們的GooView初始添加是從listViewItem中紅點的touch事件開始的,所以我們先完成listView adapter的實現(xiàn)。

  1. public class GooViewAapter extends BaseAdapter { 
  2.     private Context mContext; 
  3.     //記錄已經(jīng)remove的position 
  4.     private HashSet<Integer> mRemoved = new HashSet<Integer>(); 
  5.     private List<String> list = new ArrayList<String>(); 
  6.  
  7.     public GooViewAapter(Context mContext, List<String> list) { 
  8.         super(); 
  9.         this.mContext = mContext; 
  10.         this.list = list; 
  11.     } 
  12.  
  13.     @Override 
  14.     public int getCount() { 
  15.         return list.size(); 
  16.     } 
  17.  
  18.     @Override 
  19.     public Object getItem(int position) { 
  20.         return list.get(position); 
  21.     } 
  22.  
  23.     @Override 
  24.     public long getItemId(int position) { 
  25.         return position; 
  26.     } 
  27.  
  28.     @Override 
  29.     public View getView(final int position, View convertView, ViewGroup parent) { 
  30.         if (convertView == null) { 
  31.             convertView = View.inflate(mContext, R.layout.list_item_goo, null); 
  32.         } 
  33.         ViewHolder holder = ViewHolder.getHolder(convertView); 
  34.         holder.mContent.setText(list.get(position)); 
  35.         //item固定小紅點layout 
  36.         LinearLayout pointLayout = holder.mPointLayout; 
  37.         //item固定小紅點 
  38.         final TextView point = holder.mPoint; 
  39.  
  40.         boolean visiable = !mRemoved.contains(position); 
  41.         pointLayout.setVisibility(visiable ? View.VISIBLE : View.GONE); 
  42.         if (visiable) { 
  43.             point.setText(String.valueOf(position)); 
  44.             pointLayout.setTag(position); 
  45.             GooViewListener mGooListener = new GooViewListener(mContext, pointLayout) { 
  46.                 @Override 
  47.                 public void onDisappear(PointF mDragCenter) { 
  48.                     super.onDisappear(mDragCenter); 
  49.                     mRemoved.add(position); 
  50.                     notifyDataSetChanged(); 
  51.                     Utils.showToast(mContext, "position " + position + " disappear."); 
  52.                 } 
  53.  
  54.                 @Override 
  55.                 public void onReset(boolean isOutOfRange) { 
  56.                     super.onReset(isOutOfRange); 
  57.                     notifyDataSetChanged();//刷新ListView 
  58.                     Utils.showToast(mContext, "position " + position + " reset."); 
  59.                 } 
  60.             }; 
  61.             //在point父布局內(nèi)的觸碰事件都進行監(jiān)聽 
  62.             pointLayout.setOnTouchListener(mGooListener); 
  63.         } 
  64.         return convertView; 
  65.     } 
  66.  
  67.     static class ViewHolder { 
  68.  
  69.         public ImageView mImage; 
  70.         public TextView mPoint; 
  71.         public LinearLayout mPointLayout; 
  72.         public TextView mContent; 
  73.  
  74.         public ViewHolder(View convertView) { 
  75.             mImage = (ImageView) convertView.findViewById(R.id.iv_head); 
  76.             mPoint = (TextView) convertView.findViewById(R.id.point); 
  77.             mPointLayout = (LinearLayout) convertView.findViewById(R.id.ll_point); 
  78.             mContent = (TextView) convertView.findViewById(R.id.tv_content); 
  79.         } 
  80.  
  81.         public static ViewHolder getHolder(View convertView) { 
  82.             ViewHolder holder = (ViewHolder) convertView.getTag(); 
  83.             if (holder == null) { 
  84.                 holder = new ViewHolder(convertView); 
  85.                 convertView.setTag(holder); 
  86.             } 
  87.             return holder; 
  88.         } 
  89.     } 
  90.  

由于listview需要知道GooView的狀態(tài),所以我們在GooView中增加一個接口,用于listView回調(diào)處理后續(xù)的邏輯。

  1. interface OnDisappearListener { 
  2.         /** 
  3.          * GooView Disapper 
  4.          * 
  5.          * @param mDragCenter 
  6.          */ 
  7.         void onDisappear(PointF mDragCenter); 
  8.  
  9.         /** 
  10.          * GooView onReset 
  11.          * 
  12.          * @param isOutOfRange 
  13.          */ 
  14.         void onReset(boolean isOutOfRange); 
  15.       }  

新建一個實現(xiàn)了OnTouchListener以及OnDisappearListener 方法的的類,***將這個實現(xiàn)類設(shè)置給item中的紅點Layout。

  1. public class GooViewListener implements OnTouchListener, OnDisappearListener { 
  2.  
  3.     private WindowManager mWm; 
  4.     private WindowManager.LayoutParams mParams; 
  5.     private GooView mGooView; 
  6.     private View pointLayout; 
  7.     private int number; 
  8.     private final Context mContext; 
  9.  
  10.     private Handler mHandler; 
  11.  
  12.     public GooViewListener(Context mContext, View pointLayout) { 
  13.         this.mContext = mContext; 
  14.         this.pointLayout = pointLayout; 
  15.         this.number = (Integer) pointLayout.getTag(); 
  16.  
  17.         mGooView = new GooView(mContext); 
  18.  
  19.         mWm = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); 
  20.         mParams = new WindowManager.LayoutParams(); 
  21.         mParams.format = PixelFormat.TRANSLUCENT;//使窗口支持透明度 
  22.         mHandler = new Handler(mContext.getMainLooper()); 
  23.     } 
  24.  
  25.     @Override 
  26.     public boolean onTouch(View v, MotionEvent event) { 
  27.         int action = MotionEventCompat.getActionMasked(event); 
  28.         // 當按下時,將自定義View添加到WindowManager中 
  29.         if (action == MotionEvent.ACTION_DOWN) { 
  30.             ViewParent parent = v.getParent(); 
  31.             // 請求其父級View不攔截Touch事件 
  32.             parent.requestDisallowInterceptTouchEvent(true); 
  33.  
  34.             int[] points = new int[2]; 
  35.             //獲取pointLayout在屏幕中的位置(layout的左上角坐標) 
  36.             pointLayout.getLocationInWindow(points); 
  37.             //獲取初始小紅點中心坐標 
  38.             int x = points[0] + pointLayout.getWidth() / 2; 
  39.             int y = points[1] + pointLayout.getHeight() / 2; 
  40.             // 初始化當前點擊的item的信息,數(shù)字及坐標 
  41.             mGooView.setStatusBarHeight(Utils.getStatusBarHeight(v)); 
  42.             mGooView.setNumber(number); 
  43.             mGooView.initCenter(x, y); 
  44.             //設(shè)置當前GooView消失監(jiān)聽 
  45.             mGooView.setOnDisappearListener(this); 
  46.             // 添加當前GooView到WindowManager 
  47.             mWm.addView(mGooView, mParams); 
  48.             pointLayout.setVisibility(View.INVISIBLE); 
  49.         } 
  50.         // 將所有touch事件轉(zhuǎn)交給GooView處理 
  51.         mGooView.onTouchEvent(event); 
  52.         return true
  53.     } 
  54.  
  55.     @Override 
  56.     public void onDisappear(PointF mDragCenter) { 
  57.         //disappear 下一步完成 
  58.     } 
  59.  
  60.     @Override 
  61.     public void onReset(boolean isOutOfRange) { 
  62.         // 當dragPoint彈回時,去除該View,等下次ACTION_DOWN的時候再添加 
  63.         if (mWm != null && mGooView.getParent() != null) { 
  64.             mWm.removeView(mGooView); 
  65.         } 
  66.     } 
  67.  

這樣下來,我們基本上完成了大部分功能,現(xiàn)在還差***一步,就是GooView超出范圍消失后的處理,這里我們用一個幀動畫來完成爆炸效果。

  1. public class BubbleLayout extends FrameLayout { 
  2.     Context context; 
  3.  
  4.     public BubbleLayout(Context context) { 
  5.         super(context); 
  6.         this.context = context; 
  7.     } 
  8.  
  9.     private int mCenterX, mCenterY; 
  10.  
  11.     public void setCenter(int x, int y) { 
  12.         mCenterX = x; 
  13.         mCenterY = y; 
  14.         requestLayout(); 
  15.     } 
  16.  
  17.     @Override 
  18.     protected void onLayout(boolean changed, int leftint topint right
  19.                             int bottom) { 
  20.         View child = getChildAt(0); 
  21.         // 設(shè)置View到指定位置 
  22.         if (child != null && child.getVisibility() != GONE) { 
  23.             final int width = child.getMeasuredWidth(); 
  24.             final int height = child.getMeasuredHeight(); 
  25.             child.layout((int) (mCenterX - width / 2.0f), (int) (mCenterY - height / 2.0f) 
  26.                     , (int) (mCenterX + width / 2.0f), (int) (mCenterY + height / 2.0f)); 
  27.         } 
  28.     } 
  29.  
  30. @Override 
  31.     public void onDisappear(PointF mDragCenter) { 
  32.         if (mWm != null && mGooView.getParent() != null) { 
  33.             mWm.removeView(mGooView); 
  34.  
  35.             //播放氣泡爆炸動畫 
  36.             ImageView imageView = new ImageView(mContext); 
  37.             imageView.setImageResource(R.drawable.anim_bubble_pop); 
  38.             AnimationDrawable mAnimDrawable = (AnimationDrawable) imageView 
  39.                     .getDrawable(); 
  40.  
  41.             final BubbleLayout bubbleLayout = new BubbleLayout(mContext); 
  42.             bubbleLayout.setCenter((int) mDragCenter.x, (int) mDragCenter.y - Utils.getStatusBarHeight(mGooView)); 
  43.  
  44.             bubbleLayout.addView(imageView, new FrameLayout.LayoutParams( 
  45.                     android.widget.FrameLayout.LayoutParams.WRAP_CONTENT, 
  46.                     android.widget.FrameLayout.LayoutParams.WRAP_CONTENT)); 
  47.  
  48.             mWm.addView(bubbleLayout, mParams); 
  49.  
  50.             mAnimDrawable.start(); 
  51.  
  52.             // 播放結(jié)束后,刪除該bubbleLayout 
  53.             mHandler.postDelayed(new Runnable() { 
  54.                 @Override 
  55.                 public void run() { 
  56.                     mWm.removeView(bubbleLayout); 
  57.                 } 
  58.             }, 501); 
  59.         } 
  60.     }  

***附上完整demo地址:https://github.com/Horrarndoo/GooView 

責(zé)任編輯:龐桂玉 來源: Android開發(fā)中文站
相關(guān)推薦

2015-09-07 10:57:38

qq未讀消息

2011-06-20 16:03:03

Qt 控件 鼠標

2011-07-05 18:51:51

QT 控件 鼠標

2015-02-11 17:49:35

Android源碼自定義控件

2013-04-19 10:14:24

2009-06-08 20:13:36

Eclipse自定義控

2014-09-24 11:42:46

AndroidButton

2015-01-22 15:59:07

Android源碼日期時間控件SelectTime

2017-02-17 09:37:12

Android自定義控件方法總結(jié)

2013-01-06 10:43:54

Android開發(fā)View特效

2013-03-28 10:58:30

自定義Android界android

2011-12-16 14:23:51

Java

2016-11-16 21:55:55

源碼分析自定義view androi

2009-08-03 13:34:06

自定義C#控件

2009-08-03 13:39:46

C#自定義用戶控件

2016-12-26 15:25:59

Android自定義View

2009-09-03 13:34:03

.NET自定義控件

2022-06-30 14:02:07

鴻蒙開發(fā)消息彈窗組件

2010-08-03 16:13:01

FlexBuilder

2009-07-28 09:32:41

ASP.NET自定義控
點贊
收藏

51CTO技術(shù)棧公眾號

日韩午夜小视频| 成人av网站在线| 久久精品在线播放| 国产黄色一区二区三区| 欧美伦理91| 国产精品久久久久久久久快鸭| 亚洲va久久久噜噜噜久久天堂| 日本少妇xxxx动漫| 日韩欧美视频专区| 亚洲精品国精品久久99热| 亚洲不卡视频在线| 国产盗摄一区二区| 国产精品理论在线观看| 国产私拍一区| 国产三级精品在线观看| 国产欧美日韩一级| 国产成人av电影在线观看| 久久的精品视频| 中文字幕一区二区久久人妻网站| 国产精品99| 午夜国产精品一区| 免费在线精品视频| 国产在线一在线二| 处破女av一区二区| 成人a视频在线观看| 成人毛片在线播放| 亚洲小说欧美另类婷婷| www.亚洲一区| 日本美女bbw| 亚洲精品一级二级三级| 欧美mv日韩mv| 亚洲欧美日韩中文字幕在线观看| 欧美日韩尤物久久| 欧美性黄网官网| 国产玉足脚交久久欧美| 91三级在线| 自拍偷拍国产亚洲| 一区精品在线| 日本最黄一级片免费在线| 久久久综合精品| 精品国产一区二区三区麻豆小说 | 日韩视频 中文字幕| 成人精品福利| 国产欧美在线观看一区| 欧美日本韩国国产| 无码国产精品96久久久久| 国产成人综合视频| 91大片在线观看| 国产高清第一页| 国产一区二区三区在线观看免费视频| 国产日韩欧美影视| 亚洲专区第一页| 免费国产亚洲视频| 国产精品美女久久| 涩涩视频在线观看| 秋霞午夜鲁丝一区二区老狼| 国产精品扒开腿做爽爽爽的视频| 夜夜爽妓女8888视频免费观看| 欧美中文字幕| 国产精品成人免费电影| 波多野结衣日韩| 免费av网站大全久久| 国产日韩欧美在线观看| 一区二区三区亚洲视频| 国产主播一区二区| 91久久久一线二线三线品牌| 精品久久在线观看| youjizz国产精品| 免费不卡亚洲欧美| 91激情在线| 亚洲日本在线a| 日韩a级黄色片| av资源在线| 色综合久久久久综合| 9久久婷婷国产综合精品性色 | 香蕉成人app免费看片| 亚洲在线免费播放| 超碰网在线观看| 色999久久久精品人人澡69| 在线成人av网站| 蜜臀av粉嫩av懂色av| 国产精品欧美三级在线观看| 精品国产一区二区在线| 久久免费看少妇高潮v片特黄| 午夜国产精品视频| 欧美重口另类videos人妖| 日韩av免费播放| 国产成人av影院| 日本不卡高清视频一区| 成人影院在线看| 亚洲成人av一区二区三区| 亚洲精品高清无码视频| 国产精品毛片无码| 日韩h在线观看| 免费在线观看黄色小视频| 亚洲国产一区二区精品专区| 国产成人亚洲综合91| 精品国产乱码久久久久久蜜臀网站| 99r国产精品| 99亚洲精品视频| 中文字幕在线官网| 欧美一级夜夜爽| 久久精品国产亚洲av久| 亚洲欧美综合| 国产男人精品视频| 日本高清视频免费看| 亚洲国产精品99久久久久久久久| 日本大片免费看| 日本h片久久| 亚洲成人教育av| 一级片一级片一级片| 欧美专区18| 国产日韩精品久久| 成人影院在线观看| 欧美性色综合网| 免费看污片网站| 在线不卡欧美| 7777精品久久久大香线蕉小说| 屁屁影院ccyy国产第一页| 中文字幕第一页在线视频| 精品视频一区二区三区在线观看| 亚洲精品资源在线| 日韩欧美中文字幕视频| 日韩国产在线一| 精品欧美日韩| 黑人玩欧美人三根一起进| 欧美日韩免费一区二区三区 | 福利视频亚洲| 亚洲精品资源在线| 国产精品6666| 国产mv日韩mv欧美| 亚洲第一页在线视频| 日韩网站中文字幕| 亚洲剧情一区二区| 日韩成人在线免费视频| 国产精品一区二区久久不卡 | 欧美天天在线| 99久久久久国产精品免费| 免费不卡视频| 欧美美女直播网站| 特黄一区二区三区| 久久精品国产99| 一区二区三区观看| 视频欧美精品| y97精品国产97久久久久久| 中文字幕乱码人妻无码久久| 国产嫩草影院久久久久| 中文字幕欧美人妻精品一区| 国产成人久久| 国产精品久久999| 97视频精彩视频在线观看| 欧美在线影院一区二区| 免费黄在线观看| 全国精品久久少妇| 亚洲一区二区三区精品在线观看| 91亚洲精品| 久久香蕉国产线看观看网| 国产jzjzjz丝袜老师水多| 亚洲精品五月天| av av在线| 亚洲美女91| 久久综合狠狠综合久久综青草| 亚洲免费福利| 在线成人激情视频| 91亚洲欧美激情| 亚洲精品第一国产综合野| 91超薄肉色丝袜交足高跟凉鞋| 亚洲第一黄色| 欧美一区少妇| 国产精品蜜月aⅴ在线| 久久视频在线播放| wwwav在线播放| 婷婷国产在线综合| 中文字幕在线观看免费高清| 老司机免费视频一区二区| 国产系列第一页| 国产乱人伦精品一区| 欧美一级电影久久| 日本蜜桃在线观看| 精品国产三级电影在线观看| 久久国产视频一区| 中文字幕亚洲电影| 国产精品熟妇一区二区三区四区| 国产一区二区三区的电影 | 欧美日本高清| 精品国产区一区| 乱子伦一区二区三区| 亚洲天堂网中文字| 欧美深性狂猛ⅹxxx深喉| 免费一级片91| 久久国产精品视频在线观看| 精品国产一区探花在线观看| 国产精品香蕉国产| 国产深夜视频在线观看| 在线播放日韩av| 污视频软件在线观看| 欧美日韩国产综合一区二区三区| 久久婷婷综合国产| 中文字幕 久热精品 视频在线| 日本少妇一级片| 日本欧美韩国一区三区| 妞干网视频在线观看| 精品视频免费| 精品一区二区三区免费毛片| 四虎国产精品永久在线国在线| 97视频在线播放| av网址在线免费观看| 亚洲欧美在线免费观看| 亚洲AV无码精品国产| 欧美亚洲综合网| av资源免费观看| 一区二区三区欧美亚洲| 美国精品一区二区| 91老司机福利 在线| 一区二区在线免费观看视频| 麻豆成人91精品二区三区| 免费成人在线视频网站| 欧美理论在线| 老司机av福利| 91综合网人人| 亚洲成色www久久网站| 性欧美xxxx免费岛国不卡电影| 亚洲在线www| 日韩av懂色| 国产精品成久久久久三级| 欧美久久天堂| 97人洗澡人人免费公开视频碰碰碰| 18av在线视频| 插插插亚洲综合网| 黄色免费在线看| 日韩在线观看网址| 国产一级免费在线观看| 精品亚洲一区二区| 少妇性bbb搡bbb爽爽爽欧美| 亚洲第一精品福利| 国精品人妻无码一区二区三区喝尿 | 成人免费一区| 国产成人精品电影久久久| 2022成人影院| 欧美专区在线观看| 亚洲欧洲高清| 国产不卡精品视男人的天堂| 亚洲风情在线资源| 日本久久久久久| 日日av拍夜夜添久久免费| 欧美在线www| 欧美艳星kaydenkross| 日本视频久久久| 91精品xxx在线观看| 国产不卡一区二区在线播放| 偷拍中文亚洲欧美动漫| 日韩av大片免费看| 黄色精品视频| 国产一区深夜福利| 成人在线精品| 国产精品免费一区二区三区四区| 国产精品jk白丝蜜臀av小说| 久久久精品国产一区二区三区| 日韩精品免费一区二区夜夜嗨 | 亚洲 欧美综合在线网络| 精品一区免费观看| 欧美日韩国产页| 国产免费a视频| 欧美午夜一区二区| 国产美女精品视频国产| 日韩精品专区在线影院观看| 天堂av2024| 一区二区三区视频免费在线观看| 色视频在线免费观看| 精品中文字幕在线2019| 国产在线88av| 国产精品女人久久久久久| 国产成人免费视频网站视频社区| 国产成人一区二区三区免费看| 欧美黑人巨大videos精品| 日韩高清国产精品| 欧美一区国产在线| 国产在线精品91| 奇米四色…亚洲| 深夜福利网站在线观看| va亚洲va日韩不卡在线观看| 亚洲性猛交xxxx乱大交| 亚洲精品视频一区| 91精品国产高清一区二区三密臀| 欧美三级视频在线观看| www.四虎在线观看| 亚洲欧洲第一视频| aa在线视频| 国产成人精品一区| 视频一区视频二区欧美| 日本欧洲国产一区二区| 欧美国产先锋| 国产真人无码作爱视频免费| 国产精品1024久久| 六月婷婷七月丁香| 亚洲乱码国产乱码精品精可以看| 一级成人黄色片| 日韩一级二级三级精品视频| 女人天堂在线| 欧美大片在线看免费观看| 日本综合视频| 国产在线精品二区| 久久久久av| 国产免费999| 91一区二区在线| 免费麻豆国产一区二区三区四区| 91久久精品国产91性色tv| 亚洲av无码乱码在线观看性色 | 久久草.com| 欧美高清一区| 最新天堂在线视频| 91麻豆高清视频| 免费毛片在线播放免费| 欧美区一区二区三区| 男人的天堂在线视频| 欧美精品激情视频| www.欧美视频| 亚洲丰满在线| 美女91精品| 欲求不满的岳中文字幕| 亚洲精品成a人| 国产又大又粗又长| 一区二区在线视频| 欧美美女日韩| 蜜桃传媒视频麻豆一区| 在线欧美三区| 美女黄色一级视频| 一区二区三区在线不卡| 国产美女无遮挡永久免费| 中文字幕日韩精品在线观看| 欧美黄色网页| 日韩电影天堂视频一区二区| 久久电影一区| 久久精品—区二区三区舞蹈| 懂色av影视一区二区三区| 免费观看的毛片| 久久久久久久色| 成功精品影院| 97超碰人人澡| 成人av资源在线观看| 精品无码一区二区三区电影桃花 | 欧美性猛交xxxx免费看久久久| 蜜桃91麻豆精品一二三区| 色综合久久88| 最新国产一区二区| h无码动漫在线观看| 国产a视频精品免费观看| 国产免费无码一区二区视频| 日韩欧美一区二区在线视频| av小次郎在线| 国产麻豆乱码精品一区二区三区| 一区视频在线看| 亚洲综合自拍网| 日韩欧美在线视频观看| 青青草av免费在线观看| 国产成人精品av在线| 久久免费大视频| 激情久久综合网| 亚洲自拍偷拍综合| 天天干视频在线| 热99久久精品| 97精品视频| 国产精久久久久| 欧美视频中文字幕在线| 国产视频在线看| 国产在线999| 国产综合亚洲精品一区二| 亚洲一区二区乱码| 欧美体内she精视频| 新版中文在线官网| 久久riav| 狠狠色狠狠色综合系列| 国产亚洲精品久久久久久无几年桃| 亚洲国产成人在线视频| 视频二区不卡| 国产免费xxx| 26uuu精品一区二区在线观看| 亚洲精品无码久久久久| 美女少妇精品视频| 欧美人与动xxxxz0oz| 久久久精品三级| 一区二区三区免费在线观看| 四虎精品在线| 91精品视频在线播放| 亚洲三级免费| 特级西西人体高清大胆| 日韩精品一区二区三区中文精品| 丝袜诱惑一区二区| 中文精品一区二区三区| jiyouzz国产精品久久| 中文字幕乱码无码人妻系列蜜桃| 欧美猛男性生活免费| 国模精品一区| 2018国产精品| 欧美视频三区在线播放| 99久久精品免费看国产小宝寻花| 无码免费一区二区三区免费播放| 国产91精品精华液一区二区三区 | 欧美精品一区二区三区在线四季| 国产在线精品免费|