/**
* 扇形选择器
*
*/
public class SelectView extends RelativeLayout {
MyView myView;
//touch的point
private float oldX,oldY;
private float originTouchPointX,originTouchPointY;
//点击的第几圈
private int circleNum;
private SelectViewAdapter adapter;
private Paint paint=new Paint();
private SelectViewResultListener resultListener;
private boolean anitionFinish=true;
public SelectView(Context context,AttributeSet attributeSet) {
// TODO Auto-generated constructor stub
super(context, attributeSet);
myView=new MyView(context);
myView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
myView.setBackgroundColor(Color.TRANSPARENT);
this.addView(myView);
}
public void setAdapter(SelectViewAdapter adapter){
this.adapter=adapter;
adapter.setServiceView(this);
myView.invalidate();
}
public void show(){
if (adapter==null||adapter.getCircleCount()==0) {
return;
}
if(anitionFinish){
anitionFinish=false;
AnimationSet animationSet=new AnimationSet(true);
RotateAnimation rotateAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 1.0f);
rotateAnimation.setDuration(500);
rotateAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
anitionFinish=true;
}
});
animationSet.addAnimation(rotateAnimation);
this.setVisibility(View.VISIBLE);
this.startAnimation(animationSet);
this.bringToFront();
}
}
public void dismiss(){
if (anitionFinish) {
anitionFinish=false;
AnimationSet animationSet=new AnimationSet(true);
RotateAnimation rotateAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 1.0f);
rotateAnimation.setDuration(800);
rotateAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
anitionFinish=true;
SelectView.this.setVisibility(View.GONE);
if (circleNum!=-1) {
Map<String, Integer> map=adapter.getSelectMap();
resultListener.onClickDidFinishAnimationSelectItem(map);
}
}
});
animationSet.addAnimation(rotateAnimation);
this.startAnimation(animationSet);
}
}
private class MyView extends RelativeLayout{
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (adapter==null) {
return false;
}
float touchX=event.getX();
float touchY=event.getY();
//获取圆心位置
int originX=getMeasuredWidth()/2;
int originY=getMeasuredHeight();
//获取距离圆心距离
float x=touchX-originX;
float y=originY-touchY;
//按下
super.onTouchEvent(event);
if (event.getAction()==MotionEvent.ACTION_DOWN) {
//记录初始位置
oldX=touchX;
oldY=touchY;
double r= Math.sqrt(x*x+y*y);
if (r>adapter.getOriginWidth()&&r<(adapter.getOriginWidth()+adapter.getRingHeight()*adapter.getCircleCount())) {
circleNum=(int) ((r-adapter.getOriginWidth())/adapter.getRingHeight());
originTouchPointX=touchX;
originTouchPointY=touchY;
}else {
circleNum=-1;
}
}
//手指松开
if (event.getAction()==MotionEvent.ACTION_UP) {
if ((touchX-oldX)*(touchX-oldX)+(touchY-oldY)*(touchY-oldY)<200) {
if (circleNum!=-1) {
List<String> lineDataList=adapter.getDataSource().get(adapter.getKeyList().get(circleNum));
//当前圆环的半径
double radius=adapter.getOriginWidth()+adapter.getRingHeight()*(circleNum+0.5);
//可视角度
double visibleAngle=180;
if (radius>getMeasuredWidth()/2) {
visibleAngle=180-2*Math.acos(getMeasuredWidth()/2.0/radius)*180/Math.PI;
}
//每个元素的角度
double angle=adapter.getTextViewWidth(circleNum)/(Math.PI*radius)*180;
if (angle*lineDataList.size()<visibleAngle) {
angle=visibleAngle/lineDataList.size();
}
// System.out.println("angle>>>>"+angle);
//把x值矫正过来
x=-x;
double totalAngle=Math.acos(x/Math.sqrt(x*x+y*y))*180/Math.PI-adapter.getAngleWithCircleNum(circleNum)-(180-visibleAngle)/2;
// System.out.println("totalAngle>>>>"+totalAngle);
int selectNum=(int) (totalAngle/angle);
// System.out.println("selectNum>>>>"+selectNum);
if (totalAngle>0&&selectNum<lineDataList.size()) {
adapter.setSelectSection(adapter.getKeyList().get(circleNum),Integer.valueOf(selectNum));
this.invalidate();
if (resultListener!=null) {
String key=adapter.getKeyList().get(circleNum);
Map<String, Integer> map=adapter.getSelectMap();
map.put(key, Integer.valueOf(selectNum));
}
}
}
SelectView.this.dismiss();
}
}
//手指移动
if(event.getAction()==MotionEvent.ACTION_MOVE) {
if ((touchX-oldX)*(touchX-oldX)+(touchY-oldY)*(touchY-oldY)>=200) {
if (circleNum!=-1) {
//新坐标下的角度
double newAngle=Math.acos(x/Math.sqrt(x*x+y*y))*180/Math.PI;
//旧坐标下的角度
x=originTouchPointX-originX;
y=originTouchPointY-originY;
double oldAngle=Math.acos(x/Math.sqrt(x*x+y*y))*180/Math.PI;
//偏移角度
double moveAngle=oldAngle-newAngle;
//当前圆环的半径
double radius=adapter.getOriginWidth()+adapter.getRingHeight()*(circleNum+0.5);
//可视角度
double visibleAngle=180;
if (radius>getMeasuredWidth()/2) {
visibleAngle=180-2*Math.acos(getMeasuredWidth()/2.0/radius)*180/Math.PI;
}
//点击的位置对应的圆环数据
List<String> lineDataList=adapter.getDataSource().get(adapter.getKeyList().get(circleNum));
//每个元素的角度
double angle=adapter.getTextViewWidth(circleNum)/(Math.PI*radius)*180;
if (angle*lineDataList.size()<visibleAngle) {
angle=visibleAngle/lineDataList.size();
}
// System.out.println("visibleAngle>>>>"+visibleAngle+">>>>>>angle>>>>>"+angle);
// System.out.println("moveAngle之前>>>>>>>>"+moveAngle);
//向右滑动
if (moveAngle>0) {
if (moveAngle+adapter.getAngleWithCircleNum(circleNum)>=0) {
moveAngle=-adapter.getAngleWithCircleNum(circleNum);
}
}
//向左滑动
else if (moveAngle<0){
if (visibleAngle-adapter.getAngleWithCircleNum(circleNum)-moveAngle>=angle*lineDataList.size()) {
moveAngle=visibleAngle-adapter.getAngleWithCircleNum(circleNum)-angle*lineDataList.size();
}
}
// System.out.println("moveAngle之后>>>>>>>>"+moveAngle);
adapter.addAngleWithCircleNum(circleNum,Double.valueOf(moveAngle));
originTouchPointX=touchX;
originTouchPointY=touchY;
this.invalidate();
}
}
}
// System.out.println("touch事件");
return true;
}
@SuppressLint("NewApi")
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
// System.out.println("onDraw>>>事件执行了");
if (adapter==null) {
return;
}
canvas.translate(getMeasuredWidth()/2, getMeasuredHeight());
this.drawBackGround(canvas);
this.drawTextView(canvas);
}
private void drawBackGround(Canvas canvas){
canvas.save();
int ringHeight=adapter.getRingHeight();
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(ringHeight);
paint.setAntiAlias(true);
List<Integer> backGroundColors=adapter.getBackGroundColor();
for (int i = adapter.getCircleCount()-1; i >=0; i--) {
paint.setStrokeWidth(ringHeight+1);
paint.setColor(backGroundColors.get(i).intValue());
int radius=adapter.getOriginWidth()+ringHeight*i+ringHeight/2;
RectF rect = new RectF(-radius, -radius, radius, radius);
canvas.drawArc(rect, 180, 180, false, paint);
}
canvas.restore();
}
private void drawTextView(Canvas canvas){
canvas.save();
paint.setStyle(Style.FILL);
paint.setStrokeWidth(1.0f);
paint.setTextSize(adapter.getTextSize());
int radius=adapter.getOriginWidth()-adapter.getRingHeight()/2;
for (int i = 0; i < adapter.getKeyList().size(); i++) {
//获得每一圈的外半径
radius+=adapter.getRingHeight();
//每一圈的数据数组
List<String> lineDataList=adapter.getDataSource().get(adapter.getKeyList().get(i));
// System.out.println("lineDataList>>>>>"+lineDataList);
double visibleAngle=180;
if (radius>getMeasuredWidth()/2) {
visibleAngle=180-2*Math.acos(getMeasuredWidth()/2.0/radius)*180/Math.PI;
}
//每个元素的角度
double angle=adapter.getTextViewWidth(i)/(Math.PI*radius)*180;
int count=(int) (visibleAngle/angle);
if (angle*(count+2)<360) {
count+=2;
}else if (angle*(count+1)<360) {
count+=1;
}
//originNum已经转过了多少个
int originNum=(int)(-adapter.getAngleWithCircleNum(i)/angle);
if (originNum<0) {
originNum=0;
}
//remainCount剩余个数
int remainCount=lineDataList.size()-originNum;
if (count>remainCount) {
count=remainCount;
}
if (angle*adapter.getDataSource().get(adapter.getKeyList().get(i)).size()<visibleAngle) {
angle=visibleAngle/adapter.getDataSource().get(adapter.getKeyList().get(i)).size();
}
//附加的初始角度
double extraAngle=adapter.getAngleWithCircleNum(i);
if (extraAngle<0) {
extraAngle=extraAngle%angle;
}
//循环填充数据
for (int j = 0; j < count; j++) {
Rect bounds = new Rect();
//设置字体颜色
if (adapter.getSelectMap().get(adapter.getKeyList().get(i))!=null&&adapter.getSelectMap().get(adapter.getKeyList().get(i)).intValue()==j+originNum) {
paint.setColor(adapter.getSelectedTextColor());
}else {
paint.setColor(adapter.getUnSelectedTextColor(i,j));
}
paint.getTextBounds(lineDataList.get(j+originNum), 0, lineDataList.get(j+originNum).length(), bounds);
int width = bounds.width();
int textAngle=(int) (width*180/(Math.PI*radius))+2;
int originAngle=(int) (-180+angle*j+(180-visibleAngle)/2+extraAngle+(angle-textAngle)/2);
Path path=new Path();
RectF rect = new RectF(-radius, -radius, radius, radius);
path.addArc(rect, originAngle, textAngle);
canvas.drawTextOnPath(lineDataList.get(j+originNum), path, 0, adapter.getTextSize()/2, paint);
}
}
canvas.restore();
}
}
public void setSelectViewResultListener(SelectViewResultListener listener){
resultListener=listener;
}
static public interface SelectViewResultListener{
public void onClickDidFinishAnimationSelectItem(Map<String, Integer> map);
}
static abstract public class SelectViewAdapter {
protected Context mContext;
private Map<Integer, Double> angleMap;
private Map<String, Integer> mySelectMap;
private SelectView serviceView;
public SelectViewAdapter(Context context) {
// TODO Auto-generated constructor stub
mContext=context;
mySelectMap=setSelectMap();
}
//把dataSource从内到外的key按顺序放入list中,内容不能为空
abstract public List<String> getKeyList();
/*
* getDataSource与getSelectMap键相同
*/
//提供的选项
abstract public Map<String, List<String>> getDataSource();
//定义选中的map
abstract public Map<String, Integer> setSelectMap();
//设置选中的map
public Map<String, Integer> getSelectMap(){
if (mySelectMap==null) {
mySelectMap=new HashMap<String, Integer>();
for (int i = 0; i < getCircleCount(); i++) {
mySelectMap.put(getKeyList().get(i), Integer.valueOf(0));
}
}
return mySelectMap;
}
public void setServiceView(SelectView view){
serviceView=view;
}
//设置选中的选项
public void setSelectSection(String key,Integer num){
mySelectMap.put(key, num);
}
//每个环转过的角度
@SuppressLint("UseSparseArrays")
public void addAngleWithCircleNum(int circleNum,Double angle){
if (angleMap==null) {
angleMap=new HashMap<Integer, Double>();
for (int i = 0; i < getCircleCount(); i++) {
angleMap.put(Integer.valueOf(i), Double.valueOf(0));
}
}
angleMap.put(Integer.valueOf(circleNum), angleMap.get(Integer.valueOf(circleNum))+angle);
}
public double getAngleWithCircleNum(int circleNum){
double angle=0;
if (angleMap!=null) {
angle=angleMap.get(Integer.valueOf(circleNum)).doubleValue();
}
return angle;
}
//设置选中的选项字体颜色
public int getSelectedTextColor(){return Color.RED;}
//设置未选中的选项字体颜色
public int getUnSelectedTextColor(int circleNum,int columns){return Color.WHITE;}
//设置字体大小
public float getTextSize(){
return getRingHeight()/3;
}
//设置每个选项的宽度
public int getTextViewWidth(int circleNum){
int width=1;
if (getDataSource()!=null) {
Paint paint =new Paint();
paint.setTextSize(getTextSize());
Rect bounds = new Rect();
List<String> lineDataList=getDataSource().get(getKeyList().get(circleNum));
for (String string : lineDataList) {
paint.getTextBounds(string, 0, string.length(), bounds);
if (width<bounds.width()) {
width=bounds.width();
}
}
}
return width+30;
}
//设置最内层圆环的内边缘初始半径
public int getOriginWidth(){
int radius=0;
if (serviceView!=null) {
if (serviceView.getMeasuredWidth()>serviceView.getMeasuredHeight()) {
radius=serviceView.getMeasuredHeight()/4;
}else {
radius=serviceView.getMeasuredWidth()/4;
}
}else {
DisplayMetrics metric = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
radius=metric.widthPixels/4;
}
return radius;
}
//设置每个圆环的高度
public int getRingHeight(){
int ringHeight=0;
if (serviceView!=null) {
if (serviceView.getMeasuredWidth()>serviceView.getMeasuredHeight()) {
ringHeight=serviceView.getMeasuredHeight()/9;
}else {
ringHeight=serviceView.getMeasuredWidth()/9;
}
}else {
DisplayMetrics metric = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
ringHeight=metric.widthPixels/9;
}
return ringHeight;
}
public int getCircleCount(){
int count=0;
if (getDataSource()!=null) {
count=getDataSource().size();
}
return count;
}
//返回的色值是integer类型的list
public List<Integer> getBackGroundColor(){
List<Integer> colorList=new ArrayList<Integer>();
//UIColorFromRGB(0xfdd1ae),UIColorFromRGB(0xfdba86),UIColorFromRGB(0xffa45e),UIColorFromRGB(0xfe8c36),UIColorFromRGB(0xfe8c36),UIColorFromRGB(0xfe8c36)
colorList.add(Integer.valueOf(0xfffdd1ae));
colorList.add(Integer.valueOf(0xFFfdba86));
colorList.add(Integer.valueOf(0xFFffa45e));
colorList.add(Integer.valueOf(0xFFfe8c36));
colorList.add(Integer.valueOf(0xFFfe8c36));
colorList.add(Integer.valueOf(0xFFfe8c36));
colorList.add(Integer.valueOf(0xFFEB8E55));
colorList.add(Integer.valueOf(0xFF708069));
colorList.add(Integer.valueOf(0xFFFAEBD7));
colorList.add(Integer.valueOf(0xFF7FFFD4));
colorList.add(Integer.valueOf(0xFFB0E0E6));
colorList.add(Integer.valueOf(0xFFB0171F));
colorList.add(Integer.valueOf(0xFFFF00FF));
return colorList;
}
}
}
* 扇形选择器
*
*/
public class SelectView extends RelativeLayout {
MyView myView;
//touch的point
private float oldX,oldY;
private float originTouchPointX,originTouchPointY;
//点击的第几圈
private int circleNum;
private SelectViewAdapter adapter;
private Paint paint=new Paint();
private SelectViewResultListener resultListener;
private boolean anitionFinish=true;
public SelectView(Context context,AttributeSet attributeSet) {
// TODO Auto-generated constructor stub
super(context, attributeSet);
myView=new MyView(context);
myView.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,LayoutParams.MATCH_PARENT));
myView.setBackgroundColor(Color.TRANSPARENT);
this.addView(myView);
}
public void setAdapter(SelectViewAdapter adapter){
this.adapter=adapter;
adapter.setServiceView(this);
myView.invalidate();
}
public void show(){
if (adapter==null||adapter.getCircleCount()==0) {
return;
}
if(anitionFinish){
anitionFinish=false;
AnimationSet animationSet=new AnimationSet(true);
RotateAnimation rotateAnimation = new RotateAnimation(-180, 0, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 1.0f);
rotateAnimation.setDuration(500);
rotateAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
anitionFinish=true;
}
});
animationSet.addAnimation(rotateAnimation);
this.setVisibility(View.VISIBLE);
this.startAnimation(animationSet);
this.bringToFront();
}
}
public void dismiss(){
if (anitionFinish) {
anitionFinish=false;
AnimationSet animationSet=new AnimationSet(true);
RotateAnimation rotateAnimation = new RotateAnimation(0, -180, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, 1.0f);
rotateAnimation.setDuration(800);
rotateAnimation.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animation animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animation animation) {
// TODO Auto-generated method stub
anitionFinish=true;
SelectView.this.setVisibility(View.GONE);
if (circleNum!=-1) {
Map<String, Integer> map=adapter.getSelectMap();
resultListener.onClickDidFinishAnimationSelectItem(map);
}
}
});
animationSet.addAnimation(rotateAnimation);
this.startAnimation(animationSet);
}
}
private class MyView extends RelativeLayout{
public MyView(Context context) {
super(context);
// TODO Auto-generated constructor stub
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
if (adapter==null) {
return false;
}
float touchX=event.getX();
float touchY=event.getY();
//获取圆心位置
int originX=getMeasuredWidth()/2;
int originY=getMeasuredHeight();
//获取距离圆心距离
float x=touchX-originX;
float y=originY-touchY;
//按下
super.onTouchEvent(event);
if (event.getAction()==MotionEvent.ACTION_DOWN) {
//记录初始位置
oldX=touchX;
oldY=touchY;
double r= Math.sqrt(x*x+y*y);
if (r>adapter.getOriginWidth()&&r<(adapter.getOriginWidth()+adapter.getRingHeight()*adapter.getCircleCount())) {
circleNum=(int) ((r-adapter.getOriginWidth())/adapter.getRingHeight());
originTouchPointX=touchX;
originTouchPointY=touchY;
}else {
circleNum=-1;
}
}
//手指松开
if (event.getAction()==MotionEvent.ACTION_UP) {
if ((touchX-oldX)*(touchX-oldX)+(touchY-oldY)*(touchY-oldY)<200) {
if (circleNum!=-1) {
List<String> lineDataList=adapter.getDataSource().get(adapter.getKeyList().get(circleNum));
//当前圆环的半径
double radius=adapter.getOriginWidth()+adapter.getRingHeight()*(circleNum+0.5);
//可视角度
double visibleAngle=180;
if (radius>getMeasuredWidth()/2) {
visibleAngle=180-2*Math.acos(getMeasuredWidth()/2.0/radius)*180/Math.PI;
}
//每个元素的角度
double angle=adapter.getTextViewWidth(circleNum)/(Math.PI*radius)*180;
if (angle*lineDataList.size()<visibleAngle) {
angle=visibleAngle/lineDataList.size();
}
// System.out.println("angle>>>>"+angle);
//把x值矫正过来
x=-x;
double totalAngle=Math.acos(x/Math.sqrt(x*x+y*y))*180/Math.PI-adapter.getAngleWithCircleNum(circleNum)-(180-visibleAngle)/2;
// System.out.println("totalAngle>>>>"+totalAngle);
int selectNum=(int) (totalAngle/angle);
// System.out.println("selectNum>>>>"+selectNum);
if (totalAngle>0&&selectNum<lineDataList.size()) {
adapter.setSelectSection(adapter.getKeyList().get(circleNum),Integer.valueOf(selectNum));
this.invalidate();
if (resultListener!=null) {
String key=adapter.getKeyList().get(circleNum);
Map<String, Integer> map=adapter.getSelectMap();
map.put(key, Integer.valueOf(selectNum));
}
}
}
SelectView.this.dismiss();
}
}
//手指移动
if(event.getAction()==MotionEvent.ACTION_MOVE) {
if ((touchX-oldX)*(touchX-oldX)+(touchY-oldY)*(touchY-oldY)>=200) {
if (circleNum!=-1) {
//新坐标下的角度
double newAngle=Math.acos(x/Math.sqrt(x*x+y*y))*180/Math.PI;
//旧坐标下的角度
x=originTouchPointX-originX;
y=originTouchPointY-originY;
double oldAngle=Math.acos(x/Math.sqrt(x*x+y*y))*180/Math.PI;
//偏移角度
double moveAngle=oldAngle-newAngle;
//当前圆环的半径
double radius=adapter.getOriginWidth()+adapter.getRingHeight()*(circleNum+0.5);
//可视角度
double visibleAngle=180;
if (radius>getMeasuredWidth()/2) {
visibleAngle=180-2*Math.acos(getMeasuredWidth()/2.0/radius)*180/Math.PI;
}
//点击的位置对应的圆环数据
List<String> lineDataList=adapter.getDataSource().get(adapter.getKeyList().get(circleNum));
//每个元素的角度
double angle=adapter.getTextViewWidth(circleNum)/(Math.PI*radius)*180;
if (angle*lineDataList.size()<visibleAngle) {
angle=visibleAngle/lineDataList.size();
}
// System.out.println("visibleAngle>>>>"+visibleAngle+">>>>>>angle>>>>>"+angle);
// System.out.println("moveAngle之前>>>>>>>>"+moveAngle);
//向右滑动
if (moveAngle>0) {
if (moveAngle+adapter.getAngleWithCircleNum(circleNum)>=0) {
moveAngle=-adapter.getAngleWithCircleNum(circleNum);
}
}
//向左滑动
else if (moveAngle<0){
if (visibleAngle-adapter.getAngleWithCircleNum(circleNum)-moveAngle>=angle*lineDataList.size()) {
moveAngle=visibleAngle-adapter.getAngleWithCircleNum(circleNum)-angle*lineDataList.size();
}
}
// System.out.println("moveAngle之后>>>>>>>>"+moveAngle);
adapter.addAngleWithCircleNum(circleNum,Double.valueOf(moveAngle));
originTouchPointX=touchX;
originTouchPointY=touchY;
this.invalidate();
}
}
}
// System.out.println("touch事件");
return true;
}
@SuppressLint("NewApi")
@Override
protected void onDraw(Canvas canvas) {
// TODO Auto-generated method stub
super.onDraw(canvas);
// System.out.println("onDraw>>>事件执行了");
if (adapter==null) {
return;
}
canvas.translate(getMeasuredWidth()/2, getMeasuredHeight());
this.drawBackGround(canvas);
this.drawTextView(canvas);
}
private void drawBackGround(Canvas canvas){
canvas.save();
int ringHeight=adapter.getRingHeight();
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(ringHeight);
paint.setAntiAlias(true);
List<Integer> backGroundColors=adapter.getBackGroundColor();
for (int i = adapter.getCircleCount()-1; i >=0; i--) {
paint.setStrokeWidth(ringHeight+1);
paint.setColor(backGroundColors.get(i).intValue());
int radius=adapter.getOriginWidth()+ringHeight*i+ringHeight/2;
RectF rect = new RectF(-radius, -radius, radius, radius);
canvas.drawArc(rect, 180, 180, false, paint);
}
canvas.restore();
}
private void drawTextView(Canvas canvas){
canvas.save();
paint.setStyle(Style.FILL);
paint.setStrokeWidth(1.0f);
paint.setTextSize(adapter.getTextSize());
int radius=adapter.getOriginWidth()-adapter.getRingHeight()/2;
for (int i = 0; i < adapter.getKeyList().size(); i++) {
//获得每一圈的外半径
radius+=adapter.getRingHeight();
//每一圈的数据数组
List<String> lineDataList=adapter.getDataSource().get(adapter.getKeyList().get(i));
// System.out.println("lineDataList>>>>>"+lineDataList);
double visibleAngle=180;
if (radius>getMeasuredWidth()/2) {
visibleAngle=180-2*Math.acos(getMeasuredWidth()/2.0/radius)*180/Math.PI;
}
//每个元素的角度
double angle=adapter.getTextViewWidth(i)/(Math.PI*radius)*180;
int count=(int) (visibleAngle/angle);
if (angle*(count+2)<360) {
count+=2;
}else if (angle*(count+1)<360) {
count+=1;
}
//originNum已经转过了多少个
int originNum=(int)(-adapter.getAngleWithCircleNum(i)/angle);
if (originNum<0) {
originNum=0;
}
//remainCount剩余个数
int remainCount=lineDataList.size()-originNum;
if (count>remainCount) {
count=remainCount;
}
if (angle*adapter.getDataSource().get(adapter.getKeyList().get(i)).size()<visibleAngle) {
angle=visibleAngle/adapter.getDataSource().get(adapter.getKeyList().get(i)).size();
}
//附加的初始角度
double extraAngle=adapter.getAngleWithCircleNum(i);
if (extraAngle<0) {
extraAngle=extraAngle%angle;
}
//循环填充数据
for (int j = 0; j < count; j++) {
Rect bounds = new Rect();
//设置字体颜色
if (adapter.getSelectMap().get(adapter.getKeyList().get(i))!=null&&adapter.getSelectMap().get(adapter.getKeyList().get(i)).intValue()==j+originNum) {
paint.setColor(adapter.getSelectedTextColor());
}else {
paint.setColor(adapter.getUnSelectedTextColor(i,j));
}
paint.getTextBounds(lineDataList.get(j+originNum), 0, lineDataList.get(j+originNum).length(), bounds);
int width = bounds.width();
int textAngle=(int) (width*180/(Math.PI*radius))+2;
int originAngle=(int) (-180+angle*j+(180-visibleAngle)/2+extraAngle+(angle-textAngle)/2);
Path path=new Path();
RectF rect = new RectF(-radius, -radius, radius, radius);
path.addArc(rect, originAngle, textAngle);
canvas.drawTextOnPath(lineDataList.get(j+originNum), path, 0, adapter.getTextSize()/2, paint);
}
}
canvas.restore();
}
}
public void setSelectViewResultListener(SelectViewResultListener listener){
resultListener=listener;
}
static public interface SelectViewResultListener{
public void onClickDidFinishAnimationSelectItem(Map<String, Integer> map);
}
static abstract public class SelectViewAdapter {
protected Context mContext;
private Map<Integer, Double> angleMap;
private Map<String, Integer> mySelectMap;
private SelectView serviceView;
public SelectViewAdapter(Context context) {
// TODO Auto-generated constructor stub
mContext=context;
mySelectMap=setSelectMap();
}
//把dataSource从内到外的key按顺序放入list中,内容不能为空
abstract public List<String> getKeyList();
/*
* getDataSource与getSelectMap键相同
*/
//提供的选项
abstract public Map<String, List<String>> getDataSource();
//定义选中的map
abstract public Map<String, Integer> setSelectMap();
//设置选中的map
public Map<String, Integer> getSelectMap(){
if (mySelectMap==null) {
mySelectMap=new HashMap<String, Integer>();
for (int i = 0; i < getCircleCount(); i++) {
mySelectMap.put(getKeyList().get(i), Integer.valueOf(0));
}
}
return mySelectMap;
}
public void setServiceView(SelectView view){
serviceView=view;
}
//设置选中的选项
public void setSelectSection(String key,Integer num){
mySelectMap.put(key, num);
}
//每个环转过的角度
@SuppressLint("UseSparseArrays")
public void addAngleWithCircleNum(int circleNum,Double angle){
if (angleMap==null) {
angleMap=new HashMap<Integer, Double>();
for (int i = 0; i < getCircleCount(); i++) {
angleMap.put(Integer.valueOf(i), Double.valueOf(0));
}
}
angleMap.put(Integer.valueOf(circleNum), angleMap.get(Integer.valueOf(circleNum))+angle);
}
public double getAngleWithCircleNum(int circleNum){
double angle=0;
if (angleMap!=null) {
angle=angleMap.get(Integer.valueOf(circleNum)).doubleValue();
}
return angle;
}
//设置选中的选项字体颜色
public int getSelectedTextColor(){return Color.RED;}
//设置未选中的选项字体颜色
public int getUnSelectedTextColor(int circleNum,int columns){return Color.WHITE;}
//设置字体大小
public float getTextSize(){
return getRingHeight()/3;
}
//设置每个选项的宽度
public int getTextViewWidth(int circleNum){
int width=1;
if (getDataSource()!=null) {
Paint paint =new Paint();
paint.setTextSize(getTextSize());
Rect bounds = new Rect();
List<String> lineDataList=getDataSource().get(getKeyList().get(circleNum));
for (String string : lineDataList) {
paint.getTextBounds(string, 0, string.length(), bounds);
if (width<bounds.width()) {
width=bounds.width();
}
}
}
return width+30;
}
//设置最内层圆环的内边缘初始半径
public int getOriginWidth(){
int radius=0;
if (serviceView!=null) {
if (serviceView.getMeasuredWidth()>serviceView.getMeasuredHeight()) {
radius=serviceView.getMeasuredHeight()/4;
}else {
radius=serviceView.getMeasuredWidth()/4;
}
}else {
DisplayMetrics metric = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
radius=metric.widthPixels/4;
}
return radius;
}
//设置每个圆环的高度
public int getRingHeight(){
int ringHeight=0;
if (serviceView!=null) {
if (serviceView.getMeasuredWidth()>serviceView.getMeasuredHeight()) {
ringHeight=serviceView.getMeasuredHeight()/9;
}else {
ringHeight=serviceView.getMeasuredWidth()/9;
}
}else {
DisplayMetrics metric = new DisplayMetrics();
((Activity) mContext).getWindowManager().getDefaultDisplay().getMetrics(metric);
ringHeight=metric.widthPixels/9;
}
return ringHeight;
}
public int getCircleCount(){
int count=0;
if (getDataSource()!=null) {
count=getDataSource().size();
}
return count;
}
//返回的色值是integer类型的list
public List<Integer> getBackGroundColor(){
List<Integer> colorList=new ArrayList<Integer>();
//UIColorFromRGB(0xfdd1ae),UIColorFromRGB(0xfdba86),UIColorFromRGB(0xffa45e),UIColorFromRGB(0xfe8c36),UIColorFromRGB(0xfe8c36),UIColorFromRGB(0xfe8c36)
colorList.add(Integer.valueOf(0xfffdd1ae));
colorList.add(Integer.valueOf(0xFFfdba86));
colorList.add(Integer.valueOf(0xFFffa45e));
colorList.add(Integer.valueOf(0xFFfe8c36));
colorList.add(Integer.valueOf(0xFFfe8c36));
colorList.add(Integer.valueOf(0xFFfe8c36));
colorList.add(Integer.valueOf(0xFFEB8E55));
colorList.add(Integer.valueOf(0xFF708069));
colorList.add(Integer.valueOf(0xFFFAEBD7));
colorList.add(Integer.valueOf(0xFF7FFFD4));
colorList.add(Integer.valueOf(0xFFB0E0E6));
colorList.add(Integer.valueOf(0xFFB0171F));
colorList.add(Integer.valueOf(0xFFFF00FF));
return colorList;
}
}
}