15

В моем приложении для Android мне нужно создать возможности масштабирования. Я нашел полезный код для масштабирования линейного макета here. Но в моем приложении несколько действий начинаются с scrollview, и этот код не распознает scrollview. Как я могу сделать масштабирование для прокручиваемой активности? Это один из моих макетов.Как сделать масштабируемое прокрутку?

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/scrollViewZoom" 
android:layout_width="match_parent" 
android:layout_height="wrap_content" 
android:layout_centerHorizontal="true" 
android:layout_centerVertical="true" > 

<LinearLayout 
    android:id="@+id/wd_content" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:layout_marginTop="10dp" 
    android:orientation="vertical" > 

    <!-- Start Circle --> 

    <TableRow 
     android:id="@+id/row_circl1" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_gravity="center" 
     android:layout_marginTop="30dp" 
     android:background="@color/purple_color" > 

     <RelativeLayout 
      android:id="@+id/circle_layout1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:background="@color/white_color" > 

      <ImageView 
       android:id="@+id/img_engin_circle1" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerHorizontal="true" 
       android:background="@drawable/circle_engin_bg" 
       android:contentDescription="TODO" /> 
     </RelativeLayout> 

     <RelativeLayout 
      android:id="@+id/circle_layout2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:background="@color/white_color" > 

      <ImageView 
       android:id="@+id/img_engin_circle2" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerHorizontal="true" 
       android:background="@drawable/circle_engin_bg" 
       android:contentDescription="TODO" /> 
     </RelativeLayout> 
    </TableRow> 

    <TableRow 
     android:id="@+id/row_name_circle" 
     android:layout_width="wrap_content" 
     android:layout_height="match_parent" 
     android:layout_gravity="center" 
     android:layout_marginTop="30dp" > 

     <RelativeLayout 
      android:id="@+id/circle_name_layout1" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="-15dp" 
      android:background="@color/white_color" > 

      <ImageView 
       android:id="@+id/img_name_circle1" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerHorizontal="true" 
       android:background="@drawable/circle_gauge_name" 
       android:contentDescription="TODO" /> 
     </RelativeLayout> 

     <RelativeLayout 
      android:id="@+id/circle_name_layout2" 
      android:layout_width="wrap_content" 
      android:layout_height="wrap_content" 
      android:layout_marginTop="-15dp" 
      android:background="@color/white_color" > 

      <ImageView 
       android:id="@+id/img_name_circle2" 
       android:layout_width="wrap_content" 
       android:layout_height="wrap_content" 
       android:layout_centerHorizontal="true" 
       android:background="@drawable/circle_gauge_name" 
       android:contentDescription="TODO" /> 
     </RelativeLayout> 
    </TableRow> 

    <!-- End Circle --> 

</LinearLayout> 

</ScrollView> 

Любая идея поможет мне. Спасибо.

+0

Пожалуйста, проверьте эту ссылку: [позволяющую-зум-на-свитка зрения] [1] удачи. [1]: http://stackoverflow.com/questions/18572014/enabling-zoom-on-scroll-view –

+0

Спасибо за ответ @ Adir.el, но я нашел другое решение. – IndieBoy

ответ

22

Хорошо. После вспашки сети, наконец, нашел свой ответ. Я нашел onTouchEvent() для scrollview не работает, поэтому я должен использовать dispatchTouchEvent() вместо onTouchEvent(). Наверху вы можете увидеть мой xml-код (в моем вопросе), вот мой код активности, конечно, с комментариями.

// step 1: add some instance 
private float mScale = 1f; 
private ScaleGestureDetector mScaleDetector; 
GestureDetector gestureDetector; 

//step 2: create instance from GestureDetector(this step sholude be place into onCreate()) 
gestureDetector = new GestureDetector(this, new GestureListener()); 

