自绘制View---------原型旋转刻度调频View
代码种使用:
private CircleView mCircleView = null; ...... mCircleView = new CircleView(this, mHandler); RelativeLayout rela = (RelativeLayout)findViewById(R.id.rl_middlepart); rela.addView(mCircleView);
自绘制View实现代码如下:
package com.mediatek.fmradio; import java.util.StringTokenizer; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.LinearGradient; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Paint.Align; import android.graphics.Path; import android.graphics.Shader; import android.graphics.Typeface; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.format.Time; import android.util.AttributeSet; import android.util.Log; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; public class CircleView extends View { private static final String TAG = "CircleView"; private final Paint mPaint = new Paint(); private final double FM_STATION_FIELD = 108.0-87.5; private int mOuterCircleColor; private int mInnerCircleColor; private int mDotColor; private int mTextMHzColor; private int mStrTextWarnColor; private float mCircleRadiusOrange; private float mCircleRadiusBlack; private float mCircleRadiusPointer; private float mCircleRadiusThumb; private boolean mIsInitialized; private boolean mDrawValuesReady; private float mXMore; private float mYMore; private int mXCompass; private int mYCompass; private int mXEarphoneLeft; private int mYEarphoneLeft; private int mXEarphoneRight; private int mYEarphoneRight; private float mXSVFirst; private float mYSVFirst; private float mXSVSecond; private float mYSVSecond; private float mXSVThird; private float mYSVThird; private float mXSVPoint; private float mYSVPoint; private float mXSVFourth; private float mYSVFourth; private float mXStar; private float mYStar; private float mXCenter; private float mYCenter; private float mXTouch; private float mYTouch; private float mXThumb; private float mYThumb; private double mRadian; private double mRadianJudge; private int mOuterCircleRadius; private int mInnerCircleRadius; private float mTextMHzSize; private float mStrTextWarnSize; private float[] mTextGridHeights; private float[] mTextGridWidths; private Resources mRes; private Bitmap mSVNBitmapPoint; private Bitmap mBitmapCompass; private Bitmap mBitmapCompassPointer; private Bitmap mBitmapCompassThumb; private Bitmap mEarphoneLeft; private Bitmap mEarphoneRight; private Bitmap mBitmapEarphoneLeft; private Bitmap mBitmapEarphoneLeftNo; private Bitmap mBitmapEarphoneRight; private Bitmap mBitmapEarphoneRightNo; private Bitmap mBitmapFavoriteOff; private Bitmap mBitmapFavoriteOn; private Bitmap mBitmapFavorite; private int mXTextMHzMargin; private int mYTextMHzMargin; private int mXFM; private int mYFM; private int mXWarn; private int mYWarn; private int mXTextWarn; private int mYTextWarn; private int mXOscillo; private int mYOscillo; private String mStrStationValue; private String[] mStrStationValueNums; private Bitmap[] mSVNBitmaps; private String[] mRecordTimeNums; private Bitmap mFMBitmap; private Bitmap mWarnBitmap; private Bitmap mOscilloBitmap; private String mStrTextWarn; private String mStrTextFM; private String mStrTextMHZ; private String mStrTextRDS; private String mStrStationName; private boolean mBoolFavoriteState; private boolean mBoolFavoriteMode; private boolean mBoolDisplayState; private boolean mBoolClickState; private Handler mHandler; Message mMessage; Bundle mBundle; public CircleView(Context context) { super(context); } public CircleView(Context context, final Handler mHandler) { super(context); this.mHandler = mHandler; mBundle = new Bundle(); Log.i(TAG, "CircleView initialized ."); mRes = context.getResources(); mOuterCircleColor = mRes.getColor(R.color.black); mInnerCircleColor = mRes.getColor(R.color.orange); mDotColor = mRes.getColor(R.color.orange); mTextMHzColor = mRes.getColor(R.color.mhz_text_color); mStrTextWarnColor = mRes.getColor(R.color.warn_text_color); mXCompass = (int) mRes.getDimension(R.dimen.compass_xcoord); mYCompass = (int) mRes.getDimension(R.dimen.compass_ycoord); mXEarphoneLeft = (int) mRes.getDimension(R.dimen.earphone_left_xcoord); mYEarphoneLeft = (int) mRes.getDimension(R.dimen.earphone_left_ycoord); mXEarphoneRight = (int) mRes.getDimension(R.dimen.earphone_right_xcoord); mYEarphoneRight = (int) mRes.getDimension(R.dimen.earphone_right_ycoord); mXStar = (int) mRes.getDimension(R.dimen.star_xcoord); mYStar = (int) mRes.getDimension(R.dimen.star_ycoord); mXSVFirst = (int) mRes.getDimension(R.dimen.first_xcoord); mYSVFirst = (int) mRes.getDimension(R.dimen.first_ycoord); mXSVSecond = (int) mRes.getDimension(R.dimen.second_xcoord); mYSVSecond = (int) mRes.getDimension(R.dimen.second_ycoord); mXSVThird = (int) mRes.getDimension(R.dimen.third_xcoord); mYSVThird = (int) mRes.getDimension(R.dimen.third_ycoord); mXSVPoint = (int) mRes.getDimension(R.dimen.point_xcoord); mYSVPoint = (int) mRes.getDimension(R.dimen.point_ycoord); mXSVFourth = (int) mRes.getDimension(R.dimen.fourth_xcoord); mYSVFourth = (int) mRes.getDimension(R.dimen.fourth_ycoord); mXFM = (int) mRes.getDimension(R.dimen.text_fm_xcoord); mYFM = (int) mRes.getDimension(R.dimen.text_fm_ycoord); mXWarn = (int) mRes.getDimension(R.dimen.warn_xcoord); mYWarn = (int) mRes.getDimension(R.dimen.warn_ycoord); mXTextWarn = (int) mRes.getDimension(R.dimen.text_warn_xcoord); mYTextWarn = (int) mRes.getDimension(R.dimen.text_warn_ycoord); mXOscillo = (int) mRes.getDimension(R.dimen.oscillo_graph_xcoord); mYOscillo = (int) mRes.getDimension(R.dimen.oscillo_graph_ycoord); mTextMHzSize = (int) mRes.getDimension(R.dimen.text_mhz_size); mStrTextWarnSize = (int) mRes.getDimension(R.dimen.text_warn_size); mXTextMHzMargin = (int) mRes.getDimension(R.dimen.text_mhz_xcoord_margin); mYTextMHzMargin = (int) mRes.getDimension(R.dimen.text_mhz_ycoord_margin); mCircleRadiusOrange = (int) mRes.getDimension(R.dimen.circle_radius_orange); mCircleRadiusBlack = (int) mRes.getDimension(R.dimen.circle_radius_black); mCircleRadiusPointer = (int) mRes.getDimension(R.dimen.circle_radius_pointer); mCircleRadiusThumb = (int) mRes.getDimension(R.dimen.circle_radius_thumb); mSVNBitmaps = new Bitmap[10]; mSVNBitmaps[0] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num0); mSVNBitmaps[1] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num1); mSVNBitmaps[2] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num2); mSVNBitmaps[3] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num3); mSVNBitmaps[4] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num4); mSVNBitmaps[5] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num5); mSVNBitmaps[6] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num6); mSVNBitmaps[7] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num7); mSVNBitmaps[8] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num8); mSVNBitmaps[9] = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num9); mSVNBitmapPoint = BitmapFactory.decodeResource(mRes, R.drawable.fm_station_num_point); mBitmapCompass = BitmapFactory.decodeResource(mRes, R.drawable.fm_compass); mBitmapCompassPointer = BitmapFactory.decodeResource(mRes, R.drawable.fm_compass_pointer); mBitmapCompassThumb = BitmapFactory.decodeResource(mRes, R.drawable.fm_compass_thumb); mBitmapEarphoneLeft = BitmapFactory.decodeResource(mRes, R.drawable.fm_earphone_left); mBitmapEarphoneLeftNo = BitmapFactory.decodeResource(mRes, R.drawable.fm_earphone_left_no); mEarphoneLeft = mBitmapEarphoneLeft; mBitmapEarphoneRight = BitmapFactory.decodeResource(mRes, R.drawable.fm_earphone_right); mBitmapEarphoneRightNo = BitmapFactory.decodeResource(mRes, R.drawable.fm_earphone_right_no); mEarphoneRight = mBitmapEarphoneRight; mBitmapFavoriteOff = BitmapFactory.decodeResource(mRes, R.drawable.fm_star); mBitmapFavoriteOn = BitmapFactory.decodeResource(mRes, R.drawable.fm_star_pressed); mBitmapFavorite = mBitmapFavoriteOff; mFMBitmap = BitmapFactory.decodeResource(mRes, R.drawable.fm_text_fm); mWarnBitmap = BitmapFactory.decodeResource(mRes, R.drawable.fm_warn); mOscilloBitmap = BitmapFactory.decodeResource(mRes, R.drawable.fm_oscillo_graph); mBoolFavoriteState = true; mBoolFavoriteMode = true; mBoolDisplayState = true; mBoolClickState = false; mStrStationValue = "87.5"; mStrStationName = ""; mStrTextWarn = mRes.getString(R.string.dlg_noantenna_text_new); mStrTextFM = "FM"; mStrTextMHZ = "MHz"; mStrTextRDS = ""; mRadian = 0; mRadianJudge = 0; mDrawValuesReady = false; } public CircleView(Context context, AttributeSet attrs) { super(context, attrs); } public CircleView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public String getStationValue() { return this.mStrStationValue; } public String getStationName() { return this.mStrStationName; } public boolean getFavoriteState() { return this.mBoolFavoriteState; } public boolean getFavoriteMode() { return this.mBoolFavoriteMode; } public void setFavoriteState(boolean fav_st) { this.mBoolFavoriteState = fav_st; if (this.mBoolFavoriteState) { mBitmapFavorite = mBitmapFavoriteOn; } else { mBitmapFavorite = mBitmapFavoriteOff; } updateCircleView(); } public void setFavoriteMode(boolean fav_md) { this.mBoolFavoriteMode = fav_md; updateCircleView(); } public void setDisplayState(boolean is_display) { this.mBoolDisplayState = is_display; updateCircleView(); } public void setTextMHz(String tx_mhz) { if (this.mStrTextMHZ == "") { this.mStrTextMHZ = tx_mhz; updateCircleView(); } } public void setTextFM(String tx_fm) { if (this.mStrTextFM == "") { this.mStrTextFM = tx_fm; updateCircleView(); } } public void setTextRDS(String tx_rds) { this.mStrTextRDS = tx_rds; updateCircleView(); } public void setStationValue(String st_v) { this.mStrStationValue = st_v; float mid = (float) (87.5 + ((108 - 87.5) / 2.0)); float stv = Float.parseFloat(this.mStrStationValue); if (stv < mid) { mRadian = (stv - 87.5) * 2 * Math.PI / FM_STATION_FIELD; mRadianJudge = mRadian; } else { mRadian = Math.PI - (108.0 - stv) * 2 * Math.PI / FM_STATION_FIELD; mRadianJudge = mRadian + Math.PI; } updateCircleView(); } public void setStationName(String st_n) { this.mStrStationName = st_n; updateCircleView(); } public void updateCircleView() { this.invalidate(); } @Override public void onDraw(Canvas canvas) { int viewWidth = getWidth(); if (viewWidth == 0) { return; } if (!mDrawValuesReady) { mXCenter = mXCompass + mBitmapCompass.getWidth() / 2; mYCenter = mYCompass + mBitmapCompass.getHeight() / 2; mDrawValuesReady = true; } /** Draw the compass */ canvas.drawBitmap(mBitmapCompass, mXCompass, mYCompass, mPaint); if (!mBoolDisplayState) { canvas.drawBitmap(mFMBitmap, mXFM, mYFM, mPaint); canvas.drawBitmap(mWarnBitmap, mXWarn, mYWarn, mPaint); mPaint.setColor(mStrTextWarnColor); mPaint.setTextSize(mStrTextWarnSize); canvas.drawText(mStrTextWarn, mXTextWarn, mYTextWarn, mPaint); mRadianJudge = 0; mRadian = 0; mEarphoneLeft = mBitmapEarphoneLeftNo; mEarphoneRight = mBitmapEarphoneRightNo; } else { mEarphoneLeft = mBitmapEarphoneLeft; mEarphoneRight = mBitmapEarphoneRight; //canvas.drawBitmap(mOscilloBitmap, mXOscillo, mYOscillo, mPaint); drawNumBitmap(canvas, mStrStationValue); if (mBoolFavoriteMode) { canvas.drawBitmap(mBitmapFavorite, mXStar, mYStar, mPaint); } mPaint.setColor(mTextMHzColor); mPaint.setTextSize(mTextMHzSize); canvas.drawText(mStrTextMHZ, mXSVFourth + mSVNBitmaps[4].getWidth() + mXTextMHzMargin, mYSVFourth + mSVNBitmaps[4].getHeight(), mPaint); } if (mRadianJudge < Math.PI) { mXTouch = (float) (mXCenter + (mCircleRadiusPointer) * Math.sin(mRadian)); mYTouch = (float) (mYCenter - (mCircleRadiusPointer) * Math.cos(mRadian)); mXThumb = (float) (mXCenter + (mCircleRadiusThumb) * Math.sin(mRadian)); mYThumb = (float) (mYCenter - (mCircleRadiusThumb) * Math.cos(mRadian)); } else { mXTouch = (float) (mXCenter - (mCircleRadiusPointer) * Math.sin(mRadian)); mYTouch = (float) (mYCenter + (mCircleRadiusPointer) * Math.cos(mRadian)); mXThumb = (float) (mXCenter - (mCircleRadiusThumb) * Math.sin(mRadian)); mYThumb = (float) (mYCenter + (mCircleRadiusThumb) * Math.cos(mRadian)); } Matrix matrix = new Matrix(); matrix.setRotate((float) (mRadianJudge * 180 / Math.PI), mXTouch, mYTouch); Bitmap bitmap2 = Bitmap .createBitmap(mBitmapCompassPointer, 0, 0, mBitmapCompassPointer.getWidth(), mBitmapCompassPointer.getHeight(), matrix, true); canvas.drawBitmap(bitmap2, mXTouch - bitmap2.getWidth() / 2, mYTouch - bitmap2.getHeight() / 2, mPaint); canvas.drawBitmap(mBitmapCompassThumb, mXThumb - mBitmapCompassThumb.getWidth() / 2, mYThumb - mBitmapCompassThumb.getHeight() / 2, mPaint); canvas.drawBitmap(mEarphoneLeft, mXEarphoneLeft, mYEarphoneLeft, mPaint); canvas.drawBitmap(mEarphoneRight, mXEarphoneRight, mYEarphoneRight, mPaint); } @Override public boolean onTouchEvent(MotionEvent event) { float mX = event.getX(); float mY = event.getY(); double thumblen = (Math.sqrt(Math.pow(mX - ((mXThumb + mXTouch) / 2), 2) + Math.pow(mY - ((mYThumb + mYTouch) / 2), 2))); if (thumblen < (mBitmapCompassThumb.getHeight() / 2) && (event.getAction() == MotionEvent.ACTION_DOWN)) { mBoolClickState = true; } if (event.getAction() == MotionEvent.ACTION_UP) { mBoolClickState = false; } double ilen = (Math.sqrt(Math.pow(mX - mXCenter, 2) + Math.pow(mY - mYCenter, 2))); if (mBoolDisplayState && (event.getAction() == MotionEvent.ACTION_UP) && mBoolFavoriteMode) { if (mX > mXStar && mX < mXStar + mBitmapFavorite.getWidth() * 2) { if (mY > mYStar && mY < mYStar + mBitmapFavorite.getHeight() * 2) { if (mBitmapFavorite == mBitmapFavoriteOn) { mBitmapFavorite = mBitmapFavoriteOff; mBoolFavoriteState = false; } else { mBitmapFavorite = mBitmapFavoriteOn; mBoolFavoriteState = true; } mBundle.putBoolean(FmRadioListener.KEY_STATION_LOVE, mBoolFavoriteState); mMessage = new Message(); mMessage.what = FmRadioListener.MSGID_LOVE_STATE_CHANGED; mMessage.setData(mBundle); mHandler.sendMessage(mMessage); this.invalidate(); return true; } } } if (ilen >= mCircleRadiusBlack / 3 && ilen <= (mCircleRadiusBlack) && mBoolClickState && (event.getAction() == MotionEvent.ACTION_MOVE) && mBoolFavoriteMode) { double iv = (mCircleRadiusPointer) / ilen; mXTouch = (float) ((mX - mXCenter) * iv + mXCenter); mYTouch = (float) ((mY - mYCenter) * iv + mYCenter); double mXTouchi = ((mX - mXCenter) * iv + mXCenter); double mYTouchi = ((mY - mYCenter) * iv + mYCenter); double xc = Math.sqrt(Math.pow(mXTouchi - mXCenter, 2) + Math.pow(mYTouchi - (mYCenter - (mCircleRadiusPointer)), 2)); double hd = 2 * Math.asin(xc / (2 * (mCircleRadiusPointer))); if (mXTouch < mXCenter) { mStrStationValue = String.format("%.1f", 108.0 - hd / (Math.PI * 2) * FM_STATION_FIELD); mRadian = Math.PI - hd; mRadianJudge = mRadian + Math.PI; } else { mStrStationValue = String.format("%.1f", 87.5 + hd / (Math.PI * 2) * FM_STATION_FIELD); mRadian = hd; mRadianJudge = mRadian; } mBundle.putInt(FmRadioListener.KEY_STATION_VALUE, (int) (Float.parseFloat(mStrStationValue) * 10)); mMessage = new Message(); mMessage.what = FmRadioListener.MSGID_MOVE_FINISHED; mMessage.setData(mBundle); mHandler.sendMessage(mMessage); } this.invalidate(); return true; } public void drawNumBitmap(Canvas canvas, String stationvalue) { int sta_num = (int) (Float.parseFloat(mStrStationValue) * 10); if (sta_num / 1000 > 0) { canvas.drawBitmap(mSVNBitmaps[sta_num / 1000], mXSVFirst, mYSVFirst, mPaint); } sta_num = sta_num % 1000; canvas.drawBitmap(mSVNBitmaps[sta_num / 100], mXSVSecond, mYSVSecond, mPaint); sta_num = sta_num % 100; canvas.drawBitmap(mSVNBitmaps[sta_num / 10], mXSVThird, mYSVThird, mPaint); canvas.drawBitmap(mSVNBitmapPoint, mXSVPoint, mYSVPoint, mPaint); sta_num = sta_num % 10; canvas.drawBitmap(mSVNBitmaps[sta_num / 1], mXSVFourth, mYSVFourth, mPaint); } }