旋转拨号限制

所有
我想像下面的图像一样以特定的angular度旋转图像。 我有代码旋转,但它旋转360度,但我只想要特定的程度,并获得拨号上方选定的数字。

在这里输入图像说明

下面是我的代码。 我的习惯查看这项工作很好,但性能湖。

import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.PointF; import android.graphics.Rect; import android.util.AttributeSet; import android.util.Log; import android.view.GestureDetector.OnGestureListener; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.View; public class MyDialView extends View implements OnGestureListener{ private static Bitmap bimmap; private static Paint paint; private static Rect bounds; private int totalNicks = 100; private int currentNick = 0; private GestureDetector gestureDetector; private float dragStartDeg = Float.NaN; float dialerWidth = 0,dialerHeight = 0; private static Paint createDefaultPaint() { Paint paint = new Paint(); paint.setAntiAlias(true); paint.setFilterBitmap(true); return paint; } private float xyToDegrees(float x, float y) { float distanceFromCenter = PointF.length((x - 0.5f), (y - 0.5f)); if (distanceFromCenter < 0.1f || distanceFromCenter > 0.5f) { // ignore center and out of bounds events return Float.NaN; } else { return (float) Math.toDegrees(Math.atan2(x - 0.5f, y - 0.5f)); } } public final float getRotationInDegrees() { return (360.0f / totalNicks) * currentNick; } public final void rotate(int nicks) { currentNick = (currentNick + nicks); if (currentNick >= totalNicks) { currentNick %= totalNicks; } else if (currentNick < 0) { currentNick = (totalNicks + currentNick); } Log.e("Current nick", String.valueOf(currentNick)); if((currentNick > 80 || currentNick < 20)){ invalidate(); } } public MyDialView(Context context, AttributeSet attrs) { super(context, attrs); bimmap = BitmapFactory.decodeResource(context.getResources(),R.drawable.out_round); paint = createDefaultPaint(); gestureDetector = new GestureDetector(getContext(), this); dialerWidth = bimmap.getWidth() /2.0f; dialerHeight = bimmap.getHeight() / 2.0f; bounds = new Rect(); } @Override protected void onDraw(Canvas canvas) { canvas.getClipBounds(bounds); canvas.save(Canvas.MATRIX_SAVE_FLAG); //{ canvas.translate(bounds.left, bounds.top); float rotation = getRotationInDegrees(); canvas.rotate(rotation, dialerWidth, dialerHeight); canvas.drawBitmap(bimmap, 0,0,null); //canvas.rotate(- rotation, dialerWidth, dialerHeight); //} canvas.restore(); } @Override public boolean onTouchEvent(MotionEvent event) { if (gestureDetector.onTouchEvent(event)) { return true; } else { return super.onTouchEvent(event); } } //Gesture detector methods @Override public boolean onDown(MotionEvent e) { float x = e.getX() / ((float) getWidth()); float y = e.getY() / ((float) getHeight()); dragStartDeg = xyToDegrees(x, y); //Log.d("deg = " , ""+dragStartDeg); if (! Float.isNaN(dragStartDeg)) { return true; } else { return false; } } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } @Override public void onLongPress(MotionEvent e) { } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { if (! Float.isNaN(dragStartDeg)) { float currentDeg = xyToDegrees(e2.getX() / getWidth(), e2.getY() / getHeight()); if (! Float.isNaN(currentDeg)) { float degPerNick = 360.0f / totalNicks; float deltaDeg = dragStartDeg - currentDeg; final int nicks = (int) (Math.signum(deltaDeg) * Math.floor(Math.abs(deltaDeg) / degPerNick)); if (nicks != 0) { dragStartDeg = currentDeg; rotate(nicks); } } return true; } else { return false; } } @Override public void onShowPress(MotionEvent e) { } @Override public boolean onSingleTapUp(MotionEvent e) { return false; } } 

我想根据用户select0-9,也允许用户旋转到0-9不再旋转。

我也检查下面的另一个代码。

 dialer = (ImageView) findViewById(R.id.imageView_ring); dialer.setOnTouchListener(new MyOnTouchListener()); dialer.getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { // method called more than once, but the values only need to be initialized one time if (dialerHeight == 0 || dialerWidth == 0) { dialerHeight = dialer.getHeight(); dialerWidth = dialer.getWidth(); // resize Matrix resize = new Matrix(); resize.postScale((float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getWidth(), (float)Math.min(dialerWidth, dialerHeight) / (float)imageOriginal.getHeight()); imageScaled = Bitmap.createBitmap(imageOriginal, 0, 0, imageOriginal.getWidth(), imageOriginal.getHeight(), resize, false); // translate to the image view's center float translateX = dialerWidth / 2 - imageScaled.getWidth() / 2; float translateY = dialerHeight / 2 - imageScaled.getHeight() / 2; matrix.postTranslate(translateX, translateY); dialer.setImageBitmap(imageScaled); dialer.setImageMatrix(matrix); Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber)); } } }); int tickNumber = 0; private void rotateDialer(float degrees) { //System.out.println("Rotation Done :: "+rotationDone); // if(!rotationDone) { this.rotationDegrees += degrees; this.rotationDegrees = this.rotationDegrees % 360; tickNumber = (int)this.rotationDegrees*100/360; // It could be negative if (tickNumber > 0) tickNumber = 100 - tickNumber; //this.rotationDegrees = Math.abs(rotationDegrees); this.tickNumber = Math.abs(tickNumber); if(tickNumber < 20 || tickNumber > 80){ Log.e("Rotation degree :"+rotationDegrees, String.valueOf(tickNumber)); matrix.postRotate(degrees, dialerWidth / 2, dialerHeight / 2); dialer.setImageMatrix(matrix); } // } } /** * @return The angle of the unit circle with the image view's center */ private double getAngle(double xTouch, double yTouch) { double delta_x = xTouch - (dialerWidth) /2; double delta_y = (dialerHeight) /2 - yTouch; double radians = Math.atan2(delta_y, delta_x); double dx = xTouch - dWidth; double dy = (dHeight - ((dialerHeight) /2)) - yTouch; double dRadi = Math.atan2(dy, dx); //Log.e("MY degree", String.valueOf( Math.toDegrees(dRadi))); //return Math.toDegrees(dRadi); return Math.toDegrees(radians); } /** * Simple implementation of an {@link OnTouchListener} for registering the dialer's touch events. */ private class MyOnTouchListener implements OnTouchListener { private double startAngle; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // reset the touched quadrants /*for (int i = 0; i < quadrantTouched.length; i++) { quadrantTouched[i] = false; }*/ //allowRotating = false; startAngle = getAngle(event.getX(), event.getY()); break; case MotionEvent.ACTION_MOVE: /*double rotationAngleRadians = Math.atan2(event.getX() - (dialer.getWidth() / 2 ), ( (dialer.getHeight() / 2 ) - event.getY())); double angle = (int) Math.toDegrees(rotationAngleRadians); Log.i("gg", "rotaion angle"+angle);*/ double currentAngle = getAngle(event.getX(), event.getY()); //if(currentAngle < 130 || currentAngle < 110){ //Log.e("Start angle :"+startAngle, "Current angle:"+currentAngle); rotateDialer((float) (startAngle - currentAngle)); startAngle = currentAngle; //} //Log.e("MOVE start Degree:"+startAngle, "Current Degree :"+currentAngle); break; case MotionEvent.ACTION_UP: //allowRotating = true; break; } // set the touched quadrant to true //quadrantTouched[getQuadrant(event.getX() - (dialerWidth / 2), dialerHeight - event.getY() - (dialerHeight / 2))] = true; //detector.onTouchEvent(event); return true; } } 

Solutions Collecting From Web of "旋转拨号限制"

我不明白你的问题。 下面的代码将图像旋转48度。

 ImageView dialer = (ImageView) findViewById(R.id.imageView_ring); int degrees = 48; Matrix matrix = new Matrix(); matrix.setRotate(degrees); Bitmap bmpBowRotated = Bitmap.createBitmap(imageOrginal, 0, 0, imageOrginal.getWidth(),imageOrginal.getHeight(), matrix, false); dialer.setImageBitmap(bmpBowRotated); 

嗨Girish有一个类命名RotateAnimation通过使用这个类,你可以轻松地做到这一点

  look Example like RotateAnimation r = new RotateAnimation(0f, -90f,200,200); // HERE r.setStartOffset(1000); r.setDuration(1000); r.setFillAfter(true); //HERE animationSet.addAnimation(r); 

我想先知道将会有什么部署? 它允许操纵Evenets吗? 如果是,那么你得到处理ManipulationStatring和ManipulationDelta事件来旋转元素。
如果在Manipulation不可用的情况下没有这种情况,那么你可以尝试使用RenderTransformation属性,RorateTransform的元素是你正在使用的WPf。

我能够通过对代码进行以下几个调整来实现这一点

  1. 让用户始终点击箭头始终获得箭头放置的初始angular度,在你的情况90度 ,否则返回false

  2. 同样保存用户移开他的手指的angular度,并将该angular度用作他下一次触摸的初始值,就像他将箭头放在100度时一样,使他的初始触摸位置再次启动旋转

  3. 现在检查他的答案,把你的数字0到9放置的angular度,即时猜测你的值从0到9的120度,将这个angular度除以10,你可以很容易地找出什么angular度代表了什么值,并得到你的结果

同样触及到90度开始旋转是非常刺激的,所以总是检查90°+ 4和90°开始的值,但始终使用90°作为起始angular度 初始位置在0移动了60度