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

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

实现步骤:

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>

实现过程就这样完成了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏硬核项目经理的专栏

深入PHP面向对象、模式与实践(一)

2.对象是根据类中定义的模板所构造的数据,对象可以被说成是类的“实例”,它是由类定义的数据类型

13140
来自专栏HACK学习

Web安全常见漏洞修复建议

看各大发布漏洞的平台,发现众多挖洞大神精彩的漏洞发掘过程,但在修复建议或者修复方案处,给出千奇百怪神一般的回复,故而总结一下修复建议(才疏学浅不算太全敬请谅...

16820
来自专栏HACK学习

渗透测试实战-Blacklight靶机+DeRPnStiNK靶机入侵

挺久没更新靶机渗透文章,近期抽点时间继续更新文章,为什么这篇要2个靶机写在一起哪?因为第一个靶机虽然被困了几天但是其实比较简单故就和另外一个前段时间玩的合并在一...

13620
来自专栏JAVA人生/面试技巧

常用注解的理解

@RequestMapping:提供路由信息,负责URL到Controller中的具体函数的映射。

9330
来自专栏爱游博客

WordPress获取今天/最近24小时发布的文章数量

最近爱游帮朋友做一个WordPress采集网站,需要调用今天发布文章数,所以发个文章记录。

13130
来自专栏SmartSi

Spark2.3.0 使用spark-submit部署应用程序

Spark的 bin 目录中的 spark-submit 脚本用于在集群上启动应用程序。可以通过一个统一的接口使用 Spark 所有支持的集群管理器,因此不必为...

28940
来自专栏前端技术地图

React组件设计实践总结04 - 组件的思维

在 React 的世界里”一切都是组件“, 组件可以映射作函数式编程中的函数,React 的组件和函数一样的灵活的特性不仅仅可以用于绘制 UI,还可以用于封装业...

20320
来自专栏HACK学习

一个人的武林:渗透测试常规分析(一)

这门技术(艺术)一开始也不是每个人都会的,正所谓没有人一出生就会走路,从不懂到入门到深谙,一步步慢慢来,每个人都是这样;但是在这个过程中,思路无疑是最重要的,没...

9920
来自专栏企业平台构建

springboot shiro实现权限管理

记得第一次使用shiro是在才入行遇到公司的第一个框架,当时并不知道这是什么,或者说根本就没有安全框架的概念,在慢慢实践中,也对这个有了一定的了解,于是在网上找...

57530
来自专栏HACK学习

教你一些MySQL数据库入侵及防御方法

在针对网站渗透中,很多都是跟 MySQL 数据库有关,各种 MySQL 注入、MySQL 提权、MySQL 数据库 Root 账号 webshell 获取等,但...

38620

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励