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

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) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

最后

我的面试经验分享可能不会去罗列太多的具体题目,因为我依然认为面试经验中最宝贵的不是那一个个具体的题目或者具体的答案,而是结束面试时,那一刻你的感受以及多天之后你的回味~

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

【算法合集】

【延伸Android必备知识点】

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

经验分享可能不会去罗列太多的具体题目,因为我依然认为面试经验中最宝贵的不是那一个个具体的题目或者具体的答案,而是结束面试时,那一刻你的感受以及多天之后你的回味~

很多人在刚接触这个行业的时候或者是在遇到瓶颈期的时候,总会遇到一些问题,比如学了一段时间感觉没有方向感,不知道该从那里入手去学习,对此我整理了一些资料,需要的可以免费分享给大家

在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

【Android核心高级技术PDF文档,BAT大厂面试真题解析】

[外链图片转存中…(img-DxWnLU8X-1712537881369)]

【算法合集】

[外链图片转存中…(img-DZajtOGM-1712537881370)]

【延伸Android必备知识点】

[外链图片转存中…(img-E7c7jNZo-1712537881370)]

【Android部分高级架构视频学习资源】

**Android精讲视频领取学习后更加是如虎添翼!**进军BATJ大厂等(备战)!现在都说互联网寒冬,其实无非就是你上错了车,且穿的少(技能),要是你上对车,自身技术能力够强,公司换掉的代价大,怎么可能会被裁掉,都是淘汰末端的业务Curd而已!现如今市场上初级程序员泛滥,这套教程针对Android开发工程师1-6年的人员、正处于瓶颈期,想要年后突破自己涨薪的,进阶Android中高级、架构师对你更是如鱼得水,赶快领取吧!

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值