当前位置:编程学习 > wap >>

android t自定义控件之旋转圆盘

   这是我改其它应用的圆盘,可以控手指滑动左右旋转,但是在圆盘中的icon图标 我想获得点击打开其它的Activity,但是有些地方我没看明白,望 高手指点,谢谢

里面的一些算法,我还是不太明白





android 自定义旋转圆盘 --------------------编程问答-------------------- [code=java]/** 
  --------------------编程问答--------------------
/** 
 *@project name: ToolBox 
 *@file name: TurnTable.java 
 *@date 2012-4-24
 *@author hyman
 *@Copyright (C) 2011 NanJing BBMF Information Technology Co., Ltd.(Shanghai Branch)
 */
package com.example.turntable;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

/**
 * 旋转台
 * 
 * @author menue
 * 
 */
public class TurnTable extends View {

private int nYoffset = 0;

/**
 * 图标,及对应的Activity等 集合
 */
private List<FunctionIcon> fiList = new ArrayList<FunctionIcon>();
/**
 * 旋转台背景图
 */
private Bitmap turntable;
/**
 * 旋转台里的分隔线
 */
private Bitmap divider;
// 没点的图标
private int[] resIcons = { R.drawable.icon_installuninstall_0,
R.drawable.icon_appmove_0, R.drawable.icon_batterymanager_0,
R.drawable.icon_cachemanager_0, R.drawable.icon_processmanager_0 };
// 按下时的图标
private static int[] res_Icons = { R.drawable.icon_installuninstall_1,
R.drawable.icon_appmove_1, R.drawable.icon_batterymanager_1,
R.drawable.icon_cachemanager_1, R.drawable.icon_processmanager_1 };
// 安装卸载,App移动,一键省电,缓存清理,进程管理,备份还原,程序锁,截屏
// private static int[] res_Titles = { R.string.installuninstall,
// R.string.appmove, R.string.batterysave, R.string.cacheclear,
// R.string.processmanager, R.string.backuprestore, R.string.applock,
// R.string.shot };
private static Context context;

@SuppressWarnings({ "rawtypes" })
/**
 * 对应的Activity.class
 */
// private Class[] activities = { InstallUninstallActivity.class,
// AppMoveActivity.class, BatteryManagerActivity.class,
// CacheManagerActivity.class, ProcessManagerActivity.class,
// BackupRestoreActivity.class, AppLockActivity.class,
// ShotPreferenceActivity.class };
private Paint paint; // 画笔
private int mWidth = 0; // 宽度
/**
 * 小图标离圆心的距离
 */
private float arcRadius;
/**
 * 分隔线离圆心的距离
 */
private float inArcRadius;
/**
 * 图标 离圆心的距离icon(left,top)
 */
private float iconRadius;
/**
 * 触摸是否在旋转台
 */
private boolean touchInTurnTable; // 元件中心
/**
 * 触摸是否在中心控件
 */
private boolean touchInCenterAre; // 元件中心
/**
 * 
 * move
 */
private double touchDegreeFromX, _touchDegreeFromX;
/**
 * 旋转角度
 */
private double turnDegree;
/**
 * 45度角
 */
private final double Angle45Degree = Math.PI * 2 / 5; // 圆周率/4

public TurnTable(Context context, AttributeSet attrs) {
super(context, attrs);
TurnTable.context = context;
releaseRes();
paint = new Paint(Paint.ANTI_ALIAS_FLAG); //
}

/**
 * 释放内存
 */
private void releaseRes() {
if (turntable != null) {
turntable.recycle();// 释放资源
turntable = null;
}
if (divider != null) {
divider.recycle();
divider = null;
}
for (FunctionIcon fi : fiList) {
if (fi.icon != null) {
fi.icon.recycle();
fi.icon = null;
}
if (fi._icon != null) {
fi._icon.recycle();
fi._icon = null;
}
}
}

// 当view的大小发生变化时触发,相当于初始化界面
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if (mWidth == 0) {
releaseRes();
mWidth = w;
// 背景大圆图
turntable = BitmapFactory.decodeResource(getResources(),
R.drawable.bg_turntable);
// 圆图中的分隔线
divider = BitmapFactory.decodeResource(getResources(),
R.drawable.tt_divider);
arcRadius = mWidth / 2.0f + 70;// 半径 相当于圆的半径(小图标离圆心的距离)
// inArcRadius = mWidth / 8.0f;// 分隔线离圆心的距离
// 向fiList加入值
for (int i = 0; i < 5; i++) { // 对应的Activity
FunctionIcon fi = new FunctionIcon();
fi.icon = BitmapFactory.decodeResource(getResources(),
resIcons[i]);
fi._icon = BitmapFactory.decodeResource(getResources(),
res_Icons[i]);
fi.click = false;
fi.mindegree = Angle45Degree * i;

/**
 * Math.atan2(x,y) x 指定点的 x 坐标的数字。 y 指定点的 y 坐标的数字。
 * 计算出来的结果translateDegree是一个弧度值, 也可以表示相对直角三角形对角的角,其中 x 是临边边长,而 y
 * 是对边边长。 Math.cos 余弦函数 Math.acos 反余弦函数
 */
fi.translateDegree = Math.atan2(
fi.icon.getWidth() / 2,
arcRadius * Math.cos(Angle45Degree / 2)
- fi.icon.getHeight())
+ Angle45Degree / 2 + Angle45Degree * i - 180;
fi.rotateDegree = (float) ((Angle45Degree * i - Angle45Degree * 5 / 3) -180);//ccy up
// fi.activity = activities[i];
fiList.add(fi);
}
/**
 * Math.pow(x,y):x的y次方 Math.sqrt(x):平方根
 */
iconRadius = (float) Math.sqrt(Math.pow(
(arcRadius * Math.cos(Math.PI / 5) - fiList.get(0).icon
.getHeight()), 2)
+ Math.pow(fiList.get(0).icon.getWidth() / 2, 2)) - 10;
}
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 平移(x,y)个像素单位
nYoffset = canvas.getWidth() / 2;
//nYoffset=canvas.getHeight()/2;
canvas.translate(0, nYoffset);
// canvas.translate(0, canvas.getWidth() / 2 +300);//ccy
// canvas.drawBitmap(bitmap, src, dst, paint)
// 画一个位图为大(大圆图,src为你要画的bitmap的区域,dst为你要显示在屏幕上的区域,)
canvas.drawBitmap(turntable, new Rect(0, 0, turntable.getWidth(),
turntable.getHeight()), new Rect(0, 0, canvas.getWidth(),
canvas.getWidth()), paint);
// 移动原点
canvas.translate(mWidth / 2, canvas.getWidth() / 2);
// Matrix类用于对图像进行移动缩放旋转等等操作
Matrix matrix = new Matrix();
for (FunctionIcon fi : fiList) {
matrix.setValues(new float[] { 
(float) Math.cos(fi.rotateDegree),
(float) -Math.sin(fi.rotateDegree),
(float) (iconRadius * Math.cos(fi.translateDegree)),
(float) Math.sin(fi.rotateDegree),
(float) Math.cos(fi.rotateDegree),
(float) (iconRadius * Math.sin(fi.translateDegree)),
0, 0,1 });

if (fi.click) {
// 把点击的图片画上去
canvas.drawBitmap(fi._icon, matrix, paint);
fi.click = false;
} else {
// 把没点击的图片画上去
canvas.drawBitmap(fi.icon, matrix, paint);
}
// 线的旋转角度
double dividerRotateDegree = fi.rotateDegree + Angle45Degree * 5
/ 2;
if (dividerRotateDegree > 2 * Math.PI) {
dividerRotateDegree -= 2 * Math.PI;
} else if (dividerRotateDegree < 0) {
dividerRotateDegree += 2 * Math.PI;
}
double dividerTranslateDegree = fi.mindegree;
matrix.setValues(new float[] {
(float) Math.cos(dividerRotateDegree),
(float) -Math.sin(dividerRotateDegree),
(float) (inArcRadius * Math.cos(dividerTranslateDegree)),
(float) Math.sin(dividerRotateDegree),
(float) Math.cos(dividerRotateDegree),
(float) (inArcRadius * Math.sin(dividerTranslateDegree)),
0, 0, 1 });
// 把线画上去
canvas.drawBitmap(divider, matrix, paint);
}
}


