使用 ViewPager 的图像库 +放大图像视图

发布于 2025-01-01 01:11:12 字数 8449 浏览 2 评论 0原文

我想实现什么?

使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧城烟雨 2025-01-08 01:11:12

如果你想使用 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 is ScaleType.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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文