自定义View之圆形拖动DEMO

来源:互联网 发布:mac限量版口红2017 编辑:程序博客网 时间:2024/06/05 08:55
[java] view plaincopyprint?
  1.   
[java] view plaincopyprint?
  1. VIEW主文件  
[java] view plaincopyprint?
  1. /** 
  2.   *  
  3.   */  
  4.  package com.android.circle;  
  5.    
  6.  import java.util.ArrayList;  
  7.  import java.util.List;  
  8.    
  9.  import android.content.ClipData;  
  10.  import android.content.ClipDescription;  
  11.  import android.content.Context;  
  12.  import android.content.Intent;  
  13.  import android.content.res.TypedArray;  
  14.  import android.graphics.Canvas;  
  15.  import android.graphics.Color;  
  16.  import android.graphics.Paint;  
  17.  import android.graphics.Paint.Style;  
  18.  import android.graphics.drawable.Drawable;  
  19.  import android.util.AttributeSet;  
  20.  import android.util.FloatMath;  
  21.  import android.util.Log;  
  22.  import android.view.DragEvent;  
  23.  import android.view.LayoutInflater;  
  24.  import android.view.MotionEvent;  
  25.  import android.view.View;  
  26.  import android.view.ViewGroup;  
  27.  import android.widget.ImageView;  
  28.  import android.widget.Toast;  
  29.    
  30.  public class CircleView extends ViewGroup {  
  31.     Paint mPaint;  
  32.     float mCenter_X, mCenter_Y;  
  33.     int mInnerRadius, mOuterRadius, mOuterSamllRadius, mCircleNumber;  
  34.     View mChild;  
  35.     double mDegree;  
  36.     LayoutInflater mLayoutInflater;  
  37.     ArrayList<CircleValue> mCircleValue = new ArrayList<CircleValue>();  
  38.     private onPenUpCallback mOnPenUpCallback;  
  39.       
  40.     /** 
  41.      * @param context 
  42.      * @param attrs 
  43.      */  
  44.     public CircleView(Context context, AttributeSet attrs) {  
  45.         super(context, attrs);  
  46.    
  47.         mPaint = new Paint();  
  48.    
  49.         TypedArray array = context.obtainStyledAttributes(attrs,  
  50.                 R.styleable.Circle);  
  51.         mInnerRadius = array.getDimensionPixelSize(  
  52.                 R.styleable.Circle_inner_radius, 50);  
  53.         mOuterRadius = array.getDimensionPixelSize(  
  54.                 R.styleable.Circle_outer_radius, 100);  
  55.         mOuterSamllRadius = array.getDimensionPixelSize(  
  56.                 R.styleable.Circle_outer_small_radius, 30);  
  57.         mCircleNumber = array.getInteger(R.styleable.Circle_number1, 4);  
  58.    
  59.         mLayoutInflater = LayoutInflater.from(getContext());  
  60.    
  61.         for (int i = 0; i < mCircleNumber; i++) {  
  62.             mChild = mLayoutInflater.inflate(R.layout.circle_item, null);  
  63.             mChild.setTag("" + i);  
  64.             mChild.setOnTouchListener(new View.OnTouchListener() {  
  65.                 float down_x=0 , down_y=0 , curr_x=0 , curr_y=0;  
  66.                 @Override  
  67.                 public boolean onTouch(View v, MotionEvent event) {  
  68.                     String _id = v.getTag().toString();  
  69.                     int id = Integer.parseInt(_id);  
  70.                       
  71.                     switch (event.getAction()) {  
  72.                     case MotionEvent.ACTION_DOWN:  
  73.                         down_x = event.getRawX();  
  74.                         down_y = event.getRawY();  
  75.                         break;  
  76.                     case MotionEvent.ACTION_MOVE:  
  77.                         curr_x = event.getRawX();  
  78.                         curr_y = event.getRawY();  
  79.                         moveView(v,id,down_x ,  down_y, curr_x , curr_y);  
  80.                           
  81.                         break;  
  82.                     case MotionEvent.ACTION_UP:  
  83.                     case MotionEvent.ACTION_CANCEL:  
  84.                           
  85.                         boolean ret = checkUp(v);  
  86.                         if(ret == true)  
  87.                         {  
  88.                             mOnPenUpCallback.CallBack();  
  89.                         }  
  90.                         else  
  91.                         {  
  92.                             CircleValue value =  getOriginalValue(id);  
  93.                             v.layout(value.left ,value.top , value.right , value.buttom);  
  94.                         }  
  95.                         break;  
  96.                           
  97.                     default:  
  98.                         break;  
  99.                     }  
  100.    
  101.                     return true;  
  102.                 }  
  103.             });  
  104.    
  105.             addView(mChild, i);  
  106.         }  
  107.    
  108.         array.recycle();  
  109.    
  110.     }  
  111.     public void setPenUpCallBack(onPenUpCallback c)  
  112.     {  
  113.         mOnPenUpCallback = c;  
  114.     }  
  115.       
  116.     private boolean checkUp(View v)  
  117.     {  
  118.         float x = v.getX()+v.getWidth()/2;  
  119.         float y = v.getY()+v.getHeight()/2;  
  120.           
  121.         float gx = Math.abs(x-mCenter_X);  
  122.         float gy = Math.abs(y-mCenter_Y);  
  123.           
  124.         double d = (double)(gx*gx + gy*gy);  
  125.         double radius = Math.sqrt(d);  
  126.    
  127.         if(radius < mInnerRadius)  
  128.         {  
  129.             return true;  
  130.         }  
  131.         else  
  132.         {  
  133.             return false;  
  134.         }  
  135.     }  
  136.       
  137.     private void moveView(View v, int id ,float down_x , float down_y, float curr_x ,float curr_y )  
  138.     {  
  139.         CircleValue value =  getOriginalValue(id);  
  140.         int gap_x , gap_y ;  
  141.           
  142.         gap_x = (int)(curr_x - down_x);  
  143.         gap_y = (int)(curr_y - down_y);  
  144.         v.layout(value.left+ gap_x,value.top+gap_y , value.right + gap_x , value.buttom + gap_y);  
  145.     }  
  146.       
  147.     public void onDraw(Canvas canvas) {  
  148.         super.onDraw(canvas);  
  149.    
  150.         mPaint.setStyle(Style.FILL);  
  151.         mPaint.setColor(Color.GRAY);  
  152.         canvas.drawCircle(mCenter_X, mCenter_Y, mOuterRadius, mPaint);  
  153.    
  154.         mPaint.setStyle(Style.FILL);  
  155.         mPaint.setColor(Color.GREEN);  
  156.         canvas.drawCircle(mCenter_X, mCenter_Y, mInnerRadius, mPaint);  
  157.    
  158.     }  
  159.    
  160.     private float calcCircleX(int index) {  
  161.         float x = 0;  
  162.         float degree = (float) mDegree * index;  
  163.    
  164.         x = FloatMath.sin(degree) * mOuterRadius;  
  165.         return mCenter_X + x;  
  166.     }  
  167.    
  168.     private float calcCircleY(int index) {  
  169.         float y = 0;  
  170.         float degree = (float) mDegree * index;  
  171.    
  172.         y = FloatMath.cos(degree) * mOuterRadius;  
  173.         return mCenter_Y - y;  
  174.     }  
  175.    
  176.     protected void onLayout(boolean changed, int left, int top, int right,  
  177.             int bottom) {  
  178.         mDegree = 2 * Math.PI / getChildCount();  
  179.         mCenter_X = getMeasuredWidth() >> 1;  
  180.         mCenter_Y = getMeasuredHeight() >> 1;  
  181.    
  182.         for (int i = 0; i < getChildCount(); i++) {  
  183.             View child = getChildAt(i);  
  184.    
  185.             int w = child.getMeasuredWidth();  
  186.             int h = child.getMeasuredHeight();  
  187.    
  188.             child.measure(w, h);  
  189.    
  190.             float cx = calcCircleX(i);  
  191.             float cy = calcCircleY(i);  
  192.             int sx = (int) cx - (w >> 1);  
  193.             int sy = (int) cy - (h >> 1);  
  194.    
  195.             child.layout(sx, sy, sx + w, sy + h);  
  196.             if(w!=0 && h!=0)  
  197.             {  
  198.                 CircleValue mValue = new CircleValue(sx, sy, sx + w, sy + h);  
  199.                 mCircleValue.add(mValue);  
  200.             }  
  201.         }  
  202.     }  
  203.       
  204.     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  205.         super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  206.         setMeasuredDimension(widthMeasureSpec, heightMeasureSpec);  
  207.     }  
  208.    
  209.     private CircleValue getOriginalValue(int id)  
  210.     {  
  211.         return mCircleValue.get(id);  
  212.     }  
  213.       
  214.     public interface onPenUpCallback{  
  215.         public void CallBack();  
  216.     }  
  217.       
  218.     private class CircleValue {  
  219.         public int left, top, right, buttom;  
  220.    
  221.         public CircleValue() {  
  222.             left = 0;  
  223.             top = 0;  
  224.             right = 0;  
  225.             buttom = 0;  
  226.         }  
  227.           
  228.         public CircleValue(int l, int t, int r, int b) {  
  229.             left = l;  
  230.             top = t;  
  231.             right = r;  
  232.             buttom = b;  
  233.         }  
  234.           
  235.         public void setValue(int l, int t, int r, int b) {  
  236.             left = l;  
  237.             top = t;  
  238.             right = r;  
  239.             buttom = b;  
  240.         }  
  241.     }  
  242.  }  
  243.    
[java] view plaincopyprint?
  1. attrs.xml   
[java] view plaincopyprint?
  1. <?xml version="1.0" encoding="utf-8"?>  
  2.  <resources>  
  3.    
  4.      <declare-styleable name="Circle">  
  5.          <attr name="inner_radius" format="dimension" />  
  6.          <attr name="outer_radius" format="dimension" />  
  7.          <attr name="outer_small_radius" format="dimension" />  
  8.          <attr name="number1" format="integer" />  
  9.      </declare-styleable>  
  10.    
  11.  </resources>  


此view只是一个demo.可以用于解锁界面等.下面是效果图.周边圆环拖动到中间区域内则响应触发事件.不在区域之内则回到原来的地方