public static void showHelp(Context context) {
List<Map<String, Object>> itemlist = new ArrayList<Map<String, Object>>();
for (int i = 0; i < res_Icons.length; i++) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("icon", res_Icons[i]);
// map.put("title",
// context.getResources().getString(res_Titles[i]));
itemlist.add(map);
}
// final Dialog dialog = new Dialog(context, R.style.CustomDialog);
// LayoutInflater li = LayoutInflater.from(context);
// RelativeLayout rl = (RelativeLayout) li.inflate(R.layout.help, null);
// ImageView iv = (ImageView) rl.findViewById(R.id.close);
// iv.setOnClickListener(new OnClickListener() {
//
// @Override
// public void onClick(View v) {
// dialog.cancel();
// dialog.dismiss();
// }
// });
// ListView lv = (ListView) rl.findViewById(R.id.help);
// SimpleAdapter adapter = new SimpleAdapter(context,
// (List<Map<String, Object>>) itemlist, R.layout.help_item,
// new String[] { "icon", "title" }, new int[] { R.id.icon,
// R.id.title });
// lv.setAdapter(adapter);
// dialog.setContentView(rl);
// dialog.show();
}

/**
 * 是否在旋转台区域
 * 
 * @param x
 * @param y
 * @return
 */
private boolean inTurnTable(float x, float y) {
// 出圆的面积
double outCircle = Math.PI * arcRadius * arcRadius;
double inCircle = Math.PI * inArcRadius * inArcRadius;
double fingerCircle = Math.PI * (x * x + y * y);
if (fingerCircle < outCircle && fingerCircle > inCircle) {
return true;
} else {
return false;
}
}

