前言
最近项目中需要实现轮播图显示商品图片,当用户点击商品图片的时候,需要图片放大显示,当然用户还能进行多张图片的滑动切换,放大,缩小图片等操作,实现起来相对还是比较简单的,话不多说,咱们是用代码说话的,直接上代码。
实现步骤:
1.效果图的展示
2.项目中添加相关的依赖
3.主界面实现轮播图的效果
实现过程:
1.效果图的展示
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); } } }
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) { } }); } }
/** * 滑动图片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(); } }
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; } }
在测试的过程中,对放大的图片进行缩放的时候,遇到下面的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源码:点击这里。
总结