Android实现轮播图点击图片放大效果

作者: 龙旋之谷 | 来源:发表于2019-08-22 09:35 被阅读54次

    最近项目中需要实现轮播图显示商品图片,当用户点击商品图片的时候,需要图片放大显示,当然用户还能进行多张图片的滑动切换,放大,缩小图片等操作,实现起来相对还是比较简单的,话不多说,咱们是用代码说话的,直接上代码。

    实现步骤:

    1.效果图的展示
    2.项目中添加相关的依赖
    3.主界面实现轮播图的效果
    4.点击轮播图进入图片放大展示页面
    5.图片放大展示页面所需的适配器
    6.获取fragment需要展示图片的url
    7.图片缩放时遇到Bug解决

    实现过程:
    1.效果图的展示


    QQ图片20190822093116.gif

    2.项目中添加相关的依赖

        implementation 'com.youth.banner:banner:1.4.9'
        implementation 'com.github.bumptech.glide:glide:4.5.0'
        implementation 'com.commit451:PhotoView:1.2.4'
    

    3.主界面实现轮播图的效果

    public class MainActivity extends AppCompatActivity implements OnBannerListener {
    
        private Banner banner;
        private ArrayList<String> list_path;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            initView();
            initData();
            initListener();
        }
    
        private void initView() {
            banner = findViewById(R.id.banner);
        }
    
        private void initData() {
            setBanner();//设置轮播图
        }
    
        private void initListener() {
    
        }
    
        /**
         * 设置轮播图
         */
        private void setBanner() {
            //放图片地址的集合
            list_path = new ArrayList<>();
            //设置图片数据
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/2a919def19fc47e3aa0d75d8c227ab1b.jpg");
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/d027d1efc0564c44bb979ba0bd21f560.jpg");
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/bbb930d66e5a48baa8d3c143544d7631.jpg");
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/fb1721b8c9be4da9949fcdd26fc902a2.jpg");
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/08b58dde9b284638b44e2d03c4cb9acf.jpg");
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/d3caeb6129ee43df87f5c1e1058d96fc.jpg");
            list_path.add("https://sami-1256315447.picgz.myqcloud.com/article/201908/9fd01c4add07473db31ba850f20a7232.jpg");
            list_path.add("http://a.hiphotos.baidu.com/image/pic/item/00e93901213fb80e3b0a611d3fd12f2eb8389424.jpg");
    
            //设置内置样式,共有六种可以点入方法内逐一体验使用。
            banner.setBannerStyle(BannerConfig.NUM_INDICATOR);
            //设置图片加载器,图片加载器在下方
            banner.setImageLoader(new ImgLoader());
            //设置图片网址或地址的集合
            banner.setImages(list_path);
            //设置轮播的动画效果,内含多种特效,可点入方法内查找后内逐一体验
            banner.setBannerAnimation(Transformer.Default);
            //设置轮播间隔时间
            banner.setDelayTime(3000);
            //设置是否为自动轮播,默认是“是”
            banner.isAutoPlay(true);
            //设置指示器的位置,小点点,左中右。
            banner.setIndicatorGravity(BannerConfig.CENTER)
                    //以上内容都可写成链式布局,这是轮播图的监听。比较重要。方法在下面。
                    .setOnBannerListener(this)
                    //必须最后调用的方法,启动轮播图。
                    .start();
        }
    
        //轮播图的监听方法
        @Override
        public void OnBannerClick(int position) {
            Intent intent = new Intent(this, BigImgActivity.class);
            intent.putStringArrayListExtra("imgData", list_path);
            intent.putExtra("clickPosition", position);
            startActivity(intent);
        }
    
        //自定义的图片加载器
        private class ImgLoader extends ImageLoader {
            @Override
            public void displayImage(Context context, Object path, ImageView imageView) {
                Glide.with(context).load((String) path).into(imageView);
            }
        }
    }
    

    4.点击轮播图进入图片放大展示页面

    public class BigImgActivity extends AppCompatActivity {
        private ViewPagerFixed viewPager;
        private TextView tvNum;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_big_img);
            initView();
        }
    
        private void initView() {
            viewPager = findViewById(R.id.viewpager);
            tvNum = findViewById(R.id.tv_num);
    
            //接收图片数据及位置
            final ArrayList<String> imgData = getIntent().getStringArrayListExtra("imgData");
            int clickPosition = getIntent().getIntExtra("clickPosition", 0);
    
            //添加适配器
            PhotoPagerAdapter viewPagerAdapter = new PhotoPagerAdapter(getSupportFragmentManager(), imgData);
            viewPager.setAdapter(viewPagerAdapter);
            viewPager.setCurrentItem(clickPosition);//设置选中图片位置
    
            viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
                @Override
                public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                    tvNum.setText(String.valueOf(position + 1) + "/" + imgData.size());
                }
    
                @Override
                public void onPageSelected(int position) {
                }
    
                @Override
                public void onPageScrollStateChanged(int state) {
    
                }
            });
        }
    }
    

    5.图片放大展示页面所需的适配器

    /**
     * 滑动图片ViewPager适配器
     */
    public class PhotoPagerAdapter extends FragmentPagerAdapter {
    
        private final ArrayList<String> urlList;
    
        public PhotoPagerAdapter(FragmentManager fm, ArrayList<String> urlList) {
            super(fm);
            this.urlList=urlList;
        }
    
        @Override
        public Fragment getItem(int position) {
            return PhotoFragment.newInstance(urlList.get(position));
        }
    
        @Override
        public int getCount() {
            return urlList.size();
        }
    }
    

    6.获取fragment需要展示图片的url

    public class PhotoFragment extends Fragment {
    
        private String url;
        private PhotoView mPhotoView;
    
        /**
         * 获取这个fragment需要展示图片的url
         *
         * @param url
         * @return
         */
        public static PhotoFragment newInstance(String url) {
            PhotoFragment fragment = new PhotoFragment();
            Bundle args = new Bundle();
            args.putString("url", url);
            fragment.setArguments(args);
            return fragment;
        }
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            url = getArguments().getString("url");
        }
    
        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_img, container, false);
            mPhotoView = view.findViewById(R.id.photoview);
            //设置缩放类型,默认ScaleType.CENTER(可以不设置)
            // mPhotoView.setScaleType(ImageView.ScaleType.CENTER);
    
            //长按事件
            mPhotoView.setOnLongClickListener(new View.OnLongClickListener() {
                @Override
                public boolean onLongClick(View view) {
                    //Toast.makeText(getActivity(), "长按事件", Toast.LENGTH_SHORT).show();
                    return true;
                }
            });
    
            //点击事件
            mPhotoView.setOnPhotoTapListener(new PhotoViewAttacher.OnPhotoTapListener() {
                @Override
                public void onPhotoTap(View view, float x, float y) {
                    //Toast.makeText(getActivity(), "点击事件,真实项目中可关闭activity", Toast.LENGTH_SHORT).show();
                    getActivity().finish();
                }
            });
    
    
            Glide.with(getContext())
                    .load(url)
                    // .placeholder(R.mipmap.ic_launcher)//加载过程中图片未显示时显示的本地图片
                    // .error(R.mipmap.ic_launcher)//加载异常时显示的图片
                    //.centerCrop()//图片图填充ImageView设置的大小
                    // .fitCenter()//缩放图像测量出来等于或小于ImageView的边界范围,该图像将会完全显示
                    .into(mPhotoView);
            return view;
        }
    }
    

    7.图片缩放时遇到Bug解决
    在测试的过程中,对放大的图片进行缩放的时候,遇到下面的Bug:

     java.lang.IllegalArgumentException: pointerIndex out of range
    
    在这里插入图片描述

    在做多点触控放大缩小,操作自己所绘制的图形时发生这个异常,如果是操作图片的放大缩小多点触控不会出现这个错误
    这个bug是Android系统原因 。

    问题解决方案:

    自定义ViewPager,重写onTouchEvent 和onInterceptTouchEvent

    public class ViewPagerFixed extends android.support.v4.view.ViewPager {
     
        public ViewPagerFixed(Context context) {
            super(context);
        }
     
        public ViewPagerFixed(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
     
        @Override
        public boolean onTouchEvent(MotionEvent ev) {
            try {
                return super.onTouchEvent(ev);
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            }
            return false;
        }
     
        @Override
        public boolean onInterceptTouchEvent(MotionEvent ev) {
            try {
                return super.onInterceptTouchEvent(ev);
            } catch (IllegalArgumentException ex) {
                ex.printStackTrace();
            }
            return false;
        }
    }
    

    布局文件:

    <?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="#fff">
    
        <com.showly.testimagedemo.view.ViewPagerFixed
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <TextView
            android:id="@+id/tv_num"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:textColor="#ffffff"
            android:textSize="30sp" />
    
    </RelativeLayout>
    

    实现过程就这样完成了。
    需要Demo源码的童鞋可以在底部的公众号回复:"TestImageDemo"即可获取。


    以下是个人公众号(longxuanzhigu),之后发布的文章会同步到该公众号,方便交流学习Android知识及分享个人爱好文章,有问题可以留言哦:
    [图片上传失败...(image-cc5b8d-1566437652539)]

    相关文章

      网友评论

        本文标题:Android实现轮播图点击图片放大效果

        本文链接:https://www.haomeiwen.com/subject/dqpgsctx.html