此文转载,非本人原创

package com.android.activity;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class ActAsyncTaskActivity extends Activity implements OnClickListener {
private PorterDuffView pViewA, pViewB, pViewC, pViewD;
public static final String[] STRING_ARR = {//
"http://developer.android.com/images/home/android-jellybean.png",//
"http://developer.android.com/images/home/design.png",//
"http://developer.android.com/images/home/google-play.png",//
"http://developer.android.com/images/home/google-io.png" };
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
pViewA = (PorterDuffView) findViewById(R.id.pViewA);
pViewA.setOnClickListener(this);
pViewB = (PorterDuffView) findViewById(R.id.pViewB);
pViewB.setOnClickListener(this);
pViewC = (PorterDuffView) findViewById(R.id.pViewC);
pViewC.setOnClickListener(this);
pViewD = (PorterDuffView) findViewById(R.id.pViewD);
pViewD.setOnClickListener(this);
}
public void onClick(View v) {
if (v instanceof PorterDuffView) {
PorterDuffView pdView = (PorterDuffView) v;
if (pdView.isLoading() == false) {
DownloadImgTask task = new DownloadImgTask(pdView);
task.execute(STRING_ARR[pdView.getId() % STRING_ARR.length]);
pdView.setPorterDuffMode(true);
pdView.setLoading(true);
pdView.setProgress(0);
pdView.invalidate();
}
}
}
}
package com.android.activity;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpParams;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.Log;
public class DownloadImgTask extends AsyncTask<String, Float, Bitmap> {
private static final String TAG="DownloadImgTask";
private PorterDuffView pdView;
public DownloadImgTask(PorterDuffView pdView) {
this.pdView = pdView;
}
/** 下载准备工作。在UI线程中调用。 */
protected void onPreExecute() {
Log.i(TAG, "onPreExecute");
}
/** 执行下载。在背景线程调用。 */
protected Bitmap doInBackground(String... params) {
Log.i(TAG, "doInBackground:" + params[0]);
HttpClient httpClient = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(params[0]);
InputStream is = null;
ByteArrayOutputStream baos = null;
try {
HttpResponse httpResponse = httpClient.execute(httpGet);
printHttpResponse(httpResponse);
HttpEntity httpEntity = httpResponse.getEntity();
long length = httpEntity.getContentLength();
Log.i(TAG, "content length=" + length);
is = httpEntity.getContent();
if (is != null) {
baos = new ByteArrayOutputStream();
byte[] buf = new byte[128];
int read = -1;
int count = 0;
while ((read = is.read(buf)) != -1) {
baos.write(buf, 0, read);
count += read;
publishProgress(count * 1.0f / length);
}
Log.i(TAG, "count=" + count + " length=" + length);
byte[] data = baos.toByteArray();
Bitmap bit = BitmapFactory.decodeByteArray(data, 0, data.length);
return bit;
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.close();
}
if (is != null) {
is.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
/** 更新下载进度。在UI线程调用。onProgressUpdate */
protected void onProgressUpdate(Float... progress) {
// LogOut.out(this, "onProgressUpdate");
pdView.setProgress(progress[0]);
}
/** 通知下载任务完成。在UI线程调用。 */
protected void onPostExecute(Bitmap bit) {
Log.i(TAG, "onPostExecute");
pdView.setPorterDuffMode(false);
pdView.setLoading(false);
pdView.setImageBitmap(bit);
}
protected void onCancelled() {
Log.i(TAG, "DownloadImgTask cancel...");
super.onCancelled();
}
private void printHttpResponse(HttpResponse httpResponse) {
Header[] headerArr = httpResponse.getAllHeaders();
for (int i = 0; i < headerArr.length; i++) {
Header header = headerArr[i];
Log.i(TAG, "name[" + header.getName() + "]value[" + header.getValue() + "]");
}
HttpParams params = httpResponse.getParams();
Log.i(TAG, String.valueOf(params));
Log.i(TAG, String.valueOf(httpResponse.getLocale()));
}
}
package com.android.activity;
import java.text.DecimalFormat;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
/**
* 自定义组件实现新浪微博的图片加载效果。<br/>
*
*
*
*/
public class PorterDuffView extends ImageView {
private static final String TAG="PorterDuffView";
/** 前景Bitmap高度为1像素。采用循环多次填充进度区域。 */
public static final int FG_HEIGHT = 1;
/** 下载进度前景色 */
// public static final int FOREGROUND_COLOR = 0x77123456;
public static final int FOREGROUND_COLOR = 0x77ff0000;
/** 下载进度条的颜色。 */
public static final int TEXT_COLOR = 0xff7fff00;
/** 进度百分比字体大小。 */
public static final int FONT_SIZE = 30;
private Bitmap bitmapBg, bitmapFg;
private Paint paint;
/** 标识当前进度。 */
private float progress;
/** 标识进度图片的宽度与高度。 */
private int width, height;
/** 格式化输出百分比。 */
private DecimalFormat decFormat;
/** 进度百分比文本的锚定Y中心坐标值。 */
private float txtBaseY;
/** 标识是否使用PorterDuff模式重组界面。 */
private boolean porterduffMode;
/** 标识是否正在下载图片。 */
private boolean loading;
public PorterDuffView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context, attrs);
}
/** 生成一宽与背景图片等同高为1像素的Bitmap,。 */
private static Bitmap createForegroundBitmap(int w) {
Bitmap bm = Bitmap.createBitmap(w, FG_HEIGHT, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bm);
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
p.setColor(FOREGROUND_COLOR);
c.drawRect(0, 0, w, FG_HEIGHT, p);
return bm;
}
private void init(Context context, AttributeSet attrs) {
if (attrs != null) {
// //
// int count = attrs.getAttributeCount();
// for (int i = 0; i < count; i++) {
// LogOut.out(this, "attrNameRes:" +
// Integer.toHexString(attrs.getAttributeNameResource(i))//
// + " attrName:" + attrs.getAttributeName(i)//
// + " attrResValue:" + attrs.getAttributeResourceValue(i, -1)//
// + " attrValue:" + attrs.getAttributeValue(i)//
// );
// }
// //
TypedArray typedArr = context.obtainStyledAttributes(attrs, R.styleable.PorterDuffView);
porterduffMode = typedArr.getBoolean(R.styleable.PorterDuffView_porterduffMode, false);
}
Drawable drawable = getDrawable();
if (porterduffMode && drawable != null && drawable instanceof BitmapDrawable) {
bitmapBg = ((BitmapDrawable) drawable).getBitmap();
width = bitmapBg.getWidth();
height = bitmapBg.getHeight();
// LogOut.out(this, "width=" + width + " height=" + height);
bitmapFg = createForegroundBitmap(width);
} else {
// 不符合要求,自动设置为false。
porterduffMode = false;
}
paint = new Paint();
paint.setFilterBitmap(false);
paint.setAntiAlias(true);
paint.setTextSize(FONT_SIZE);
// 关于FontMetrics的详情介绍,可见:
// <a href="\"http://xxxxxfsadf.iteye.com/blog/480454\"" target="\"_blank\"">http://xxxxxfsadf.iteye.com/blog/480454</a>
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
// 注意观察本输出:
// ascent:单个字符基线以上的推荐间距,为负数
Log.i(TAG, "ascent:" + fontMetrics.ascent//
// descent:单个字符基线以下的推荐间距,为正数
+ " descent:" + fontMetrics.descent //
// 单个字符基线以上的最大间距,为负数
+ " top:" + fontMetrics.top //
// 单个字符基线以下的最大间距,为正数
+ " bottom:" + fontMetrics.bottom//
// 文本行与行之间的推荐间距
+ " leading:" + fontMetrics.leading);
// 在此处直接计算出来,避免了在onDraw()处的重复计算
txtBaseY = (height - fontMetrics.bottom - fontMetrics.top) / 2;
decFormat = new DecimalFormat("0.0%");
}
public void onDraw(Canvas canvas) {
if (porterduffMode) {
int tmpW = (getWidth() - width) / 2, tmpH = (getHeight() - height) / 2;
// 画出背景图
canvas.drawBitmap(bitmapBg, tmpW, tmpH, paint);
// 设置PorterDuff模式
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
// canvas.drawBitmap(bitmapFg, tmpW, tmpH - progress * height,
// paint);
int tH = height - (int) (progress * height);
for (int i = 0; i < tH; i++) {
canvas.drawBitmap(bitmapFg, tmpW, tmpH + i, paint);
}
// 立即取消xfermode
paint.setXfermode(null);
int oriColor = paint.getColor();
paint.setColor(TEXT_COLOR);
paint.setTextSize(FONT_SIZE);
String tmp = decFormat.format(progress);
float tmpWidth = paint.measureText(tmp);
canvas.drawText(decFormat.format(progress), tmpW + (width - tmpWidth) / 2, tmpH + txtBaseY, paint);
// 恢复为初始值时的颜色
paint.setColor(oriColor);
} else {
Log.i(TAG, "onDraw super");
super.onDraw(canvas);
}
}
public void setProgress(float progress) {
if (porterduffMode) {
this.progress = progress;
// 刷新自身。
invalidate();
}
}
public void setBitmap(Bitmap bg) {
if (porterduffMode) {
bitmapBg = bg;
width = bitmapBg.getWidth();
height = bitmapBg.getHeight();
bitmapFg = createForegroundBitmap(width);
Paint.FontMetrics fontMetrics = paint.getFontMetrics();
txtBaseY = (height - fontMetrics.bottom - fontMetrics.top) / 2;
setImageBitmap(bg);
// 请求重新布局,将会再次调用onMeasure()
// requestLayout();
}
}
public boolean isLoading() {
return loading;
}
public void setLoading(boolean loading) {
this.loading = loading;
}
public void setPorterDuffMode(boolean bool) {
porterduffMode = bool;
}
}
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:porterduff="http://schemas.android.com/apk/res/com.android.activity"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="点击loading开始下载..." />
<com.android.activity.PorterDuffView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pViewA"
android:src="@drawable/weibo1"
android:layout_gravity="center"
porterduff:porterduffMode="true"
/>
<com.android.activity.PorterDuffView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pViewB"
android:src="@drawable/weibo1"
android:layout_gravity="center"
porterduff:porterduffMode="true"
/>
<com.android.activity.PorterDuffView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pViewC"
android:src="@drawable/weibo1"
android:layout_gravity="center"
porterduff:porterduffMode="true"
/>
<com.android.activity.PorterDuffView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/pViewD"
android:src="@drawable/weibo1"
android:layout_gravity="center"
porterduff:porterduffMode="true"
>
</com.android.activity.PorterDuffView>
</LinearLayout>
</ScrollView>
</LinearLayout>

attrs.xml

<?xml version="1.0" encoding="UTF-8"?>
<resources>
<!--请参阅
[android_sdk]\platforms\android-n\data\res\values\attrs.xml
-->
<declare-styleable name="PorterDuffView">
<attr name="porterduffMode" format="boolean"></attr>
</declare-styleable>
</resources>

http://download.csdn.net/detail/fuweiping/4742079

仿新浪微博的图片加载相关推荐

