实现一个简单的照片墙。

实现原理:

1:去重复 相同的url不要下载两次,可以用set集合对封装的任务,但是我们应用使用了内存缓存即使不做判断也不会加载两次,因为LruCache对象已经帮我们实现了

2:下载图片的任务使用了AsyncTask

3: 当我们快速滑动屏幕的时候怎么做到当手指松开的时候才加载可见屏幕范围对应的图片,避免了快速滑动导致卡的问题

activity_main.xml

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

android:paddingBottom="@dimen/activity_vertical_margin"

android:paddingLeft="@dimen/activity_horizontal_margin"

android:paddingRight="@dimen/activity_horizontal_margin"

android:paddingTop="@dimen/activity_vertical_margin"

tools:context=".MainActivity">

android:id="@+id/photo_wall"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:columnWidth="90dip"

android:gravity="center"

android:numColumns="auto_fit"

android:stretchMode="columnWidth"

android:verticalSpacing="10dip" />

Constant.java

public class Constant {

public static String[] imgs = new String[]{

"http://img5.douban.com/view/photo/thumb/public/p1042461956.jpg",

"http://img5.douban.com/lpic/s28035816.jpg",

"http://img3.douban.com/lpic/s28049685.jpg",

"http://img5.douban.com/lpic/s28004598.jpg",

"http://img5.douban.com/lpic/s28050639.jpg",

"http://img3.douban.com/lpic/s28056884.jpg",

"http://img5.douban.com/lpic/s28036379.jpg",

"http://img5.douban.com/lpic/s28045199.jpg",

"http://img3.douban.com/lpic/s28034923.jpg",

"http://img5.douban.com/lpic/s28067039.jpg",

"http://img3.douban.com/spic/s28000872.jpg",

"http://img3.douban.com/view/movie_poster_cover/mpst/public/p2237747953.jpg",

"http://img5.douban.com/view/movie_poster_cover/mpst/public/p2240110789.jpg",

"http://img5.douban.com/view/movie_poster_cover/mpst/public/p2235609577.jpg",

"http://img5.douban.com/view/movie_poster_cover/mpst/public/p2233113686.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2225188257.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2201518484.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2229383316.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2222477444.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2230484792.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2204911658.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2210568759.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2201468648.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2226169113.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2221319641.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2231932406.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2208286457.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2203481530.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2232079769.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2224484447.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2233767512.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2202114105.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2209761319.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2230222544.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2220776342.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2233840624.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2194199028.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2230222544.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2220776342.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2233840624.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2194199028.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2233260210.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2210832820.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2203693875.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2231791943.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2203838902.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2220218254.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2215268072.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2219669553.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2208934451.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2225669293.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2225986472.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2199678535.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2230471461.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2204888387.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2224389662.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2207808539.jpg",

"http://img5.douban.com/view/movie_poster_cover/lpst/public/p2225291257.jpg",

"http://img3.douban.com/view/movie_poster_cover/lpst/public/p2230505723.jpg"

};

}

ImageLoaderAdapter.java

package com.jackie.photowall;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.os.AsyncTask;

import android.util.LruCache;

import android.view.LayoutInflater;

import android.view.View;

import android.view.ViewGroup;

import android.widget.AbsListView;

import android.widget.BaseAdapter;

import android.widget.GridView;

import android.widget.ImageView;

import java.io.IOException;

import java.net.HttpURLConnection;

import java.net.MalformedURLException;

import java.net.URL;

import java.util.HashSet;

import java.util.Set;

/**

* Created by Jackie on 5/14/15.

*/

