Android---仿QQ空间动态九宫格图片预览(一)

}

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);

  1. 给 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

<?xml version="1.0" encoding="utf-8"?>

<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

PhotoView控件


简单的介绍

这是一个图片查看库,实现图片浏览功能,支持pinch(捏合)手势或者点击放大缩小。支持在ViewPager中翻页浏览图片。

PhotoView 是一款扩展自Android ImageView ,支持通过单点/多点触摸来进行图片缩放的智能控件。功能实用和强大。

特性

可以用于查看图片,并对图片进行拖动缩放,拖动过程中不会出现边缘空白;

双击缩小放大,Fling移动,并支持上述过程的渐变;

在放大情况下也支持viewpager等的拖动切换;

支持多击事件检测,单机,双击事件;

支持各种回调给调用者;

效果预览

image

使用

  1. 在根文件(不是模块文件)中添加此:build.gradle

allprojects {

repositories {

maven { url “https://www.jitpack.io” }

}

}

buildscript {

repositories {

maven { url “https://www.jitpack.io” }

}

}

  1. 导入依赖

implementation ‘com.github.chrisbanes:PhotoView:2.0.0’

  1. 编写布局文件
<?xml version="1.0" encoding="utf-8"?>

<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>

  1. 编写逻辑代码

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实现图片浏览

使用ViewPager和PhotoView实现图片浏览


使用photoView实现图片的放大缩小,再使用viewPager实现图片的左右滑动

image

添加依赖

  • 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
<?xml version="1.0" encoding="utf-8"?>

<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,那么就开始动手实践吧

  1. 生成GlideApp
  • 首先创建MyAppGlideModule类

@GlideModule

public final class MyAppGlideModule extends AppGlideModule {

}

  • build ->Rebuild Project

image

  1. 封装ImageLoading类

因为我这里只是一个测试Demo,所以这是封装了一种方法,Glide的 功能很强大,如加载gif图, 实现模糊 等等操作,这里插入一个大佬写的Glide专栏

Android图片加载框架最全解析----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

NineGridImageView 是九宫格图片控件。用法1. 首先添加依赖compile 'com.jaeger.ninegridimageview:library:1.0.0'2. 在布局文件中添加 NineGridImageView, 如下所示:nineGridImageView.setAdapter(nineGridViewAdapter);下面是 NineGridImageViewAdapter.class 的源码:public abstract class NineGridImageViewAdapter {     protected abstract void onDisplayImage(Context context, ImageView imageView, T t);     protected void onItemImageClick(Context context, int index, List list) {          }     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 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);...4. 给 NineGridImageView 设置图片数据:nineGridImageView.setImagesData(List imageDataList);图片展示:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值