  1. ASP.NET仿新浪微博下拉加载更多数据瀑布流效果

    闲来无事,琢磨着写点东西.貌似页面下拉加载数据,瀑布流的效果很火,各个网站都能见到各式各样的展示效果,原理大同小异.于是乎,决定自己写一写这个效果,希望能给比我还菜的菜鸟们一点参考价值.       ...

  2. html实现图片加载动画效果,HTML5+javascript实现图片加载进度动画效果

    在网上找资料的时候,看到网上有图片加载进度的效果,手痒就自己也写了一个. 图片加载完后,隐藏loading效果. 想看加载效果,请ctrel+F5强制刷新或者清理缓存. 效果预览: 0% 代码如下: ...

  3. 仿新浪微博图片加载进度条——JLPieProgressView

    2019独角兽企业重金招聘Python工程师标准>>> JLPieProgressView 仿新浪微博图片加载进度条 实现代码如下: #import "JLPieProgr ...

  4. Android笔记之(图片高斯+Glide实现微信图片加载策略+仿微信进度条)

    很久以前就想自己实现一下仿微信图片加载的那种策略了,先加载一张模糊的图片,然后再加载清晰大图,今天研究了一下,不过要是Glide支持进度条显示就好了,不得不说Glide很强大, 不啰嗦了,直接上代码了 ...