// animation for scalling 
mScaleDetector = new ScaleGestureDetector(this, new ScaleGestureDetector.SimpleOnScaleGestureListener() 
    {         
     @Override 
     public boolean onScale(ScaleGestureDetector detector) 
     { 
      float scale = 1 - detector.getScaleFactor(); 

      float prevScale = mScale; 
      mScale += scale; 

      if (mScale < 0.1f) // Minimum scale condition: 
       mScale = 0.1f; 

      if (mScale > 10f) // Maximum scale condition: 
       mScale = 10f; 
      ScaleAnimation scaleAnimation = new ScaleAnimation(1f/prevScale, 1f/mScale, 1f/prevScale, 1f/mScale, detector.getFocusX(), detector.getFocusY()); 
      scaleAnimation.setDuration(0); 
      scaleAnimation.setFillAfter(true); 
      ScrollView layout =(ScrollView) findViewById(R.id.scrollViewZoom); 
      layout.startAnimation(scaleAnimation); 
      return true; 
     } 
    }); 


// step 3: override dispatchTouchEvent() 
@Override 
public boolean dispatchTouchEvent(MotionEvent event) { 
    super.dispatchTouchEvent(event); 
    mScaleDetector.onTouchEvent(event); 
    gestureDetector.onTouchEvent(event); 
    return gestureDetector.onTouchEvent(event); 
} 

//step 4: add private class GestureListener 

private class GestureListener extends GestureDetector.SimpleOnGestureListener { 
    @Override 
    public boolean onDown(MotionEvent e) { 
     return true; 
    } 
    // event when double tap occurs 
    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     // double tap fired. 
     return true; 
    } 
} 

Большое спасибо.

+5

Другая жизнь спасена! Еще одно пиво гарантировано здесь, в Брази! –

+2

Показывает только увеличение зума, а не прокрутку, когда я реализован. –

+0

Не могли бы вы объяснить, где мне нужно это использовать? Я создаю специальный класс, расширяющий Scrollview и помещающий выше код в этот класс. но он дает исключение иниции –

1

Спасибо за ваше решение, я осуществил это немного по-другому, потому что мой Scrollview внутри фрагмента, а не деятельности, делегировать всю логику представления, я бы рекомендовал добавить dispatchTouchEvent в ту же точку зрения пользовательских прокрутки:

package com.your.package; 

import android.content.Context; 
import android.util.AttributeSet; 
import android.view.GestureDetector; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.animation.ScaleAnimation; 
import android.widget.ScrollView; 

import com.your.package.R; 

public class CustomZoomScrollView extends ScrollView { 


    // step 1: add some instance 
    private float mScale = 1f; 
    private ScaleGestureDetector mScaleDetector; 
    GestureDetector gestureDetector; 


    public CustomZoomScrollView(Context context) { 
     super(context); 
    } 

    public CustomZoomScrollView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     //step 2: create instance from GestureDetector(this step should be place into onCreate()) 
     gestureDetector = new GestureDetector(getContext(), new GestureListener()); 

     mScaleDetector = new ScaleGestureDetector(getContext(), new ScaleGestureDetector.SimpleOnScaleGestureListener() 
     { 
      @Override 
      public boolean onScale(ScaleGestureDetector detector) 
      { 
       float scale = 1 - detector.getScaleFactor(); 

       float prevScale = mScale; 
       mScale += scale; 

       if (mScale < 0.1f) // Minimum scale condition: 
        mScale = 0.1f; 

       if (mScale > 10f) // Maximum scale condition: 
        mScale = 10f; 
       ScaleAnimation scaleAnimation = new ScaleAnimation(1f/prevScale, 1f/mScale, 1f/prevScale, 1f/mScale, detector.getFocusX(), detector.getFocusY()); 
       scaleAnimation.setDuration(0); 
       scaleAnimation.setFillAfter(true); 
       getRootView().findViewById(R.id.svSeats).startAnimation(scaleAnimation); 
       return true; 
      } 
     }); 
    } 

    // step 3: override dispatchTouchEvent() 
    @Override 
    public boolean dispatchTouchEvent(MotionEvent event) { 
     super.dispatchTouchEvent(event); 
     mScaleDetector.onTouchEvent(event); 
     gestureDetector.onTouchEvent(event); 
     return gestureDetector.onTouchEvent(event); 
    } 

//step 4: add private class GestureListener 

    private class GestureListener extends GestureDetector.SimpleOnGestureListener { 
     @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 
     // event when double tap occurs 
     @Override 
     public boolean onDoubleTap(MotionEvent e) { 
      // double tap fired. 
      return true; 
     } 
    } 
} 
Смежные вопросы