}
protected ImageView generateImageView(Context context) {
GridImageView imageView = new GridImageView(context);
imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
return imageView;
}
}
-
T 是你图片的数据类型, 你可以简单的使用 String 类型也可以是你自定义的类型;
-
你必须重写
onDisplayImage(Context context, ImageView imageView, T t)
方法去设置显示图片的方式, 你可以使用 Picasso、Glide 、ImageLoader 或者其他的图片加载库,你也可以给ImageView
设置一个占位图; -
如果你需要处理图片的点击事件,你可以重写
onItemImageClick(Context context, int index, List<T> list)
方法,加上你自己的处理逻辑; -
如果你要使用自定义的
ImageView
,你可以重写generateImageView(Context context)
方法, 去生成自定的ImageView
。
下面是一段示例代码:
private NineGridImageViewAdapter mAdapter = new NineGridImageViewAdapter() {
@Override
protected void onDisplayImage(Context context, ImageView imageView, Photo photo) {
Picasso.with(context)
.load(photo.getSmallUrl)
.placeholder(R.drawable.ic_default_image)
.into(imageView);
}
@Override
protected ImageView generateImageView(Context context) {
return super.generateImageView(context);
}
@Override
protected void onItemImageClick(Context context, int index, List photoList) {
showBigPicture(context, photoList.get(index).getBigUrl());
}
…
mNineGridImageView.setAdapter(mAdapter);
…
- 给 NineGridImageView 设置图片数据:
nineGridImageView.setImagesData(List imageDataList);
demo代码
MainActivity
package com.huncm.review1;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.jaeger.library.StatusBarUtil;
import com.jaeger.ninegridimageview.NineGridImageView;
import com.jaeger.ninegridimageview.NineGridImageViewAdapter;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
List list = new ArrayList<>();
list.add(“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20211026/image.6719h9mvs700.png”);
list.add(“https://img-blog.csdnimg.cn/img_convert/8dc4978a27ba3ccdaa697c2d7814f3ac.png”);
list.add(“https://img-blog.csdnimg.cn/img_convert/52f5dd5a02ab958c9a2b4daa825925e5.png”);
list.add(“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20211026/image.6719h9mvs700.png”);
list.add(“https://img-blog.csdnimg.cn/img_convert/8dc4978a27ba3ccdaa697c2d7814f3ac.png”);
NineGridImageView nineGridImageView = findViewById(R.id.nineGridImageView);
nineGridImageView.setAdapter(myadpter);
nineGridImageView.setImagesData( list);
}
private NineGridImageViewAdapter myadpter = new NineGridImageViewAdapter() {
@Override
protected void onDisplayImage(Context context, ImageView imageView, String url) {
Glide.with(context).load(url).into(imageView);
}
@Override
protected void onItemImageClick(Context context, int index, List list) {
super.onItemImageClick(context, index, list);
}
@Override
protected ImageView generateImageView(Context context) {
return super.generateImageView(context);
}
};
}
activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=“.MainActivity”>
<com.jaeger.ninegridimageview.NineGridImageView
android:id=“@+id/nineGridImageView”
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:layout_margin=“16dp”
android:layout_marginStart=“16dp”
android:layout_marginLeft=“16dp”
android:layout_marginEnd=“16dp”
android:layout_marginRight=“16dp”
app:imgGap=“4dp”
app:maxSize=“9”
app:showStyle=“grid”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“parent” />
</androidx.constraintlayout.widget.ConstraintLayout>
当我实现这个控件的时候,我发现他不能点击图片放大,图片不能预览,而且不能左滑右滑😢,我的卑微又开始了,我就去网上找了如何实现点击方大
这时出现了第二个控件:PhotoView
简单的介绍
这是一个图片查看库,实现图片浏览功能,支持pinch(捏合)手势或者点击放大缩小。支持在ViewPager中翻页浏览图片。
PhotoView 是一款扩展自Android ImageView ,支持通过单点/多点触摸来进行图片缩放的智能控件。功能实用和强大。
特性
可以用于查看图片,并对图片进行拖动缩放,拖动过程中不会出现边缘空白;
双击缩小放大,Fling移动,并支持上述过程的渐变;
在放大情况下也支持viewpager等的拖动切换;
支持多击事件检测,单机,双击事件;
支持各种回调给调用者;
效果预览
使用
- 在根文件(不是模块文件)中添加此:
build.gradle
allprojects {
repositories {
maven { url “https://www.jitpack.io” }
}
}
buildscript {
repositories {
maven { url “https://www.jitpack.io” }
}
}
- 导入依赖
implementation ‘com.github.chrisbanes:PhotoView:2.0.0’
- 编写布局文件
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=“.MainActivity2”>
<com.github.chrisbanes.photoview.PhotoView
android:id=“@+id/photo_view”
android:layout_width=“0dp”
android:layout_height=“0dp”
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“parent”
tools:ignore=“MissingClass” />
</androidx.constraintlayout.widget.ConstraintLayout>
- 编写逻辑代码
package com.huncm.review1;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import com.bumptech.glide.Glide;
import com.github.chrisbanes.photoview.PhotoView;
import javax.microedition.khronos.opengles.GL;
public class MainActivity2 extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
PhotoView photoView = findViewById(R.id.photo_view);
Glide.with(this).load(“https://img-blog.csdnimg.cn/img_convert/52f5dd5a02ab958c9a2b4daa825925e5.png”).into(photoView);
}
}
写到这里QQ九宫格也算是实现了一半,如果只是这两个控件的话,实现的QQ九宫格图片不能预览,也不能左滑右滑,我便在网上搜索了一波。找到一种解决方法:
使用ViewPager和PhotoView实现图片浏览
使用photoView实现图片的放大缩小,再使用viewPager实现图片的左右滑动
添加依赖
- build.gradle (app)
//photoView
implementation ‘com.github.chrisbanes:PhotoView:2.0.0’
//glide
implementation ‘com.github.bumptech.glide:glide:4.9.0’
annotationProcessor ‘androidx.annotation:annotation:1.0.0’
annotationProcessor ‘com.github.bumptech.glide:compiler:4.9.0’
- build.gradle (project)
allprojects {
repositories {
google()
jcenter()
maven { url “https://jitpack.io” }
}
}
- manifests 添加网络权限
XML文件
- activity_main.xml
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=“http://schemas.android.com/apk/res/android”
xmlns:app=“http://schemas.android.com/apk/res-auto”
xmlns:tools=“http://schemas.android.com/tools”
android:layout_width=“match_parent”
android:layout_height=“match_parent”
tools:context=“.MainActivity”>
<androidx.viewpager.widget.ViewPager
android:id=“@+id/viewpager”
android:layout_width=“0dp”
android:layout_height=“0dp”
android:background=“#99000000”
app:layout_constraintBottom_toBottomOf=“parent”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“parent”></androidx.viewpager.widget.ViewPager>
<LinearLayout
android:id=“@+id/points”
android:layout_width=“0dp”
android:layout_height=“wrap_content”
android:layout_alignBottom=“@+id/viewpager”
android:gravity=“center”
android:orientation=“horizontal”
android:padding=“5dp”
app:layout_constraintEnd_toEndOf=“parent”
app:layout_constraintStart_toStartOf=“parent”
app:layout_constraintTop_toTopOf=“@+id/viewpager”>
</androidx.constraintlayout.widget.ConstraintLayout>
使用Glide
这里使用Glide来加载网络图片,Gilde自从4.0.0版本开始要通过生成GlideApp类来使用各种Api,那么就开始动手实践吧
- 生成GlideApp
- 首先创建MyAppGlideModule类
@GlideModule
public final class MyAppGlideModule extends AppGlideModule {
}
- build ->Rebuild Project
- 封装ImageLoading类
因为我这里只是一个测试Demo,所以这是封装了一种方法,Glide的 功能很强大,如加载gif图, 实现模糊 等等操作,这里插入一个大佬写的
Glide专栏
public class ImageLoader {
public static void display(Context context, ImageView imageView,String url){
GlideApp
.with(context)
.load(url)
.placeholder(R.drawable.timg)
.into(imageView);
}
}
Activity层操作
在这一层需要初始化Viewpager和设置白点指示器, 并和适配器绑定数据
package com.huncm.photoviewdemo;
import androidx.appcompat.app.AppCompatActivity;
import androidx.viewpager.widget.ViewPager;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.LinearLayout;
public class MainActivity extends AppCompatActivity {
private ViewPager viewPager;
private MyViewPagerAdapter myViewPagerAdapter;
private String[] imglist = {
“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20210427/image.2c9e9xfoi3b4.png”,
“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20210427/image.17irwo5suuxs.png”,
“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20210427/image.2oi4dcxsc1c0.png”,
“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20210427/image.2m80368jvr80.png”,
“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20210427/image.65n8rjffvk00.png”,
“https://cdn.jsdelivr.net/gh/Yqifei/Blog-Image@master/20210427/image.75iaxbwd0fk0.png”
};
private LinearLayout points;
private int prePosition;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
private void initData() {
viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageScrolled(int position, float v, int i1) {
position = position % imglist.length;
//把前一个白变为黑
points.getChildAt(prePosition).setBackgroundResource(R.drawable.point_back);
//把当前白点变为黑点
points.getChildAt(position).setBackgroundResource(R.drawable.point_white);
//记录下当前位置(当前位置变白后,赋值给前一个点)
prePosition = position;
}
@Override
public void onPageSelected(int i) {
}
@Override
public void onPageScrollStateChanged(int i) {
}
});
}
private void initView() {
viewPager = findViewById(R.id.viewpager);
myViewPagerAdapter = new MyViewPagerAdapter(this,imglist);
viewPager.setAdapter(myViewPagerAdapter);
points = findViewById(R.id.points);
for(int i = 0;i<imglist.length;i++) {
//白点
//根据viewPager的数量,添加白点指示器
ImageView view = new ImageView(this);
view.setBackgroundResource(R.drawable.point_back);
//给点设置宽高
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(20, 20);
//给控件设置边距
params.leftMargin = 10;
//给view设置参数
view.setLayoutParams(params);
//将图片添加到线性布局中
points.addView(view);
}
points.getChildAt(0).setBackgroundResource(R.drawable.point_white);
viewPager.setCurrentItem(0);
}
}
适配器配置
这里把需要浏览的图片地址数组传递过去,然后通过Gilde加载网络图片, 并以PhotoView代替ImageView实现放大缩小功能
package com.huncm.photoviewdemo;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.viewpager.widget.PagerAdapter;
import com.github.chrisbanes.photoview.PhotoView;
public class MyViewPagerAdapter extends PagerAdapter {
private String[] imgList;
private Context context;
public MyViewPagerAdapter(Context context,String[] imgList){
this.imgList = imgList;
this.context = context;
}
@Override
public int getCount() {
return imgList.length;
}
//指定复用的判断逻辑,固定写法:view == object
@Override
public boolean isViewFromObject(View view, Object object) {
//当创建新的条目,又反回来,判断view是否可以被复用(即是否存在)
return view == object;
}
//返回要显示的条目内容
@Override
public Object instantiateItem(ViewGroup container, int position) {
//container 容器 相当于用来存放imageView
PhotoView photoView = new PhotoView(context);
photoView.setScaleType(ImageView.ScaleType.FIT_CENTER);
ImageLoader.display(context,photoView,imgList[position]);
//把图片添加到container中
container.addView(photoView);
//把图片返回给框架,用来缓存
return photoView;
}
//销毁条目
@Override