public class ImageLoaderAdapter extends BaseAdapter implements AbsListView.OnScrollListener {

private Activity mActivity;

private GridView mGridView;

private LayoutInflater mInflater;

/**

* 图片缓存技术的核心类,用于缓存所有下载好的图片,在程序内存达到设定值时会将最少最近使用的图片移除掉。

*/

private LruCache mMemoryCache;

/**

* 记录所有正在下载或等待下载的任务。

*/

private Set mImageLoaderTasks;

/**

* 第一张可见图片的下标

*/

private int mFirstVisibleItem;

/**

* 可见区域一屏有多少张图片

*/

private int mVisibleItemCount;

/**

* 代表第一次进来不滑动的时候自动加载图片

*/

private boolean mIsFirstLoader = true;

public ImageLoaderAdapter(GridView mGridView, Activity mActivity) {

this.mActivity = mActivity;

this.mGridView = mGridView;

mInflater = LayoutInflater.from(mActivity);

mImageLoaderTasks = new HashSet();

/**

* 获取应用给app分配的内存空间

*/

int maxMemory = (int) Runtime.getRuntime().maxMemory();

/**

* 给图片分配合理的内容空间

*/

int cacheSize = maxMemory / 8;

mMemoryCache = new LruCache(cacheSize) {

@Override

protected int sizeOf(String key, Bitmap bitmap) {

return bitmap.getByteCount();

}

};

mGridView.setOnScrollListener(this);

}

@Override

public int getCount() {

return Constant.imgs != null && Constant.imgs.length > 0 ? Constant.imgs.length : 0;

}

@Override

public Object getItem(int position) {

return Constant.imgs[position];

}

@Override

public long getItemId(int position) {

return position;

}

@Override

public View getView(int position, View convertView, ViewGroup arg2) {

final String url = (String) getItem(position);

ViewHolder holder = null;

if (convertView == null) {

convertView = mInflater.inflate(R.layout.img_item, null);

holder = new ViewHolder();

holder.imageview = (ImageView) convertView.findViewById(R.id.imageview);

convertView.setTag(holder);

} else {

holder = (ViewHolder) convertView.getTag();

}

/**

* 给ImageView设置一个Tag,保证异步加载图片时不会乱序

*/

holder.imageview.setTag(url);

setImageView(url, holder.imageview);

return convertView;

}

/**

* 首先用url到缓存中找 如果没有就显示默认图片 如果缓存中有 就显示

*

* @param url 要显示图片的url

* @param imageview

*/

private void setImageView(String url, ImageView imageview) {

Bitmap bitmap = mMemoryCache.get(url);

if (bitmap != null && imageview != null) {

imageview.setImageBitmap(bitmap);

} else {

// imageview.setImageResource(R.drawable.empty_photo);

}

}

class ViewHolder {

ImageView imageview;

}

/**

* view 就是GridView

* firstVisibleItem 可见 第一个条目

* visibleItemCount 可见的总条目

* totalItemCount 要加载的总条目

*/

@Override

public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

mFirstVisibleItem = firstVisibleItem;

mVisibleItemCount = visibleItemCount;

if (mIsFirstLoader && visibleItemCount > 0) {

loadImages(firstVisibleItem, visibleItemCount);

mIsFirstLoader = false;

}

}

@Override

public void onScrollStateChanged(AbsListView view, int scrollState) {

// 仅当GridView静止时才去下载图片,GridView滑动时取消所有正在下载的任务

if (scrollState == SCROLL_STATE_IDLE) {

loadImages(mFirstVisibleItem, mVisibleItemCount);

} else {

cancelAllTasks();

}

}

private void cancelAllTasks() {

if (mImageLoaderTasks != null) {

for (ImageLoaderTask task : mImageLoaderTasks) {

task.cancel(false);

}

}

}

private void loadImages(int firstVisibleItem, int visibleItemCount) {

for (int i = firstVisibleItem; i < firstVisibleItem + visibleItemCount; i++) {

String imagUrl = Constant.imgs[i];

Bitmap bitmap = getBitmapFromMemory(imagUrl);

if (bitmap == null) {//从网络获取

ImageLoaderTask task = new ImageLoaderTask();

mImageLoaderTasks.add(task);

task.execute(imagUrl);

} else {//从缓存获取

ImageView imageView = (ImageView) mGridView.findViewWithTag(imagUrl);

if (imageView != null && bitmap != null) {

imageView.setImageBitmap(bitmap);

}

}

}

}

private Bitmap getBitmapFromMemory(String key) {

return mMemoryCache.get(key);

}

private class ImageLoaderTask extends AsyncTask {

String url = null;

@Override

protected Bitmap doInBackground(String... param) {

url = param[0];

/**

* 从网络上加载的图片 如果bitmap不为null 就加载到内存之中

*/

Bitmap bitmap = downLoadImage(url);

if (bitmap != null) {

// 图片下载完成后缓存到LrcCache中

addBitmapToMemoryCache(url, bitmap);

}

return bitmap;

}

@Override

protected void onPostExecute(Bitmap bitmap) {

super.onPostExecute(bitmap);

ImageView imageView = (ImageView) mGridView.findViewWithTag(url);

if (imageView != null && bitmap != null) {

imageView.setImageBitmap(bitmap);

}

/**

* 下载完了以后把该任务从集合中移除 可能有些人会说为什么要用hashset集合 因为他可以的任务不重复

*/

mImageLoaderTasks.remove(this);

}

}

public Bitmap downLoadImage(String imgUrl) {

Bitmap bitmap = null;

HttpURLConnection connection = null;

try {

URL url = new URL(imgUrl);

connection = (HttpURLConnection) url.openConnection();

connection.setConnectTimeout(5 * 1000);

connection.setReadTimeout(10 * 1000);

connection.setDoInput(true);

bitmap = BitmapFactory.decodeStream(connection.getInputStream());

} catch (MalformedURLException e) {

e.printStackTrace();

} catch (IOException e) {

e.printStackTrace();

} finally {

if (connection != null) {

connection.disconnect();

}

}

return bitmap;

}

/**

* 把图片加载到内存之中

*

* @param url 图片的url

* @param bitmap url对应的图片

*/

