Custom Knob View zur Lautstärkeregelung?
Ich möchte den Fortschrittsbalken um den Knopf herum anzeigen. Nachdem ich diesem Tutorial gefolgt war, habe ich dieses @ erstell Knopf es funktioniert gut.
Aber wie könnte ich den obigen Knopf so ändern, dass er wie das zweite Bild aussieht?
Der Ausführungscode für den ersten Knopf ist unten angegeben.
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.MeasureSpec;
import android.view.MotionEvent;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.RelativeLayout;
public class RoundKnobButton extends RelativeLayout implements
OnGestureListener
{
public int eventValue=10;
//doctory starts
Paint p1,p2,p3;
RectF oval;
int width;
//doctory ends
private GestureDetector gestureDetector;
private float mAngleDown, mAngleUp;
private ImageView ivRotor;
private Bitmap bmpRotorOn, bmpRotorOff;
private boolean mState = false;
private int m_nWidth = 0, m_nHeight = 0;
public interface RoundKnobButtonListener
{
public void onStateChange(boolean newstate);
public void onRotate(int percentage);
}
private RoundKnobButtonListener m_listener;
public void SetListener(RoundKnobButtonListener l)
{
m_listener = l;
}
public void SetState(boolean state)
{
mState = state;
ivRotor.setImageBitmap(state ? bmpRotorOn : bmpRotorOff);
}
public RoundKnobButton(Context context, int back, int rotoron,
int rotoroff, final int w, final int h) {
super(context);
//doctory starts
width = w;
p1 = new Paint(1);
p1.setColor(Color.rgb(86, 86, 86));
p1.setStyle(android.graphics.Paint.Style.FILL);
p2 = new Paint(1);
p2.setColor(Color.rgb(245, 109, 89));
p2.setStyle(android.graphics.Paint.Style.FILL);
p3 = new Paint(1);
p3.setColor(Color.GREEN);
p3.setStyle(android.graphics.Paint.Style.STROKE);
oval = new RectF();
//doctory ends...
// we won't wait for our size to be calculated, we'll just store out
// fixed size
m_nWidth = w;
m_nHeight = h;
// create stator
ImageView ivBack = new ImageView(context);
ivBack.setImageResource(back);
RelativeLayout.LayoutParams lp_ivBack = new RelativeLayout.LayoutParams(
w, h);
lp_ivBack.addRule(RelativeLayout.CENTER_IN_PARENT);
addView(ivBack, lp_ivBack);
// load rotor images
Bitmap srcon = BitmapFactory.decodeResource(context.getResources(),
rotoron);
Bitmap srcoff = BitmapFactory.decodeResource(context.getResources(),
rotoroff);
float scaleWidth = ((float) w) / srcon.getWidth();
float scaleHeight = ((float) h) / srcon.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
bmpRotorOn = Bitmap.createBitmap(srcon, 0, 0, srcon.getWidth(),
srcon.getHeight(), matrix, true);
bmpRotorOff = Bitmap.createBitmap(srcoff, 0, 0, srcoff.getWidth(),
srcoff.getHeight(), matrix, true);
// create rotor
ivRotor = new ImageView(context);
ivRotor.setImageBitmap(bmpRotorOn);
RelativeLayout.LayoutParams lp_ivKnob = new RelativeLayout.LayoutParams(
w, h);// LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
lp_ivKnob.addRule(RelativeLayout.CENTER_IN_PARENT);
addView(ivRotor, lp_ivKnob);
// set initial state
SetState(mState);
// enable gesture detector
gestureDetector = new GestureDetector(getContext(), this);
}
/**
* math..
*
* @param x
* @param y
* @return
*/
private float cartesianToPolar(float x, float y) {
return (float) -Math.toDegrees(Math.atan2(x - 0.5f, y - 0.5f));
}
@Override
public boolean onTouchEvent(MotionEvent event) {
if (gestureDetector.onTouchEvent(event))
return true;
else
return super.onTouchEvent(event);
}
public boolean onDown(MotionEvent event)
{
float x = event.getX() / ((float) getWidth());
float y = event.getY() / ((float) getHeight());
mAngleDown = cartesianToPolar(1 - x, 1 - y);// 1- to correct our custom
// axis direction
return true;
}
public boolean onSingleTapUp(MotionEvent e)
{
float x = e.getX() / ((float) getWidth());
float y = e.getY() / ((float) getHeight());
mAngleUp = cartesianToPolar(1 - x, 1 - y);// 1- to correct our custom
// axis direction
// if we click up the same place where we clicked down, it's just a
// button press
if (!Float.isNaN(mAngleDown) && !Float.isNaN(mAngleUp)
&& Math.abs(mAngleUp - mAngleDown) < 10) {
SetState(!mState);
if (m_listener != null)
m_listener.onStateChange(mState);
}
return true;
}
public void setRotorPosAngle(float deg)
{
if (deg >= 210 || deg <= 150)
{
if (deg > 180)
deg = deg - 360;
Matrix matrix = new Matrix();
ivRotor.setScaleType(ScaleType.MATRIX);
// matrix.postRotate((float) deg, 210 / 2, 210 / 2);// getWidth()/2,
// getHeight()/2);
matrix.postRotate((float) deg, m_nWidth/2, m_nHeight/2);//getWidth()/2, getHeight()/2);
ivRotor.setImageMatrix(matrix);
}
}
public void setRotorPercentage(int percentage)
{
int posDegree = percentage * 3 - 150;
if (posDegree < 0)
posDegree = 360 + posDegree;
setRotorPosAngle(posDegree);
}
public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
float distanceY) {
float x = e2.getX() / ((float) getWidth());
float y = e2.getY() / ((float) getHeight());
float rotDegrees = cartesianToPolar(1 - x, 1 - y);// 1- to correct our
// custom axis
// direction
if (!Float.isNaN(rotDegrees)) {
// instead of getting 0-> 180, -180 0 , we go for 0 -> 360
float posDegrees = rotDegrees;
if (rotDegrees < 0)
posDegrees = 360 + rotDegrees;
// deny full rotation, start start and stop point, and get a linear
// scale
if (posDegrees > 210 || posDegrees < 150) {
// rotate our imageview
setRotorPosAngle(posDegrees);
// get a linear scale
float scaleDegrees = rotDegrees + 150; // given the current
// parameters, we go
// from 0 to 300
// get position percent
int percent = (int) (scaleDegrees / 3);
if (m_listener != null)
m_listener.onRotate(percent);
return true; // consumed
} else
return false;
} else
return false; // not consumed
}
public void onShowPress(MotionEvent e) {
// TODO Auto-generated method stub
}
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
return false;
}
public void onLongPress(MotionEvent e) {
}
/*@Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
int i = width / 4;
oval.set(i - i / 2, i / 2, i * 3 + i / 2, i * 3 + i / 2);
canvas.drawOval(oval, p1);
canvas.drawArc(oval, -90F, (int)Math.round((360D * Double.valueOf(eventValue).doubleValue()) / 100D), true, p2);
canvas.drawLine(20, 30, 120, 200, p2);
}*/
/*@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
int desiredWidth = width;
int desiredHeight = width;
int widthMode = android.view.View.MeasureSpec.getMode(widthMeasureSpec);
int widthSize = android.view.View.MeasureSpec.getSize(widthMeasureSpec);
int heightMode = android.view.View.MeasureSpec.getMode(heightMeasureSpec);
int heightSize = android.view.View.MeasureSpec.getSize(heightMeasureSpec);
int measuredWidth;
int measuredHeight;
if (widthMode == MeasureSpec.EXACTLY)
{
measuredWidth = widthSize ;
}
else if (widthMode == MeasureSpec.AT_MOST)
{
measuredWidth = Math.min(desiredWidth , widthSize);
}
else
{
measuredWidth = desiredWidth;
}
if (heightMode == MeasureSpec.EXACTLY)
{
measuredHeight = heightSize ;
}
else if (heightMode == MeasureSpec.AT_MOST)
{
measuredHeight = Math.min(desiredHeight, heightSize );
}
else
{
measuredHeight = desiredHeight;
}
setMeasuredDimension(measuredWidth, measuredHeight);
}
*/
}
Ich habe die onDraw- und onMeasure-Funktion function erstellt und versuche, den äußeren Fortschritt zu zeichnen, oder wie könnte ich ihn ändern.
Bearbeite
Ist es möglich, den Rotationsprozentsatz auf 20 zu ändern? Ich meine, es zeigt den Fortschritt von 0 bis 99. Ist es möglich, es in 0 bis 12 umzuwandeln?