Rotar diseño de trama que contiene botones dinámicos

Tengo un Framelayout que añadir cuatro imageview en tiempo de ejecución, así en el centro que contiene la imagen principal con el que el usuario puede realizar diferentes acciones, pero me enfrentan al problema con rotar vista de diseño

Actualmente en el tacto del botón del giro estoy haciendo esto

public void setRotateListener() { mRotateImage.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { float x = event.getX(0); float y = event.getY(0); float theta = getTheta(x, y); switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_POINTER_DOWN: theta_old = theta; break; case MotionEvent.ACTION_MOVE: float delta_theta = theta - theta_old; theta_old = theta; int direction = (delta_theta > 0) ? 1 : -1; angle += 3 * direction; Log.d("Tag", "rotate angle : " + obj.getHeight()); obj.setRotation(angle); notifyListener(direction); break; } return true; } }); } private float getTheta(float x, float y) { float sx = x - (obj.getWidth() / 2.0f); float sy = y - (obj.getHeight() / 2.0f); float length = (float) Math.sqrt(sx * sx + sy * sy); float nx = sx / length; float ny = sy / length; float theta = (float) Math.atan2(ny, nx); final float rad2deg = (float) (180.0 / Math.PI); float thetaDeg = theta * rad2deg; return (thetaDeg < 0) ? thetaDeg + 360.0f : thetaDeg; } 

Pero no puedo obtener el resultado esperado ya me refiero a este enlace, así https://github.com/rprouse/XkcdClock , así como tratar de rotar con el gesto y la animación también, pero parece que no funciona como por mi movimiento en la pantalla Mientras que en el tacto el botón de la rotación quiere girar la visión entera en ambos sentido reloj y antihorario

Tengo Diseño Un Diseño que puede funcionar como su necesidad. Descargar Demo aquí