public void addBitmapToMemoryCache(String url, Bitmap bitmap) {

if (getBitmapFromMemory(url) == null) {

mMemoryCache.put(url, bitmap);

}

}

}

效果图:

标签:

网络

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com

特别注意:本站所有转载文章言论不代表本站观点!

本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。

android照片墙,Android照片墙的实现相关推荐

  1. Android瀑布流照片墙、滑动切换图片

    继续上一篇博客中提到的反编译"马蜂窝自由行"app. 今天看到下方这段效果不错,决定实现出来. 从Gif中我们看出这个其实就是一个照片墙加上一个图片滑动.在查看图片时还有个放大缩小 ...

  2. android之android.intent.category.DEFAULT的用途和使用

    1.要弄清楚这个问题,首先需要弄明白什么是implicit(隐藏) intent什么是explicit(明确) intent. Explicit Intent明确的指定了要启动的Acitivity , ...

  3. android:layout_with=,android – 难以理解layout_alignWithParentIfMissing

    这仅适用于使用RelativeLayout时. 如果您将元素设置为一个其他元素,则表示该元素位于该元素的左侧. 但是如果这个元素会丢失,因为你删除它,例如它将与父对齐. 举个例子 android:la ...

  4. [Android Studio] Android Studio常用快捷键

    [Android Studio] Android Studio常用快捷键 (会持续更新)这边讲的常用快捷键是指做完Keymap到Eclipse后的,不是纯Android Studio的,这边主要讲下比 ...

  5. Android利用android:indeterminateDrawable来实现ProgressBar三种方式

    方式1:(效果为补间动画一样) [html] view plaincopyprint? <ProgressBar android:layout_width="wrap_content& ...

  6. Android之Android实现浮层的上下滑动(支持内部添加View)

    前言 我K,今天居然是情人节,对于资深的单身狗来说,简直是个噩耗,今天注定是各种秀恩爱,心塞中.... 话题到此结束,管他什么情人节,今天给大家带来的是一个浮层的上下滑动,浮层滑动时分三种状态:全部显 ...

  7. Android 解决Android的TextView和EditText换行问题

    Android 解决Android的TextView和EditText换行问题 参考文章: (1)Android 解决Android的TextView和EditText换行问题 (2)https:// ...

  8. Xamarin Android教程Android基本知识版本介绍与系统介绍

    Xamarin Android教程Android基本知识版本介绍与系统介绍 Xamarin Android教程Android基本知识版本介绍与系统介绍,开发Andriod有时候不像iOS一样轻松,因为 ...

  9. 【Android】Android 设置Activity窗体 不显示标题和全屏显示

    [一]Android 设置Activity窗体 不显示标题 android:theme="@android:style/Theme.NoTitleBar" 1 <activi ...

  10. [Android]《Android艺术开发探索》第一章读书笔记

    1. 典型情况下生命周期分析 (1)一般情况下,当当前Activity从不可见重新变为可见状态时,onRestart方法就会被调用. (2)当用户打开新的Activity或者切换到桌面的时候,回调如下 ...

最新文章

  1. matlab 绘图3
  2. 十分钟了解分布式计算:Petuum
  3. 为什么Python类语法应该不同?
  4. 生成模型与判别模型区别
  5. 华为支持nfc功能的手机有哪些_四款带NFC功能的千元机,三星华为低至1399元!...
  6. sql server oracle特点,SQL Server 和 Oracle 以及 MySQL 有哪些区别
  7. C++11 多线程线程共享数据
  8. Win11右键菜单切回经典模式
  9. 调用未知DLL中的导出函数[转]
  10. SAXParseException An invalid XML character 问题的解决
  11. php 执行任务,php多进程执行任务的说明
  12. Kubernetes CKS【21】---Runtime Security -主机与容器行为安全分析(strace、/proc、env、falco)
  13. 视频水印去除工具哪个好
  14. 微信小程序服务器和app互通,解读:App 与小程序的互通能力和限制
  15. java上传文件怎么设置成777权限_777权限是什么意思?文件夹权限为777如何修改设置?...
  16. 前端保留两位有效数字_用js取小数点后两位的一些方法
  17. 违反开源项目GPL协议,法院判罚了!国内首例
  18. linux修改文件图标,Gnome怎么修改应用图标icon
  19. lstm 能耗预测_预测能耗第一部分
  20. input type 类型

热门文章

  1. auto install pkgs
  2. [附源码]java毕业设计校园跑腿系统
  3. 如何写好科研论文(学习笔记2000字)
  4. 蠡测机房重构之组合查询
  5. 基本算法4.1堆积木
  6. 一文直观理解编译型语言、解释型语言和脚本语言的区别
  7. 【Python百炼成魔】魂圣初入Python之Python最佳入门实践
  8. 华为校招有多难?千军万马过独木桥!
  9. java 开源 ai 生成新闻_IBM 发布了自动为新闻播报生成字幕的 AI 模型
  10. 维基解密主站点WikiLeaks.org在美国恢复访问