代码语言
.
CSharp
.
JS
Java
Asp.Net
C
MSSQL
PHP
Css
PLSQL
Python
Shell
EBS
ASP
Perl
ObjC
VB.Net
VBS
MYSQL
GO
Delphi
AS
DB2
Domino
Rails
ActionScript
Scala
代码分类
文件
系统
字符串
数据库
网络相关
图形/GUI
多媒体
算法
游戏
Jquery
Extjs
Android
HTML5
菜单
网页交互
WinForm
控件
企业应用
安全与加密
脚本/批处理
开放平台
其它
【
Java
】
瀑布流
作者:
爱4妮
/ 发布于
2015/1/4
/
453
package com.xiaoyun.org.app.ui; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import org.json.JSONArray; import org.json.JSONObject; import com.alibaba.fastjson.JSON; import com.nostra13.universalimageloader.core.DisplayImageOptions; import com.nostra13.universalimageloader.core.assist.ImageScaleType; import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer; import com.nostra13.universalimageloader.core.display.SimpleBitmapDisplayer; import com.nostra13.universalimageloader.core.listener.ImageLoadingListener; import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener; import com.xiaoyun.org.R; import com.xiaoyun.org.app.bean.ImageData; import com.xiaoyun.org.app.common.Constant; import com.xiaoyun.org.app.common.UIHelper; import com.xiaoyun.org.util.HttpUtil; import com.xiaoyun.org.util.ImageLoader; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.os.AsyncTask; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.ImageView; import android.widget.ImageView.ScaleType; import android.widget.LinearLayout; import android.widget.ScrollView; import android.widget.Toast; /** * 自定义的ScrollView,在其中动态地对图片进行添加。 * * @author guolin */ public class MyScrollView extends ScrollView implements OnTouchListener { /** * 每页要加载的图片数量 */ public static final int PAGE_SIZE = 15; /** * 记录当前已加载到第几页 */ private int page; /** * 每一列的宽度 */ private int columnWidth; /** * 当前第一列的高度 */ private int firstColumnHeight; /** * 当前第二列的高度 */ private int secondColumnHeight; /** * 当前第三列的高度 */ private int thirdColumnHeight; /** * 是否已加载过一次layout,这里onLayout中的初始化只需加载一次 */ private boolean loadOnce; /** * 对图片进行管理的工具类 */ private ImageLoader imageLoader; /** * 第一列的布局 */ private LinearLayout firstColumn; /** * 第二列的布局 */ private LinearLayout secondColumn; /** * 第三列的布局 */ private LinearLayout thirdColumn; /** * 记录所有正在下载或等待下载的任务。 */ private static Set<LoadImageTask> taskCollection; /** * MyScrollView下的直接子布局。 */ private static View scrollLayout; /** * MyScrollView布局的高度。 */ private static int scrollViewHeight; /** * 记录上垂直方向的滚动距离。 */ private static int lastScrollY = -1; /** * 记录所有界面上的图片,用以可以随时控制对图片的释放。 */ private List<ImageView> imageViewList = new ArrayList<ImageView>(); private final static int INIT_LOAD = 1; List<ImageData> data = new ArrayList<ImageData>(); String[] imageUrls = new String[Constant.DATA_SIZE]; private DisplayImageOptions options; private ImageLoadingListener animateFirstListener = new AnimateFirstDisplayListener(); /** * 在Handler中进行图片可见性检查的判断,以及加载更多图片的操作。 */ private static Handler handler = new Handler() { public void handleMessage(android.os.Message msg) { MyScrollView myScrollView = (MyScrollView) msg.obj; int scrollY = myScrollView.getScrollY(); // 如果当前的滚动位置和上次相同,表示已停止滚动 if (scrollY == lastScrollY) { // 当滚动的最底部,并且当前没有正在下载的任务时,开始加载下一页的图片 if (scrollViewHeight + scrollY >= scrollLayout.getHeight() && taskCollection.isEmpty()) { myScrollView.loadMoreImages(); } myScrollView.checkVisibility(); } else { lastScrollY = scrollY; Message message = new Message(); message.obj = myScrollView; // 5毫秒后再次对滚动位置进行判断 handler.sendMessageDelayed(message, 5); } }; }; /** * MyScrollView的构造函数。 * * @param context * @param attrs */ public MyScrollView(Context context, AttributeSet attrs) { super(context, attrs); options = new DisplayImageOptions.Builder() .showImageOnFail(R.drawable.empty_photo).cacheInMemory(true) .cacheOnDisk(true).considerExifParams(true) .bitmapConfig(Bitmap.Config.RGB_565).delayBeforeLoading(10) .displayer(new SimpleBitmapDisplayer())// //正常显示一张图片 .build(); imageLoader = ImageLoader.getInstance(); taskCollection = new HashSet<LoadImageTask>(); setOnTouchListener(this); } /** * 进行一些关键性的初始化操作,获取MyScrollView的高度,以及得到第一列的宽度值。并在这里开始加载第一页的图片。 */ @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { super.onLayout(changed, l, t, r, b); if (changed && !loadOnce) { scrollViewHeight = getHeight(); scrollLayout = getChildAt(0); firstColumn = (LinearLayout) findViewById(R.id.first_column); secondColumn = (LinearLayout) findViewById(R.id.second_column); thirdColumn = (LinearLayout) findViewById(R.id.third_column); columnWidth = firstColumn.getWidth(); loadOnce = true; loadHandler.obtainMessage(INIT_LOAD).sendToTarget(); } } private Handler loadHandler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case INIT_LOAD: loadData(Constant.planet, Constant.WidthAndHeight); break; default: break; } super.handleMessage(msg); } }; /** * 获取全部的图片数据 * * @param account * @param pwd * @param isRememberMe */ private void loadData(final String planets, final String widthandheight) { final Handler handler = new Handler() { public void handleMessage(Message msg) { Object obj = msg.obj; if (msg.what == 1) { for (int i = 0; i < data.size() - 1; i++) { imageUrls[i] = data.get(i).getDownload_url(); } loadMoreImages(); } if (msg.what == -1) { UIHelper.ToastMessage(getContext(), "加载失败"); } } }; new Thread() { public void run() { Message msg = Message.obtain(); int what = -1; Object obj = "获取数据失败"; String url = planets + "&" + widthandheight; String Content = ""; JSONObject mJsonObject; try { data.clear(); Content = HttpUtil.getContent(url); mJsonObject = new JSONObject(Content); JSONArray mJsonArray = mJsonObject.getJSONArray("data"); ImageData imageData = null; for (int k = 0; k < mJsonArray.length(); k++) { JSONObject objs = mJsonArray.getJSONObject(k); imageData = JSON.parseObject(objs.toString(), ImageData.class); data.add(imageData); } what = 1; } catch (Exception e) { e.printStackTrace(); } msg.what = what; msg.obj = obj; handler.sendMessage(msg); } }.start(); } /** * 监听用户的触屏事件,如果用户手指离开屏幕则开始进行滚动检测。 */ @Override public boolean onTouch(View v, MotionEvent event) { if (event.getAction() == MotionEvent.ACTION_UP) { Message message = new Message(); message.obj = this; handler.sendMessageDelayed(message, 5); } return false; } /** * 开始加载下一页的图片,每张图片都会开启一个异步线程去下载。 */ public void loadMoreImages() { if (hasSDCard()) { int startIndex = page * PAGE_SIZE; int endIndex = page * PAGE_SIZE + PAGE_SIZE; if (startIndex < imageUrls.length) { UIHelper.ToastMessage(getContext(), "正在加载……"); if (endIndex > imageUrls.length) { endIndex = imageUrls.length; } for (int i = startIndex; i < endIndex; i++) { LoadImageTask task = new LoadImageTask(); taskCollection.add(task); task.execute(imageUrls[i]); } page++; } else { UIHelper.ToastMessage(getContext(), "已没有更多图片"); } } else { UIHelper.ToastMessage(getContext(), "未发现SD卡"); } } /** * 遍历imageViewList中的每张图片,对图片的可见性进行检查,如果图片已经离开屏幕可见范围,则将图片替换成一张空图。 */ public void checkVisibility() { for (int i = 0; i < imageViewList.size(); i++) { ImageView imageView = imageViewList.get(i); int borderTop = (Integer) imageView.getTag(R.string.border_top); int borderBottom = (Integer) imageView .getTag(R.string.border_bottom); if (borderBottom > getScrollY() && borderTop < getScrollY() + scrollViewHeight) { String imageUrl = (String) imageView.getTag(R.string.image_url); com.nostra13.universalimageloader.core.ImageLoader .getInstance().displayImage(imageUrl, imageView, options, animateFirstListener); } else { imageView.setImageResource(R.drawable.empty_photo); } } } /** * 判断手机是否有SD卡。 * * @return 有SD卡返回true,没有返回false。 */ private boolean hasSDCard() { return Environment.MEDIA_MOUNTED.equals(Environment .getExternalStorageState()); } /** * 异步下载图片的任务。 * * @author guolin */ class LoadImageTask extends AsyncTask<String, Void, Bitmap> { /** * 图片的URL地址 */ private String mImageUrl; /** * 可重复使用的ImageView */ private ImageView mImageView; public LoadImageTask() { } /** * 将可重复使用的ImageView传入 * * @param imageView */ public LoadImageTask(ImageView imageView) { mImageView = imageView; } @Override protected Bitmap doInBackground(String... params) { mImageUrl = params[0]; return null; } @Override protected void onPostExecute(Bitmap bitmap) { addImage(bitmap, columnWidth, Constant.height/3); taskCollection.remove(this); } /** * 向ImageView中添加一张图片 * * @param bitmap * 待添加的图片 * @param imageWidth * 图片的宽度 * @param imageHeight * 图片的高度 */ private void addImage(Bitmap bitmap, int imageWidth, int imageHeight) { LinearLayout.LayoutParams params = new LinearLayout.LayoutParams( imageWidth, imageHeight); if (mImageView != null) { com.nostra13.universalimageloader.core.ImageLoader .getInstance().displayImage(mImageUrl, mImageView, options, animateFirstListener); } else { ImageView imageView = new ImageView(getContext()); imageView.setLayoutParams(params); imageView.setScaleType(ScaleType.FIT_XY); imageView.setPadding(5, 5, 5, 5); imageView.setTag(R.string.image_url, mImageUrl); findColumnToAdd(imageView, imageHeight).addView(imageView); imageViewList.add(imageView); com.nostra13.universalimageloader.core.ImageLoader .getInstance().displayImage(mImageUrl, imageView, options, animateFirstListener); //downloadImage(mImageUrl); imageView.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub String imageUrl = mImageUrl; Intent intent = new Intent(getContext(), ImageScaleActivity.class); if ("null".equals(imageUrl)) { imageUrl = "http://h.hiphotos.baidu.com/image/pic/item/4bed2e738bd4b31c4859e0ba85d6277f9e2ff84e.jpg"; } intent.putExtra("filePath", imageUrl); getContext().startActivity(intent); } }); } } /** * 找到此时应该添加图片的一列。原则就是对三列的高度进行判断,当前高度最小的一列就是应该添加的一列。 * * @param imageView * @param imageHeight * @return 应该添加图片的一列 */ private LinearLayout findColumnToAdd(ImageView imageView, int imageHeight) { if (firstColumnHeight <= secondColumnHeight) { if (firstColumnHeight <= thirdColumnHeight) { imageView.setTag(R.string.border_top, firstColumnHeight); firstColumnHeight += imageHeight; imageView.setTag(R.string.border_bottom, firstColumnHeight); return firstColumn; } imageView.setTag(R.string.border_top, thirdColumnHeight); thirdColumnHeight += imageHeight; imageView.setTag(R.string.border_bottom, thirdColumnHeight); return thirdColumn; } else { if (secondColumnHeight <= thirdColumnHeight) { imageView.setTag(R.string.border_top, secondColumnHeight); secondColumnHeight += imageHeight; imageView .setTag(R.string.border_bottom, secondColumnHeight); return secondColumn; } imageView.setTag(R.string.border_top, thirdColumnHeight); thirdColumnHeight += imageHeight; imageView.setTag(R.string.border_bottom, thirdColumnHeight); return thirdColumn; } } /** * 将图片下载到SD卡缓存起来。 * * @param imageUrl * 图片的URL地址。 */ private void downloadImage(String imageUrl) { if (Environment.getExternalStorageState().equals( Environment.MEDIA_MOUNTED)) { Log.d("TAG", "monted sdcard"); } else { Log.d("TAG", "has no sdcard"); } HttpURLConnection con = null; FileOutputStream fos = null; BufferedOutputStream bos = null; BufferedInputStream bis = null; File imageFile = null; try { imageFile = new File(getImagePath(imageUrl)); // 初始化一个URL对象 URL mUrl = new URL(imageUrl); // 获得HTTPConnection网络连接对象 HttpURLConnection conn = (HttpURLConnection) mUrl .openConnection(); // conn.setDoInput(true); // conn.connect(); conn.setConnectTimeout(5000); conn.setRequestMethod("GET"); conn.setDoInput(true); conn.connect(); if (conn.getResponseCode() == 200) { // 得到输入流 然后写入sd卡 InputStream is = conn.getInputStream(); fos = new FileOutputStream(imageFile); byte[] buffer = new byte[1024 * 2]; int len = 0; while ((len = is.read(buffer)) != -1) { fos.write(buffer, 0, len); } // 关闭输入流 is.close(); fos.close(); } // 关闭连接 conn.disconnect(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } if (imageFile != null) { Bitmap bitmap = ImageLoader.decodeSampledBitmapFromResource( imageFile.getPath(), columnWidth); if (bitmap != null) { imageLoader.addBitmapToMemoryCache(imageUrl, bitmap); } } } /** * 获取图片的本地存储路径。 * * @param imageUrl * 图片的URL地址。 * @return 图片的本地存储路径。 */ private String getImagePath(String imageUrl) { int lastSlashIndex = imageUrl.lastIndexOf("/"); String imageName = imageUrl.substring(lastSlashIndex + 1); String imageDir = Environment.getExternalStorageDirectory() .getPath() + "/51mzt/"; File file = new File(imageDir); if (!file.exists()) { file.mkdirs(); } String imagePath = imageDir + imageName; return imagePath; } } private static class AnimateFirstDisplayListener extends SimpleImageLoadingListener { static final List<String> displayedImages = Collections .synchronizedList(new LinkedList<String>()); @Override public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) { if (loadedImage != null) { ImageView imageView = (ImageView) view; boolean firstDisplay = !displayedImages.contains(imageUri); if (firstDisplay) { FadeInBitmapDisplayer.animate(imageView, 500); displayedImages.add(imageUri); } } } } }
试试其它关键字
瀑布流
同语言下
.
List 切割成几份 工具类
.
一行一行读取txt的内容
.
Java PDF转换成图片并输出给前台展示
.
java 多线程框架
.
double类型如果小数点后为零则显示整数否则保留两位小
.
将图片转换为Base64字符串公共类抽取
.
sqlParser 处理SQL(增删改查) 替换schema 用于多租户
.
JAVA 月份中的第几周处理 1-7属于第一周 依次类推 29-
.
java计算两个经纬度之间的距离
.
输入时间参数计算年龄
可能有用的
.
C#实现的html内容截取
.
List 切割成几份 工具类
.
SQL查询 多列合并成一行用逗号隔开
.
一行一行读取txt的内容
.
C#动态修改文件夹名称(FSO实现,不移动文件)
.
c# 移动文件或文件夹
.
c#图片添加水印
.
Java PDF转换成图片并输出给前台展示
.
网站后台修改图片尺寸代码
.
处理大图片在缩略图时的展示
爱4妮
贡献的其它代码
(
1
)
.
瀑布流
Copyright © 2004 - 2024 dezai.cn. All Rights Reserved
站长博客
粤ICP备13059550号-3