失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > Android---仿QQ空间动态九宫格图片预览(一)

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

时间:2019-03-22 16:56:43

相关推荐

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

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

文章目录

Android---仿QQ空间动态九宫格图片预览(一)NineGridImageView(九宫格图片控件)预览效果特性用法demo代码PhotoView控件效果预览使用使用ViewPager和PhotoView实现图片浏览添加依赖XML文件使用GlideActivity层操作适配器配置

星光不负赶路人,时间不负有心人,每当你在感叹,如果有这样一个东西就好了,请注意其实这是你的机会。

最近在做课程设计 🚌 ,发现自己要实现一个类似QQ 动态里面的图片九宫格预览效果的控件😑 ,自己本着大佬造轮子,自己在轮子上面改善,达到自己要到效果,结果搞了几天才搞好,达到自己想要的效果,这是一个一波三折的过程,自己也看了很多源码,虽然很多也是似懂非懂的,毕竟是初学者,对很多底层适配器不是很懂🐶 ,但是终于被我搞出来了,顺便写一篇博客记录一下。

NineGridImageView(九宫格图片控件)

这是我在网上找到一个大佬的自定义的组件,我试了一下

NineGridImageView(九宫格图片控件)

预览效果

特性

设置图片之间的间隔

app:imgGap="4dp"nineGridImageView.setGap(int gap);

设置最大图片数:

app:maxSize="9"或者nineGridImageView.setMaxSize(int maxSize)

如果最大图片数小于等于0,则没有图片数的限制。

设置显示样式

app:showStyle="fill"nineGridImageView.setShowStyle(int style);

默认样式是网格样式:STYLE_GRID

另外一种样式是:STYLE_FILL

当只有一张图的时候,可以设置其显示大小,不让其显示的过小:

app:singleImgSize="120dp"nineGridImageView.setSingleImgSize(int singleImgSize)

用法

首先添加依赖

implement 'com.jaeger.ninegridimageview:library:1.0.2'implementation 'com.github.bumptech.glide:glide:4.12.0'annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0'

AndroidManifest.xml添加权限

<uses-permission android:name="android.permission.INTERNET"/><uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />android:requestLegacyExternalStorage="true"android:usesCleartextTraffic="true"

在布局文件中添加 NineGridImageView, 如下所示:

<com.jaeger.ninegridimageview.NineGridImageViewxmlns:app="/apk/res-auto"android:layout_height="wrap_content"android:layout_margin="16dp"android:layout_width="match_parent"app:imgGap="4dp"app:showStyle="fill"app:singleImgSize="120dp"/>

为 NineGridImageView 设置 NineGridImageViewAdapter

nineGridImageView.setAdapter(nineGridViewAdapter);

下面是NineGridImageViewAdapter.class的源码:

public abstract class NineGridImageViewAdapter<T> {protected abstract void onDisplayImage(Context context, ImageView imageView, T t);protected void onItemImageClick(Context context, int index, List<T> 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<T> list)方法,加上你自己的处理逻辑;如果你要使用自定义的ImageView,你可以重写generateImageView(Context context)方法, 去生成自定的ImageView

下面是一段示例代码:

private NineGridImageViewAdapter<Photo> mAdapter = new NineGridImageViewAdapter<Photo>() {@Overrideprotected void onDisplayImage(Context context, ImageView imageView, Photo photo) {Picasso.with(context).load(photo.getSmallUrl).placeholder(R.drawable.ic_default_image).into(imageView);}@Overrideprotected ImageView generateImageView(Context context) {return super.generateImageView(context);}@Overrideprotected void onItemImageClick(Context context, int index, List<Photo> photoList) {showBigPicture(context, photoList.get(index).getBigUrl());}...mNineGridImageView.setAdapter(mAdapter);...

给 NineGridImageView 设置图片数据:

nineGridImageView.setImagesData(List<T> 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 {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);List<String> list = new ArrayList<>();list.add("/gh/Yqifei/Blog-Image@master/1026/image.6719h9mvs700.png");list.add("https://img-/img_convert/8dc4978a27ba3ccdaa697c2d7814f3ac.png");list.add("https://img-/img_convert/52f5dd5a02ab958c9a2b4daa825925e5.png");list.add("/gh/Yqifei/Blog-Image@master/1026/image.6719h9mvs700.png");list.add("https://img-/img_convert/8dc4978a27ba3ccdaa697c2d7814f3ac.png");NineGridImageView nineGridImageView = findViewById(R.id.nineGridImageView);nineGridImageView.setAdapter(myadpter);nineGridImageView.setImagesData( list);}private NineGridImageViewAdapter <String> myadpter = new NineGridImageViewAdapter<String>() {@Overrideprotected void onDisplayImage(Context context, ImageView imageView, String url) {Glide.with(context).load(url).into(imageView);}@Overrideprotected void onItemImageClick(Context context, int index, List<String> list) {super.onItemImageClick(context, index, list);}@Overrideprotected ImageView generateImageView(Context context) {return super.generateImageView(context);}};}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><com.jaeger.ninegridimageview.NineGridImageViewandroid: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等的拖动切换;

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

支持各种回调给调用者;

效果预览

使用

在根文件(不是模块文件)中添加此: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'

编写布局文件

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity2"><com.github.chrisbanes.photoview.PhotoViewandroid: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 {@Overrideprotected 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-/img_convert/52f5dd5a02ab958c9a2b4daa825925e5.png").into(photoView);}}