  5. Android LruCache和DiskLruCache相结合打造图片加载框架(仿微信图片选择,照片墙)

    LrcCache和DiskLruCache相结合打造图片加载框架 转载请标明出处:http://blog.csdn.net/luoshishou/article/details/51299169 源码 ...

  6. 圆形进度条(包括仿QQ图片加载进度图)

    原文:圆形进度条(包括仿QQ图片加载进度图) 源代码下载地址:http://www.zuidaima.com/share/1581277496822784.htm 以前找到的自定义圆形进度条

  7. Android 自定义本地图片加载库,仿微信相册

    总结一下微信的本地图片加载有以下几个特点,也是提高用户体验的关键点 1.缩略图挨个加载,一个一个加载完毕,直到屏幕所有缩略图都加载完成 2.不等当前屏的所有缩略图加载完,迅速向下滑,滑动停止时立即加载 ...

  8. Android 高仿ImageLoader图片加载

    一.首先,废话不多说,先上图片 二.实现思路 1.缓存在本地和内存中,每次加载都从本地中读取,如果本地没有则从网络下载,并保存到本地或者内存 2.内存缓存使用软引用和LruCache算法 3.本地缓存 ...

  9. Android 框架练成 教你打造高效的图片加载框架

    转载请标明出处: http://blog.csdn.net/lmj623565791/article/details/41874561 ,本文出自: [张鸿洋的博客] 1.概述 优秀的图片加载框架不要 ...

最新文章