Archivo Java

 import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorMatrixColorFilter; import android.graphics.Paint; import android.view.GestureDetector; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.RelativeLayout; public class ClipArt extends RelativeLayout { int baseh; int basew; int basex; int basey; ImageButton btndel; ImageButton btnrot; ImageButton btnscl; RelativeLayout clip; Context cntx; boolean freeze = false; int h; int i; ImageView image; String imageUri; boolean isShadow; int iv; RelativeLayout layBg; RelativeLayout layGroup; RelativeLayout.LayoutParams layoutParams; public LayoutInflater mInflater; int margl; int margt; float opacity = 1.0F; Bitmap originalBitmap; int pivx; int pivy; int pos; Bitmap shadowBitmap; float startDegree; String[] v; public ClipArt(Context paramContext) { super(paramContext); cntx = paramContext; layGroup = this; basex = 0; basey = 0; pivx = 0; pivy = 0; mInflater = ((LayoutInflater) paramContext.getSystemService("layout_inflater")); mInflater.inflate(R.layout.clipart, this, true); btndel = ((ImageButton) findViewById(R.id.del)); btnrot = ((ImageButton) findViewById(R.id.rotate)); btnscl = ((ImageButton) findViewById(R.id.sacle)); layoutParams = new RelativeLayout.LayoutParams(250, 250); layGroup.setLayoutParams(layoutParams); image = ((ImageView) findViewById(R.id.clipart)); image.setImageResource(R.drawable.ic_launcher); setOnTouchListener(new View.OnTouchListener() { final GestureDetector gestureDetector = new GestureDetector(ClipArt.this.cntx, new GestureDetector.SimpleOnGestureListener() { public boolean onDoubleTap(MotionEvent paramAnonymous2MotionEvent) { return false; } }); public boolean onTouch(View paramAnonymousView, MotionEvent event) { if (!ClipArt.this.freeze) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: layGroup.invalidate(); gestureDetector.onTouchEvent(event); layGroup.performClick(); basex = ((int) (event.getRawX() - layoutParams.leftMargin)); basey = ((int) (event.getRawY() - layoutParams.topMargin)); break; case MotionEvent.ACTION_MOVE: int i = (int) event.getRawX(); int j = (int) event.getRawY(); layBg = ((RelativeLayout) getParent()); if ((i - basex > -(layGroup.getWidth() * 2 / 3)) && (i - basex < layBg.getWidth() - layGroup.getWidth() / 3)) { layoutParams.leftMargin = (i - basex); } if ((j - basey > -(layGroup.getHeight() * 2 / 3)) && (j - basey < layBg.getHeight() - layGroup.getHeight() / 3)) { layoutParams.topMargin = (j - basey); } layoutParams.rightMargin = -1000; layoutParams.bottomMargin = -1000; layGroup.setLayoutParams(layoutParams); break; } return true; } return true; } }); this.btnscl.setOnTouchListener(new View.OnTouchListener() { @SuppressLint({ "NewApi" }) public boolean onTouch(View paramAnonymousView, MotionEvent event) { if (!ClipArt.this.freeze) { int j = (int) event.getRawX(); int i = (int) event.getRawY(); layoutParams = (RelativeLayout.LayoutParams) layGroup.getLayoutParams(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: ClipArt.this.layGroup.invalidate(); ClipArt.this.basex = j; ClipArt.this.basey = i; ClipArt.this.basew = ClipArt.this.layGroup.getWidth(); ClipArt.this.baseh = ClipArt.this.layGroup.getHeight(); int[] loaction = new int[2]; layGroup.getLocationOnScreen(loaction); margl = layoutParams.leftMargin; margt = layoutParams.topMargin; break; case MotionEvent.ACTION_MOVE: float f2 = (float) Math.toDegrees(Math.atan2(i - ClipArt.this.basey, j - ClipArt.this.basex)); float f1 = f2; if (f2 < 0.0F) { f1 = f2 + 360.0F; } j -= ClipArt.this.basex; int k = i - ClipArt.this.basey; i = (int) (Math.sqrt(j * j + k * k) * Math.cos(Math.toRadians(f1 - ClipArt.this.layGroup.getRotation()))); j = (int) (Math.sqrt(i * i + k * k) * Math.sin(Math.toRadians(f1 - ClipArt.this.layGroup.getRotation()))); k = i * 2 + ClipArt.this.basew; int m = j * 2 + ClipArt.this.baseh; if (k > 150) { layoutParams.width = k; layoutParams.leftMargin = (ClipArt.this.margl - i); } if (m > 150) { layoutParams.height = m; layoutParams.topMargin = (ClipArt.this.margt - j); } ClipArt.this.layGroup.setLayoutParams(layoutParams); ClipArt.this.layGroup.performLongClick(); break; } return true; } return ClipArt.this.freeze; } }); this.btnrot.setOnTouchListener(new View.OnTouchListener() { @SuppressLint({ "NewApi" }) public boolean onTouch(View paramAnonymousView, MotionEvent event) { if (!ClipArt.this.freeze) { layoutParams = (RelativeLayout.LayoutParams) ClipArt.this.layGroup.getLayoutParams(); ClipArt.this.layBg = ((RelativeLayout) ClipArt.this.getParent()); int[] arrayOfInt = new int[2]; layBg.getLocationOnScreen(arrayOfInt); int i = (int) event.getRawX() - arrayOfInt[0]; int j = (int) event.getRawY() - arrayOfInt[1]; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: ClipArt.this.layGroup.invalidate(); ClipArt.this.startDegree = layGroup.getRotation(); ClipArt.this.pivx = (layoutParams.leftMargin + ClipArt.this.getWidth() / 2); ClipArt.this.pivy = (layoutParams.topMargin + ClipArt.this.getHeight() / 2); ClipArt.this.basex = (i - ClipArt.this.pivx); ClipArt.this.basey = (ClipArt.this.pivy - j); break; case MotionEvent.ACTION_MOVE: int k = ClipArt.this.pivx; int m = ClipArt.this.pivy; j = (int) (Math.toDegrees(Math.atan2(ClipArt.this.basey, ClipArt.this.basex)) - Math.toDegrees(Math.atan2(m - j, i - k))); i = j; if (j < 0) { i = j + 360; } ClipArt.this.layGroup.setRotation((ClipArt.this.startDegree + i) % 360.0F); break; } return true; } return ClipArt.this.freeze; } }); this.btndel.setOnClickListener(new View.OnClickListener() { public void onClick(View paramAnonymousView) { if (!ClipArt.this.freeze) { layBg = ((RelativeLayout) ClipArt.this.getParent()); layBg.performClick(); layBg.removeView(ClipArt.this.layGroup); } } }); } public void disableAll() { this.btndel.setVisibility(4); this.btnrot.setVisibility(4); this.btnscl.setVisibility(4); } public ImageView getImageView() { return this.image; } public void setFreeze(boolean paramBoolean) { this.freeze = paramBoolean; } } 

Archivo de diseño

 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <ImageButton android:id="@+id/rotate" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:adjustViewBounds="true" android:background="@android:color/transparent" android:scaleType="fitCenter" android:src="@drawable/rotation"/> <ImageButton android:id="@+id/sacle" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentBottom="true" android:layout_alignParentRight="true" android:adjustViewBounds="true" android:background="@android:color/transparent" android:scaleType="fitCenter" android:src="@drawable/pointer"/> <ImageButton android:id="@+id/del" android:layout_width="50dp" android:layout_height="50dp" android:layout_alignParentRight="true" android:layout_alignParentTop="true" android:adjustViewBounds="true" android:background="@android:color/transparent" android:scaleType="fitCenter" android:src="@drawable/close"/> <ImageView android:id="@+id/clipart" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="10dp"/> </RelativeLayout> 

E imágenes puestas

Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen Introduzca aquí la descripción de la imagen

  • Cómo rotar vistas sobre el cambio de orientación sin volver a crear el diseño?
  • ¿Por qué se rota una imagen capturada con la intención de la cámara en algunos dispositivos de Android?
  • Rotar vídeo con mp4parser de acuerdo con la cámara utilizada
  • Android Mejor forma de evitar Diálogos para descartar después de una rotación del dispositivo
  • Cómo rotar el mapa de bits correctamente?
  • Android Rotación de MapView
  • Cómo hacer menú giratorio
  • Rotación de imagen con opencv en android corta los bordes de una imagen
  • Android girar imageview, no puedo establecer la posición final de imageview en onAnimationEnd ()
  • Cómo rotar un dibujable por ObjectAnimator?
  • Rotar un ImageView como una brújula (con el "polo norte" puesto en otro lugar)
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.