使用 ViewPager 的图像库 +放大图像视图
我想实现什么?
使用 ViewPager 的图像库。我选择这个选项是因为图像之间的平滑过渡(我使用的是 ImageView),它很好并且很容易实现。
我的问题到底是什么?
我已经能够实现所有这些但是缩放不起作用。我可以在LogCat中看到它是如何打印ZOOM的(代码在帖子末尾),但图像没有放大。关于以下代码的一些注释:
ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image);
我正在使用 UrlImageViewHelper 从网络异步下载图像。api.getListUrls()
这是一个 ArrayList,其中包含图像 url。我也尝试过使用 R.drawable 中的 ImageView 而不是下载图像
导入 android.content.Context; 导入 android.content.Intent; 导入 android.graphics.Matrix; 导入 android.graphics.PointF; 导入 android.os.Bundle; 导入 android.support.v4.app.ActionBar; 导入 android.support.v4.app.Fragment; 导入 android.support.v4.app.FragmentActivity; 导入 android.support.v4.app.FragmentManager; 导入 android.support.v4.app.FragmentPagerAdapter; 导入 android.support.v4.view.Menu; 导入 android.support.v4.view.MenuItem; 导入 android.support.v4.view.ViewPager; 导入 android.util.FloatMath; 导入 android.util.Log; 导入 android.view.LayoutInflater; 导入 android.view.MenuInflater; 导入 android.view.MotionEvent; 导入 android.view.View; 导入 android.view.View.OnTouchListener; 导入 android.view.ViewGroup; 导入 android.view.ViewGroup.LayoutParams; 导入 android.widget.Gallery; 导入 android.widget.ImageView; 导入 android.widget.Toast; 公共类幻灯片扩展FragmentActivity { 私有ViewPager mPager; 公共静态API API; 公共静态 int 位置; 公共静态ActionBar顶栏; 公共静态上下文 ctx; @覆盖 公共无效onCreate(捆绑保存实例状态){ super.onCreate(savedInstanceState); setContentView(R.layout.fragment); ctx = 幻灯片.this; 位置=0; 顶部栏 = getSupportActionBar(); /* 获取端口 */ api = 新的 API(); api.getUrlsFromAPI(); topbar.setDisplayShowHomeEnabled(false); topbar.setDisplayShowTitleEnabled(true); mPager = (ViewPager) findViewById(R.id.pager); mPager.setAdapter(new TestAdapter(getSupportFragmentManager())); } @覆盖 受保护无效 onResume() { // TODO 自动生成的方法存根 super.onResume(); mPager.setCurrentItem(POSITION); } 静态最终类 TestAdapter 扩展 FragmentPagerAdapter { 公共 TestAdapter(FragmentManager fm) { 超级(调频); } @覆盖 公共 int getCount() { 返回 api.getListUrls().size(); } @覆盖 公共片段 getItem(int 位置) { TestFragment f = new TestFragment(); f.url = api.getListUrls().get(position).getUrl(); f.位置=位置; 返回f; } } 公共静态类 TestFragment 扩展 Fragment { 字符串 url = ""; 整数位置=0; 公共测试片段(){ setRetainInstance(真); } @覆盖 公共无效onCreate(捆绑保存实例状态){ super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @覆盖 public View onCreateView(LayoutInflater inflater, ViewGroup 容器, 捆绑已保存实例状态) { ImageView img = new ImageView(getActivity()); img.setPadding(6, 6, 6, 6) ; img.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)) ; ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image) ; img.setOnTouchListener(new OnTouchListener() { 私有静态最终字符串标签=“SlideImageView”; // 这些矩阵将用于移动和缩放图像 矩阵矩阵 = new Matrix(); 矩阵保存矩阵=新矩阵(); // 我们可以处于这 3 种状态之一 静态最终 int NONE = 0; 静态最终 int DRAG = 1; 静态最终 int ZOOM = 2; int模式=无; // 记住一些关于缩放的事情 PointF 开始 = new PointF(); PointF mid = new PointF(); 浮动旧距离 = 1f; @覆盖 公共布尔 onTouch(View v, MotionEvent 事件) { ImageView 视图 = (ImageView) v; // 将触摸事件转储到日志 转储事件(事件); // 在这里处理触摸事件... switch (event.getAction() & MotionEvent.ACTION_MASK) { 案例MotionEvent.ACTION_DOWN: 保存矩阵.set(矩阵); start.set(event.getX(), event.getY()); Log.d(TAG, "模式=拖动"); 模式=拖动; 休息; 案例MotionEvent.ACTION_POINTER_DOWN: oldDist = 间距(事件); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { 保存矩阵.set(矩阵); 中点(中点,事件); 模式=缩放; Log.d(TAG, "模式=ZOOM"); } 休息; 案例MotionEvent.ACTION_UP: 案例MotionEvent.ACTION_POINTER_UP: 模式=无; Log.d(TAG, "模式=无"); 休息; 案例MotionEvent.ACTION_MOVE: 如果(模式==拖动){ // ... 矩阵.set(savedMatrix); Matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } 否则 if (模式 == ZOOM) { 浮动newDist =间距(事件); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { 矩阵.set(savedMatrix); 浮点数 = newDist / oldDist; Log.d(TAG, "ZOOOOOOOM: " + 刻度); 矩阵.postScale(尺度,尺度,mid.x,mid.y); } } 休息; } view.setImageMatrix(矩阵); 返回真; // 表示事件已处理 } /** 在LogCat视图中显示一个事件,用于调试 */ 私人无效转储事件(运动事件事件){ 字符串名称[] = { "向下", "向上", "移动", "取消", “外部”,“POINTER_DOWN”,“POINTER_UP”,“7?”, “8?”、“9?” }; StringBuilder sb = new StringBuilder(); int action = event.getAction(); int actionCode = 动作 & MotionEvent.ACTION_MASK; sb.append("事件 ACTION_").append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN ||动作代码== MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append( 动作>> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")"); } sb.append(“[”); for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").append(i); sb.append("(pid ").append(event.getPointerId(i)); sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int) event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append(";"); } sb.append("]"); Log.d(TAG, sb.toString()); } /** 确定前两个手指之间的空间 */ 私有浮动间距(MotionEvent 事件){ float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); 返回 FloatMath.sqrt(x * x + y * y); } /** 计算前两个手指的中点 */ 私有无效midPoint(PointF点,MotionEvent事件){ 浮点数 x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); 点.set(x / 2, y / 2); } }); 返回图像; } @覆盖 公共无效onCreateOptionsMenu(菜单菜单,MenuInflater inflater){ } @覆盖 公共布尔onOptionsItemSelected(菜单项项目){ 返回 super.onOptionsItemSelected(item); } } }
我已经尝试过以下教程但没有成功:
What am I trying to implement?
A gallery of images using ViewPager. I choose this option because the smooth transition between images (I'm using ImageView), it is nice and quite easy to implement.
What is my problem exactly?
I've been able to implement all this but zoom isn't working. I can see in LogCat how it's printed ZOOM (the code is at the end of the post) but the image is not enlarged. Just a few notes about the following code:
ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image);
I'm using UrlImageViewHelper to download asynchronously the images from the web.api.getListUrls()
It's an ArrayList where I have the image urls.I've tried also using an ImageView from R.drawable instead of downloading the image
import android.content.Context; import android.content.Intent; import android.graphics.Matrix; import android.graphics.PointF; import android.os.Bundle; import android.support.v4.app.ActionBar; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentManager; import android.support.v4.app.FragmentPagerAdapter; import android.support.v4.view.Menu; import android.support.v4.view.MenuItem; import android.support.v4.view.ViewPager; import android.util.FloatMath; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.ViewGroup; import android.view.ViewGroup.LayoutParams; import android.widget.Gallery; import android.widget.ImageView; import android.widget.Toast; public class Slide extends FragmentActivity { private ViewPager mPager; public static Api api; public static int POSITION; public static ActionBar topbar; public static Context ctx; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.fragment); ctx = Slide.this; POSITION = 0; topbar = getSupportActionBar(); /* get portadas */ api = new Api(); api.getUrlsFromAPI(); topbar.setDisplayShowHomeEnabled(false); topbar.setDisplayShowTitleEnabled(true); mPager = (ViewPager) findViewById(R.id.pager); mPager.setAdapter(new TestAdapter(getSupportFragmentManager())); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); mPager.setCurrentItem(POSITION); } static final class TestAdapter extends FragmentPagerAdapter { public TestAdapter(FragmentManager fm) { super(fm); } @Override public int getCount() { return api.getListUrls().size(); } @Override public Fragment getItem(int position) { TestFragment f = new TestFragment(); f.url = api.getListUrls().get(position).getUrl(); f.position = position; return f; } } public static class TestFragment extends Fragment { String url = ""; Integer position = 0; public TestFragment() { setRetainInstance(true); } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ImageView img = new ImageView(getActivity()); img.setPadding(6, 6, 6, 6) ; img.setLayoutParams(new Gallery.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)) ; ImageViewHelperURL.setUrlDrawable((ImageView) img, url, R.drawable.no_image) ; img.setOnTouchListener(new OnTouchListener() { private static final String TAG = "SlideImageView"; // These matrices will be used to move and zoom image Matrix matrix = new Matrix(); Matrix savedMatrix = new Matrix(); // We can be in one of these 3 states static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE; // Remember some things for zooming PointF start = new PointF(); PointF mid = new PointF(); float oldDist = 1f; @Override public boolean onTouch(View v, MotionEvent event) { ImageView view = (ImageView) v; // Dump touch event to log dumpEvent(event); // Handle touch events here... switch (event.getAction() & MotionEvent.ACTION_MASK) { case MotionEvent.ACTION_DOWN: savedMatrix.set(matrix); start.set(event.getX(), event.getY()); Log.d(TAG, "mode=DRAG"); mode = DRAG; break; case MotionEvent.ACTION_POINTER_DOWN: oldDist = spacing(event); Log.d(TAG, "oldDist=" + oldDist); if (oldDist > 10f) { savedMatrix.set(matrix); midPoint(mid, event); mode = ZOOM; Log.d(TAG, "mode=ZOOM"); } break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_POINTER_UP: mode = NONE; Log.d(TAG, "mode=NONE"); break; case MotionEvent.ACTION_MOVE: if (mode == DRAG) { // ... matrix.set(savedMatrix); matrix.postTranslate(event.getX() - start.x, event.getY() - start.y); } else if (mode == ZOOM) { float newDist = spacing(event); Log.d(TAG, "newDist=" + newDist); if (newDist > 10f) { matrix.set(savedMatrix); float scale = newDist / oldDist; Log.d(TAG, "ZOOOOOOOM: " + scale); matrix.postScale(scale, scale, mid.x, mid.y); } } break; } view.setImageMatrix(matrix); return true; // indicate event was handled } /** Show an event in the LogCat view, for debugging */ private void dumpEvent(MotionEvent event) { String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" }; StringBuilder sb = new StringBuilder(); int action = event.getAction(); int actionCode = action & MotionEvent.ACTION_MASK; sb.append("event ACTION_").append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN || actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append( action >> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")"); } sb.append("["); for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").append(i); sb.append("(pid ").append(event.getPointerId(i)); sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int) event.getY(i)); if (i + 1 < event.getPointerCount()) sb.append(";"); } sb.append("]"); Log.d(TAG, sb.toString()); } /** Determine the space between the first two fingers */ private float spacing(MotionEvent event) { float x = event.getX(0) - event.getX(1); float y = event.getY(0) - event.getY(1); return FloatMath.sqrt(x * x + y * y); } /** Calculate the mid point of the first two fingers */ private void midPoint(PointF point, MotionEvent event) { float x = event.getX(0) + event.getX(1); float y = event.getY(0) + event.getY(1); point.set(x / 2, y / 2); } }); return img; } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { } @Override public boolean onOptionsItemSelected(MenuItem item) { return super.onOptionsItemSelected(item); } } }
I've already tried the following tutorial with no success:
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果你想使用 Matrix 和 ImageView 来转换图像,你需要更改 缩放类型改为
ScaleType.Matrix
,否则没有效果。默认比例类型是 ScaleType.FIT_CENTER ,因此它将忽略矩阵。关于您最初的任务,如果您完成此工作,您可能会发现 ImageView 上的触摸手势会干扰 ViewPager 的滚动。您肯定会在支持单点触摸拖动时遇到问题,因为这直接对应于自然的 ViewPager 滑动动作以转到下一个视图。
If you want to use a Matrix with an ImageView to transform the image, you need to change the scale type to
ScaleType.Matrix
, otherwise there will be no effect. The default scale type isScaleType.FIT_CENTER
and so it will ignore the matrix.Regarding your original task, if you get this working you may find that the touch gestures on the ImageView will interfere with the scrolling of the ViewPager. You will definitely have problems supporting single-touch drag because this directly corresponds with the natural ViewPager swipe motion to go to the next view.