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
- Después de la rotación de la pantalla, se cambiará el idioma de mi aplicación
- Uso de Matrix. Rotar en OpenGL ES 2.0
- Android, ayuda a girar la imagen en el tacto
- Cuando giro la imagen a 45 grados de superposición que sale de los límites en android
- EditText duplicado en rotación
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
- Comprensión del uso de ImageView Matrix
- Deshabilitar y habilitar cambios de orientación en una actividad en Android mediante programación
- Detectar algoritmo de giro de 360 grados
- Girar rápidamente el teléfono 180 grados, la vista previa de la cámara gira al revés
- Zoom de Android y rotación de la vista de imagen
- Rajawali cámara giratoria con Sensor.TYPE_ROTATION_VECTOR comportamiento extraño
- Android: gira el lienzo alrededor del centro de la pantalla
- Cómo manejar la rotación con Retrofit y RxJava / RxAndroid en Actividad?
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
- Recuperar la ruta de acceso del archivo de la intención de DownloadManager detectada
- Captura de ID de llamada de línea fija y uso en dispositivos IOS y Android