  1. AcWing 2983. 玩具 / POJ 2318.toys(计算几何基础、二分、判断点和直线的位置关系)
  2. php制作本地程序,PHP安装程序制作
  3. 以二进制的形式查看文件 Linux之od命令详解
  4. 【正一专栏】评深圳西乡砍人案——不要无辜的底层伤害
  5. 2.3.11 管程
  6. 【收藏】在 Linux 上以 All-in-One 模式安装 KubeSphere
  7. python监听键盘库_python监听、操作键盘鼠标库pynput详细教程|python基础教程|python入门|python教程...
  8. WCF与AJAX编程开发实践(1):AJAX基础概念和纯AJAX示例
  9. 显示收货地址页面html,收货地址.html
  10. Facebook 发布 PyTorch Hub:一行代码实现经典模型调用!
  11. Letter Combinations of a Phone Number
  12. 实现自己的控制层do-c (仿Struts2和SpringMVC)(六)
  13. 【金九银十】java数据结构和算法第二版
  14. 考试酷c语言程序设计的答案大全,C语言程序设计考试试卷07级A.doc
  15. 苹果手机又刷屏啦!!它是如何做到的?
  16. ftp 报错 227 Entering Passive Mode (192,168,169,141,213,232)
  17. 手机端rem布局详解(淘宝无限适配)
  18. mysql的时间最晚日期_MySQL日期时间函数
  19. 火狐浏览器无法载入配置文件
  20. HDS不玩了,高端存储还能玩多久?

热门文章

  1. Spring连接Mysql报Caused by: com.mysql.cj.exceptions.CJCommunicationsException: Communications link fai错
  2. java游戏循环_利用Java循环语句实现攻击防御塔小游戏
  3. 游戏伤害计算机,阴阳师:输出和防御之间的各种计算,看完就能明白游戏的伤害机制...
  4. 关于Socket类型中SOCK_STREAM和SOCK_DGRAM区别
  5. 创建MFC项目,资源视图加载失败
  6. Android开发中的水波纹效果实现
  7. 计算机网络毕业设计关于flash,《电大计算机网络毕业论文FLASH爱好者网站;的网页设计与制作》.doc...
  8. 易于学习的.NET 6.0和Angular——Angular模板入门——第1部分
  9. xv6---Lab3: page tables
  10. 与matlab有关的课程设计,MATLAB课程设计