写到这里QQ九宫格也算是实现了一半,如果只是这两个控件的话,实现的QQ九宫格图片不能预览,也不能左滑右滑,我便在网上搜索了一波。找到一种解决方法:使用ViewPager和PhotoView实现图片浏览

使用ViewPager和PhotoView实现图片浏览

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

添加依赖

build.gradle (app)

//photoViewimplementation 'com.github.chrisbanes:PhotoView:2.0.0'//glideimplementation '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 添加网络权限

<uses-permission android:name="android.permission.INTERNET"/>

XML文件

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="/apk/res/android"xmlns:app="/apk/res-auto"xmlns:tools="/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.viewpager.widget.ViewPagerandroid: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><LinearLayoutandroid: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"></LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>

使用Glide

这里使用Glide来加载网络图片,Gilde自从4.0.0版本开始要通过生成GlideApp类来使用各种Api,那么就开始动手实践吧

生成GlideApp

首先创建MyAppGlideModule类

@GlideModulepublic final class MyAppGlideModule extends AppGlideModule {}

build ->Rebuild Project

封装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 = {"/gh/Yqifei/Blog-Image@master/0427/image.2c9e9xfoi3b4.png","/gh/Yqifei/Blog-Image@master/0427/image.17irwo5suuxs.png","/gh/Yqifei/Blog-Image@master/0427/image.2oi4dcxsc1c0.png","/gh/Yqifei/Blog-Image@master/0427/image.2m80368jvr80.png","/gh/Yqifei/Blog-Image@master/0427/image.65n8rjffvk00.png","/gh/Yqifei/Blog-Image@master/0427/image.75iaxbwd0fk0.png"};private LinearLayout points;private int prePosition;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initView();initData();}private void initData() {viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {@Overridepublic 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;}@Overridepublic void onPageSelected(int i) {}@Overridepublic 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;}@Overridepublic int getCount() {return imgList.length;}//指定复用的判断逻辑,固定写法:view == object@Overridepublic boolean isViewFromObject(View view, Object object) {//当创建新的条目,又反回来,判断view是否可以被复用(即是否存在)return view == object;}//返回要显示的条目内容@Overridepublic Object instantiateItem(ViewGroup container, int position) {//container 容器 相当于用来存放imageViewPhotoView photoView = new PhotoView(context);photoView.setScaleType(ImageView.ScaleType.FIT_CENTER);ImageLoader.display(context,photoView,imgList[position]);//把图片添加到container中container.addView(photoView);//把图片返回给框架,用来缓存return photoView;}//销毁条目@Overridepublic void destroyItem(ViewGroup container, int position, Object object) {//object:刚才创建的对象,即要销毁的对象container.removeView((View) object);}}

Demo地址

接下文: Android—仿QQ空间动态九宫格图片预览(二)

如果觉得《Android---仿QQ空间动态九宫格图片预览(一)》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。