2015-02-26 2 views
0

У меня возникла проблема с увеличением увеличения на основе сенсорного положения в Android. Результат, который я хочу, похож на более раннее увеличение панели приложений в мак-книжке; значок, в котором мышь зависает, является наибольшим увеличенным, а значки окружают его медленным масштабом вниз до их первоначального размера.Увеличение на основе сенсорного местоположения

Я включил изображение того, что ему понравится, если пользователь коснется значка в центре панели значков.

enter image description here

В настоящее время у меня есть код, который несколько работает. Я использую уравнение cos для создания масштабного коэффициента, но когда вы приближаетесь к желтым значкам, это приводит к увеличению зеленого значка. Также наклонный аффект не срабатывает должным образом. Я прикрепил фотографию с примерами касания и кодом. Благодарим вас за любую помощь, которую вы можете предоставить. enter image description here

Java класс брикетирования масштабируемости

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

<?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> 

ответ

0

Мой фикс для этого было гораздо проще уравнение.
Я использовал центральную ось каждого квадрата, чтобы получить расстояние до центра, а затем разделил расстояние от центра на высоту макета.

distFromCenter = (yTouch == 0) ? pivotY : Math.abs((pivotY - userYInput)); 
scale = (distFromCenter/layoutHieght); 
scale = scale == 0 ? 2 : 2 - scale. 

Близкий центр, тем больше масштаб, другой мудрый его снижается, но никогда не опускается ниже 1.

 Смежные вопросы

  • Нет связанных вопросов^_^