Je rencontre un problème en développant un grossissement basé sur l'emplacement tactile dans Android. Le résultat que je veux est similaire à l'ancien grossissement de la barre d'application du livre mac; l'icône sur laquelle la souris survole est la plus grande agrandie et les icônes l'entourent lentement jusqu'à leur taille d'origine.Grossissement basé sur l'emplacement tactile
J'ai inclus une image de ce qu'il devrait aimer si l'utilisateur touche une icône au centre de la barre d'icônes.
Actuellement, j'ai du code qui fonctionne un peu. J'utilise une équation cos pour créer le facteur d'échelle mais lorsque vous touchez près des icônes jaunes, la dernière icône verte est agrandie. De plus, l'affect en pente ne sort pas correctement. J'ai joint une photo avec des touches d'échantillons et le code. Merci pour toute aide que vous pouvez fournir.
classe Java préformage l'échelle
public class Layout extends RelativeLayout implements View.OnTouchListener{
private Camera mCamera = new Camera();
private Matrix mMatrix = new Matrix();
private ArrayList<Layer> layers = new ArrayList<Layer>();
private final String TAG = this.getClass().getSimpleName();
private int xTouch = 0;
private int yTouch = 0;
private boolean isUserInput = false;
private int childHeight = 1;
private Context context;
public TrackerLayout(Context context) {
super(context);
setupView(context);
}
public TrackerLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setupView(context);
}
public TrackerLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setupView(context);
}
private void setupView(Context context){
this.context = context;
setOnTouchListener(this);
setWillNotDraw(false);
}
@Override
protected void onDraw(Canvas canvas) {
if (layers.size() != getChildCount()) {
getChildrenViews();
}
//getChild's order
sortChildrenByDist();
super.onDraw(canvas);
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
childHeight = h/8;
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
if(isUserInput && yTouch >= 0) {
Bitmap bitmap = child.getDrawingCache();
if (bitmap == null) {
child.setDrawingCacheEnabled(true);
child.buildDrawingCache();
bitmap = child.getDrawingCache();
}
//Get a reference for the child layer that's being modified
Layer layer = null;
for (Layer tempLayer : layers) {
if (tempLayer.child.getId() == child.getId()) {
layer = tempLayer;
break;
}
}
canvas.save();
if(layer.coordinates.scale < 1){
layer.coordinates.scale = 1;
}
canvas.scale(layer.coordinates.scale, layer.coordinates.scale, layer.coordinates.pivotX, layer.coordinates.pivotY);
Paint paint = new Paint();
paint.setAntiAlias(true);
paint.setFilterBitmap(true);
if (mCamera == null) {
mCamera = new Camera();
}
mCamera.save();
mCamera.rotateY(layer.coordinates.rotation);
if (mMatrix == null) {
mMatrix = new Matrix();
}
mCamera.getMatrix(mMatrix);
mCamera.restore();
mMatrix.preTranslate(-layer.coordinates.centerX, -layer.coordinates.centerY);
mMatrix.postScale(layer.coordinates.scale, layer.coordinates.scale);
mMatrix.postTranslate(layer.coordinates.pivotX, layer.coordinates.pivotY);
canvas.drawBitmap(bitmap, layer.coordinates.left, layer.coordinates.top, paint);
canvas.restore();
return false;
}
return super.drawChild(canvas, child, drawingTime);
}
private void getChildrenViews() {
int childrenCount = this.getChildCount();
for (int i = 0; i < childrenCount; i++) {
if (getChildAt(i) instanceof ImageView) {
Layer layer = new Layer();
ImageView child = (ImageView) getChildAt(i);
int width = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 40, context.getResources().getDisplayMetrics());
RelativeLayout.LayoutParams params = (LayoutParams) child.getLayoutParams();
params.height = childHeight;
child.setLayoutParams(params);
layer.child = (child);
layers.add(layer);
}
}
}
private void sortChildrenByDist() {
ArrayList<Layer> negDistLayers = new ArrayList<Layer>();
ArrayList<Layer> postDistLayers = new ArrayList<Layer>();
for (Layer layer : layers) {
layer.coordinates = calculateCoordinates(layer.child);
if(layer.coordinates.distFromCenter >= 0){
postDistLayers.add(layer);
}else{
negDistLayers.add(layer);
}
}
Collections.sort(negDistLayers);
Collections.sort(postDistLayers);
layers.clear();
layers.addAll(postDistLayers);
layers.addAll(negDistLayers);
drawOrderedLayers();
}
private synchronized void drawOrderedLayers() {
for (int i = (layers.size() - 1); i > -1; i--) {
this.bringChildToFront(layers.get(i).child);
}
}
/**
* This method calculates the coordinates used to create the rotates, camera, and scaling on each child view
*
* @param child - the view the coordinates will be calculated from
* @return
*/
private Coordinates calculateCoordinates(View child) {
Coordinates coordinates = new Coordinates();
coordinates.left = child.getLeft();
coordinates.top = child.getTop();
coordinates.centerX = child.getWidth()/2;
coordinates.centerY = child.getHeight()/2;
coordinates.pivotX = coordinates.left + coordinates.centerX;
coordinates.pivotY = coordinates.top + coordinates.centerY;
coordinates.userYInput = yTouch;
coordinates.distFromCenter = (yTouch == 0) ? coordinates.pivotY : ((coordinates.pivotY - coordinates.userYInput)/coordinates.userYInput);
double cosValue = (Math.cos(coordinates.distFromCenter));
coordinates.scale = (float) (2 * cosValue);
coordinates.rotation = coordinates.distFromCenter;
return coordinates;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
final int action = event.getAction();
Log.i(TAG, " on touch detected");
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
xTouch = (int) event.getX();
yTouch = (int) event.getY();
isUserInput = true;
return true;
}
case MotionEvent.ACTION_MOVE: {
xTouch = (int) event.getX();
yTouch = (int) event.getY();
isUserInput = true;
return true;
}
default:
isUserInput = false;
return false;
}
}
private class Coordinates {
int left;
int top;
int centerX;
int centerY;
float pivotX;
float pivotY;
float userYInput;
float distFromCenter;
float scale;
float rotation;
}
//This class will hold a reference to the child and it's coordinates to
//help imitate layers
private class Layer implements Comparable<Layer> {
View child;
Coordinates coordinates;
//All values need to be sort towards) so there's an if case to determine if the input is
//comparing the list of positive values or negative values
public int compareTo(Layer compareItem) {
if(coordinates.distFromCenter >= 0) {
return Float.compare(coordinates.distFromCenter, compareItem.coordinates.distFromCenter);
}else{
return Float.compare(compareItem.coordinates.distFromCenter, coordinates.distFromCenter);
}
}
}
}
xml layout
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_color">
<com.layouts.Layout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop=“true”
android:orientation="vertical">
<ImageView
android:id="@+id/icon_level_1"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:layout_alignParentRight="true"
android:background="#FFF66C"
android:layout_alignParentTop="true"/>
<ImageView
android:id="@+id/icon_level_2"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#E7EE6C"
android:layout_alignParentRight="true"
android:layout_below="@+id/ticon_level_1"/>
<ImageView
android:id="@+id/icon_level_3"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#CCE46D"
android:layout_alignParentRight="true"
android:layout_below="@+id/icon_level_2"/>
<ImageView
android:id="@+id/icon_level_4"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#B2E07B"
android:layout_alignParentRight="true"
android:layout_below="@+id/icon_level_3"/>
<ImageView
android:id="@+id/icon_level_5"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#8BDB91"
android:layout_alignParentRight="true"
android:layout_below="@+id/icon_level_4"/>
<ImageView
android:id="@+id/icon_level_6"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#65BE91"
android:layout_alignParentRight="true"
android:layout_below="@+id/icon_level_5"/>
<ImageView
android:id="@+id/icon_level_7"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#4E8F77"
android:layout_alignParentRight="true"
android:layout_below="@+id/icon_level_6"/>
<ImageView
android:id="@+id/icon_level_8"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="right"
android:background="#3A655F"
android:layout_alignParentRight="true"
android:layout_below="@+id/icon_level_7"/>
</com.layouts.Layout>