/**
 * 是否是圆中心的区域
 * 
 * @param x
 * @param y
 * @return
 */
private boolean inCenterArc(float x, float y) {
// 圆的面积
double inCircle = Math.PI * inArcRadius * inArcRadius;
double fingerCircle = Math.PI * (x * x + y * y);
if (fingerCircle < inCircle) {
return true;
} else {
return false;
}
}

/**
 * 
 */
class FunctionIcon {
/**
 * 默认状态图标
 */
public Bitmap icon;
/**
 * 按下时状态图标
 */
public Bitmap _icon;
/**
 * 是否点击
 */
public boolean click;
/**
 * 最小度数
 */
public double mindegree;
/**
 * icon 转变度数
 */
public double translateDegree;
/**
 * icon 旋转角度
 */
public float rotateDegree;
/**
 * 对应的 activity
 */
@SuppressWarnings({ "rawtypes" })
public Class activity;
}
}
--------------------编程问答--------------------
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX() - mWidth / 2;
// float x = event.getX() - mWidth / 2-30;//ccy
float y = event.getY();
/**
 * 是否按在控制台
 */
boolean downInTurnTable = inTurnTable(x, y - nYoffset * 2-40);
/**
 * 是否按在中心元件
 */
boolean downInCenterAre = inCenterArc(x, y);
Log.i("CCY", "touchInTurnTable---->" + touchInTurnTable
+ "   touchInCenterAre--->" + touchInCenterAre
+ "  downInTurnTable=" + downInTurnTable + " downInCenterAre="
+ downInCenterAre);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touchInTurnTable = downInTurnTable;
touchInCenterAre = downInCenterAre;
_touchDegreeFromX = touchDegreeFromX = Math.atan2(x, y);

break;
case MotionEvent.ACTION_MOVE:
if (touchInTurnTable && downInTurnTable) {//
turnDegree = Math.atan2(x, y) - touchDegreeFromX;
touchDegreeFromX += turnDegree;
Log.i("CCY", "    turnDegree=" + turnDegree
+ "     Angle45Degree=" + Angle45Degree);
for (FunctionIcon fi : fiList) {
if (turnDegree > 0) { 
fi.mindegree = fi.mindegree + turnDegree > 2 * Math.PI ? fi.mindegree
+ turnDegree - 2 * Math.PI
: fi.mindegree + turnDegree;
fi.translateDegree = fi.translateDegree + turnDegree > 2 * Math.PI ? fi.translateDegree
+ turnDegree - 2 * Math.PI
: fi.translateDegree + turnDegree;
fi.rotateDegree = (float) (fi.rotateDegree + turnDegree > 2 * Math.PI ? fi.rotateDegree
+ turnDegree - 2 * Math.PI
: fi.rotateDegree + turnDegree);
} else { 
fi.mindegree = fi.mindegree + turnDegree < 0 ? fi.mindegree
+ turnDegree + 2 * Math.PI
: fi.mindegree + turnDegree;
fi.translateDegree = fi.translateDegree + turnDegree < 0 ? fi.translateDegree
+ turnDegree + 2 * Math.PI
: fi.translateDegree + turnDegree;
fi.rotateDegree = (float) (fi.rotateDegree + turnDegree < 0 ? fi.rotateDegree
+ turnDegree + 2 * Math.PI
: fi.rotateDegree + turnDegree);
}
}
}
// 刷新界面
invalidate();
break;
case MotionEvent.ACTION_UP:
if (touchInTurnTable
&& downInTurnTable
&& Math.abs(Math.atan2(x, y) - _touchDegreeFromX) < Math.PI / 5) {
for (int i = 0; i < 5; i++) {
if (fiList.get(i).mindegree < touchDegreeFromX
&& fiList.get((i + 1) % 5).mindegree > touchDegreeFromX) {
fiList.get(i).click = true;
invalidate();
// getContext()
// .startActivity(
// new Intent(getContext(),
// fiList.get(i).activity));
// 点击图标,打开相应的图标
// if (fiList.get(i).activity
// .equals(AppLockActivity.class)
// && !getContext()
// .getSharedPreferences("bbmf_hyman",
// Activity.MODE_PRIVATE)
// .getString("password", "").equals("")) {
// Intent intent = new Intent(getContext(),
// AppLockCheckPwdActivity.class);
// intent.putExtra("fromHomeToOpenAppLock", true);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
// | Intent.FLAG_ACTIVITY_CLEAR_TOP);
// getContext().startActivity(intent);
// }
}
}
}
if (touchInCenterAre && downInCenterAre) {
showHelp(TurnTable.context);
}
if (touchInTurnTable) {
touchInTurnTable = false;
}
if (touchInCenterAre) {
touchInCenterAre = false;
}
break;
}
return true;
}
补充:移动开发 ,  Android
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,