2016-11-15 59 views
0

我有一个ImageView,我可以用它来放大图像,但无法滚动图像。任何人都可以通过查看我的代码告诉我我做错了什么吗?放大图像无法滚动到工作

这里是我activity_route_detail.xmlImageView我试图滚动:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:app="http://schemas.android.com/apk/res-auto" 
xmlns:tools="http://schemas.android.com/tools" 
android:id="@+id/activity_route_details" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:paddingBottom="@dimen/activity_vertical_margin" 
android:paddingLeft="@dimen/activity_horizontal_margin" 
android:paddingRight="@dimen/activity_horizontal_margin" 
android:paddingTop="@dimen/activity_vertical_margin" 
tools:context="com.example.zach.listview.RouteDetails"> 

<TextView 
    android:text="TextView" 
    android:layout_width="match_parent" 
    android:layout_height="wrap_content" 
    android:id="@+id/routeDetailsView" 
    android:textSize="18sp" 
    android:textAlignment="center" 
    android:layout_alignParentTop="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" /> 

<ImageView 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:id="@+id/routeImage" 
    android:scaleType="matrix" 
    android:layout_alignParentBottom="true" 
    android:layout_alignParentLeft="true" 
    android:layout_alignParentStart="true" /> 
</RelativeLayout> 

这里是我的routeDetails.java与滚动代码:

package com.example.zach.listview; 

import android.graphics.Matrix; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.view.MotionEvent; 
import android.view.ScaleGestureDetector; 
import android.view.View; 
import android.widget.ImageView; 
import android.widget.TextView; 



public class RouteDetails extends AppCompatActivity { 

    Matrix matrix = new Matrix(); 
    Float scale = 1f; 
    ScaleGestureDetector SGD; 
    ImageView routeImage; 

    //variables for scrolling 
    float curX, curY; 
    float mx; 
    float my; 



    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_route_details); 

     //back button for route details view 
     getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

     //TextView for route details 
     final TextView routeDetailsView = (TextView) findViewById(R.id.routeDetailsView); 
     routeDetailsView.setText(getIntent().getExtras().getString("route")); 

     //ImageView for route details 
     routeImage = (ImageView) findViewById(R.id.routeImage); 
     routeImage.setImageResource(getIntent().getIntExtra("imageResourceId", 0)); 



     ///// scrolling listener code 

     routeDetailsView.setOnTouchListener(new View.OnTouchListener() { 

      public boolean onTouch(View arg0, MotionEvent event) { 



       switch (event.getAction()) { 

        case MotionEvent.ACTION_DOWN: 
         mx = event.getX(); 
         my = event.getY(); 
         break; 
        case MotionEvent.ACTION_MOVE: 
         curX = event.getX(); 
         curY = event.getY(); 
         routeDetailsView.scrollBy((int) (mx - curX), (int) (my - curY)); 
         mx = curX; 
         my = curY; 
         break; 
        case MotionEvent.ACTION_UP: 
         curX = event.getX(); 
         curY = event.getY(); 
         routeDetailsView.scrollBy((int) (mx - curX), (int) (my - curY)); 
         break; 
       } 
       return true; 
      } 
     }); 



     ///// 



     SGD = new ScaleGestureDetector(this, new ScaleListener()); 
    } 

    //listener for pinch zoom 
    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener { 
     @Override 
     public boolean onScale(ScaleGestureDetector detector) { 
      scale = scale * detector.getScaleFactor(); 
      scale = Math.max(0.1f, Math.min(scale, 5f)); 
      matrix.setScale(scale, scale); 
      routeImage.setImageMatrix(matrix); 
      return true; 
     } 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     SGD.onTouchEvent(event); 
     return true; 
    } 

    //back button for route details view 
    @Override 
    public boolean onSupportNavigateUp() { 
     finish(); 
     return true; 
    } 

} 

回答

0

ImageView时候,它不会把自己变成一个滚动视图使用矩阵缩小。

您必须使用矩阵本身缩放ImageView移动到所需的位置,这样的事情:

  matrix.setScale(scale, scale) 
      matrix.postTranslate(curX - mx, curY - my); 
      routeImage.setImageMatrix(matrix); 

然后,你需要做两个额外的东西:

  • 您需要跟踪您正在使用的当前比例因子,以便您可以将矩阵设置为合适的比例值以及翻译值。

  • 您将需要进行一些边界检查,以便如果用户尝试滚动视图边界内的图像,则调整滚动以使图像保持在视图的边界上,这样您就不会出现大的空洞空间。警告:所有的检查和调整正确是一个真正的痛苦。我写了这些缩放组件之一,并不像听起来那么简单。

另外,我注意到你在你的ScaleListener调用matrix.setScale(scale, scale)。为了获得规模亦随滚动工作,你应该叫getFocusX()getFocusY()在探测器上,那么你可以做

 matrix.setScale(scale, scale, focusX, focusY) 

这使得你一个额外的挑战,这是找出在当前图像边界与视图边界有关系。我使用原始尺寸的图像保留Rect,并在缩放后使用matrix.mapRect()以获取更新的图像边界。当然,您必须对视图内部的图像边缘进行相同的边界检查和调整。


在GitHub上有很多这些图像视图实现。您可以通过搜索GitHub的“触摸图像视图”或“缩放图像视图”并使用预编码(希望预先测试)的组件,为自己节省一些时间&痛苦。