自己定制ListView,上拉刷新和下拉刷新,加载网络图片,并且添加缓存机制。
- package com.lixu.listviewrefresh;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.Random;
- import com.lixu.listviewrefresh.Loadnetimage.OnLoadnetimageListener;
- import com.lixu.listviewrefresh.MyRefreshListview.OnRefreshListener;
- import android.annotation.SuppressLint;
- import android.app.Activity;
- import android.app.ProgressDialog;
- import android.content.Context;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- import android.os.AsyncTask;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- import android.widget.ArrayAdapter;
- import android.widget.ImageView;
- import android.widget.ListView;
- import android.widget.TextView;
- public class MainActivity extends Activity {
- private static final String KEY_IMAGE = "image_key";
- private static final String KEY_TEXT = "text_key";
- private static final String CACHE_KEY_IMAGE = "cache_image_key";
- private static final String CACHE_KEY_TEXT = "cache_text_key";
- // 原始数据
- private ArrayList<HashMap<String, Object>> data;
- // 缓存队列
- private ArrayList<HashMap<String, Object>> cache;
- private ArrayAdapter<String> mMyAdapter;
- private MyRefreshListview lv;
- private Activity activity;
- private Random random = new Random();
- // 图片网络地址
- private String[] image_urls = { "http://img0.bdstatic.com/img/image/shouye/mxh007.jpg",
- "http://f.hiphotos.baidu.com/image/h%3D360/sign=1c9a50843ec79f3d90e1e2368aa0cdbc/f636afc379310a5566becb8fb24543a982261036.jpg",
- "http://h.hiphotos.baidu.com/image/h%3D360/sign=04ef437b0b23dd543e73a16ee108b3df/50da81cb39dbb6fd9d9ada390b24ab18962b37ef.jpg",
- "http://b.hiphotos.baidu.com/image/h%3D360/sign=e91921f7c1fdfc03fa78e5bee43e87a9/8b82b9014a90f60352684b4e3b12b31bb151eddb.jpg",
- "http://g.hiphotos.baidu.com/image/h%3D360/sign=a2540bdbf21f3a2945c8d3c8a925bce3/fd039245d688d43fa9943bf77f1ed21b0ef43bf1.jpg",
- "http://p4.so.qhimg.com/bdr/_240_/t01d4c378e7c6bfbe69.jpg",
- "http://p0.so.qhimg.com/bdr/_240_/t0160872a7d33df5735.jpg",
- "http://p3.so.qhimg.com/bdr/_240_/t01473a131702c357dd.jpg" };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- activity = this;
- data = new ArrayList<HashMap<String, Object>>();
- cache = new ArrayList<HashMap<String, Object>>();
- // 添加初始数据
- for (int i = 0; i < 30; i++) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put(KEY_IMAGE, BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher));
- map.put(KEY_TEXT, i);
- data.add(map);
- }
- lv = (MyRefreshListview) findViewById(R.id.listview);
- mMyAdapter = new MyAdapter(this, -1);
- lv.setAdapter(mMyAdapter);
- lv.setOnRefreshListener(new OnRefreshListener() {
- @Override
- public void ontop() {
- // 随机加入一张图片
- adddata(image_urls[random.nextInt(8)]);
- }
- @Override
- public void onbuttom() {
- // 没有设置缓存机制
- new MyAsyncTaskBottom(image_urls[random.nextInt(8)]).execute();
- }
- });
- }
- private class MyAdapter extends ArrayAdapter<String> {
- private LayoutInflater flater;
- private Context context;
- public MyAdapter(Context context, int resource) {
- super(context, resource);
- this.context = context;
- flater = LayoutInflater.from(context);
- }
- @Override
- public int getCount() {
- return data.size();
- }
- @SuppressLint("InflateParams")
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- if (convertView == null)
- convertView = flater.inflate(R.layout.list, null);
- ImageView iv = (ImageView) convertView.findViewById(R.id.image);
- iv.setImageBitmap((Bitmap) data.get(position).get(KEY_IMAGE));
- TextView tv = (TextView) convertView.findViewById(R.id.text);
- tv.setText(position + "原始数据");
- return convertView;
- }
- }
- private class MyAsyncTaskTop extends AsyncTask {
- private ProgressDialog pd;
- @SuppressWarnings("unused")
- private String url;
- public MyAsyncTaskTop(String url) {
- this.url = url;
- }
- @Override
- protected void onPreExecute() {
- // 设置加载进度条
- pd = new ProgressDialog(activity);
- pd.setProgressStyle(pd.STYLE_HORIZONTAL);
- pd.setMessage("正在加载。。。");
- pd.show();
- }
- @Override
- protected Object doInBackground(Object... params) {
- try {
- // 回调加载网络的类Loadnetimage
- Loadnetimage mLoadnetimage = new Loadnetimage();
- mLoadnetimage.SetLoadnetimageListener(new OnLoadnetimageListener() {
- @SuppressWarnings("unchecked")
- @Override
- public void LoadnetimageListener(int count, int total) {
- publishProgress(count, total);
- }
- });
- // 获取网络图片
- Bitmap bitmap = mLoadnetimage.loadRawDataFromURL(url);
- // 每次将图片和对应的地址放入HashMap
- HashMap<String, Object> map = new HashMap<String, Object>();
- // 将新加载图片放入缓存
- map.put(CACHE_KEY_IMAGE, bitmap);
- map.put(CACHE_KEY_TEXT, url);
- cache.add(map);
- return bitmap;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- @Override
- protected void onPostExecute(Object result) {
- addtop(result);
- pd.dismiss();
- }
- // 更新进度条
- @Override
- protected void onProgressUpdate(Object... values) {
- int count = (Integer) values[0];
- int total = (Integer) values[1];
- pd.setMax(total);
- pd.setProgress(count);
- }
- }
- @SuppressWarnings("unused")
- private class MyAsyncTaskBottom extends AsyncTask {
- private ProgressDialog pd;
- private String url;
- public MyAsyncTaskBottom(String url) {
- this.url = url;
- }
- @Override
- protected void onPreExecute() {
- // 设置进度条
- pd = new ProgressDialog(activity);
- // 样式
- pd.setProgressStyle(pd.STYLE_HORIZONTAL);
- pd.setMessage("正在加载。。。");
- pd.show();
- }
- @Override
- protected Object doInBackground(Object... params) {
- // 回调加载网络的类Loadnetimage
- Loadnetimage mLoadnetimage = new Loadnetimage();
- // 获取网络图片
- Bitmap bitmap;
- try {
- bitmap = mLoadnetimage.loadRawDataFromURL(url);
- return bitmap;
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
- @Override
- protected void onPostExecute(Object result) {
- addbottom(result);
- pd.dismiss();
- }
- }
- private void adddata(String url) {
- // 设置缓存机制
- Log.e("", "开始添加");
- for (int i = 0; i < cache.size(); i++) {
- HashMap<String, Object> map = cache.get(i);
- // 判断图片地址一样则载入缓存
- if (url.equals(map.get(CACHE_KEY_TEXT))) {
- Bitmap bitmap = (Bitmap) map.get(CACHE_KEY_IMAGE);
- addtop(bitmap);
- Log.e("", "载入缓存");
- return;
- }
- }
- // 否则从网络新加载
- Log.e("", "最新加载");
- new MyAsyncTaskTop(url).execute();
- }
- private void addtop(Object result) {
- // 新加载图片放入原始数据
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put(KEY_IMAGE, result);
- map.put(KEY_TEXT, data.size() + 1);
- data.add(0, map);
- mMyAdapter.notifyDataSetChanged();
- }
- private void addbottom(Object result) {
- HashMap<String, Object> map = new HashMap<String, Object>();
- map.put(KEY_IMAGE, result);
- map.put(KEY_TEXT, data.size() + 1);
- data.add(map);
- mMyAdapter.notifyDataSetChanged();
- // 添加数据后自动滚动到底部
- lv.setSelection(ListView.FOCUS_DOWN);
- }
- }
- package com.lixu.listviewrefresh;
- import java.io.BufferedInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.InputStream;
- import java.net.HttpURLConnection;
- import java.net.URL;
- import android.graphics.Bitmap;
- import android.graphics.BitmapFactory;
- public class Loadnetimage {
- // 设置回调机制
- private OnLoadnetimageListener mOnLoadnetimageListener;
- public Loadnetimage() {
- }
- public interface OnLoadnetimageListener {
- public void LoadnetimageListener(int count, int total);
- }
- public void SetLoadnetimageListener(OnLoadnetimageListener l) {
- mOnLoadnetimageListener = l;
- }
- public Bitmap loadRawDataFromURL(String u) throws Exception {
- URL url = new URL(u);
- HttpURLConnection conn = (HttpURLConnection) url.openConnection();
- // 设置请求的一些常用的参数
- conn.setReadTimeout(30000);
- conn.setConnectTimeout(30000);
- conn.setDoInput(true);
- conn.connect();
- // 获取图片总数
- int total = conn.getContentLength();
- InputStream is = conn.getInputStream();
- BufferedInputStream bis = new BufferedInputStream(is);
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- // 缓存2KB
- final int BUFFER_SIZE = 2 * 1024;
- final int EOF = -1;
- int count = 0;
- int c;
- byte[] buf = new byte[BUFFER_SIZE];
- while (true) {
- c = bis.read(buf);
- if (c == EOF)
- break;
- // 每次累加到现在为止我们下载了多少数据,以便于后面计算已经下载的数据占了总数量的百分比
- count = count + c;
- // 发布最新的数据,更新随后的进度条显示进度使用
- if (mOnLoadnetimageListener != null)
- mOnLoadnetimageListener.LoadnetimageListener(count, total);
- baos.write(buf, 0, c);
- }
- conn.disconnect();
- is.close();
- byte[] data = baos.toByteArray();
- baos.flush();
- Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
- return bitmap;
- }
- }
- package com.lixu.listviewrefresh;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.GestureDetector;
- import android.view.MotionEvent;
- import android.view.View;
- import android.widget.AbsListView;
- import android.widget.ListView;
- public class MyRefreshListview extends ListView {
- private OnRefreshListener mOnRefreshListener;
- private Context context;
- private int firstVisibleItem, visibleItemCount, totalItemCount;
- public MyRefreshListview(Context context, AttributeSet attrs) {
- super(context, attrs);
- this.context = context;
- }
- public interface OnRefreshListener {
- public void ontop();
- public void onbuttom();
- }
- public void setOnRefreshListener(OnRefreshListener l) {
- this.mOnRefreshListener = l;
- // 这个方法可以解决当listview中初始没有数据的时候滑动来加载数据
- final GestureDetector mGestureDetector = new GestureDetector(context,
- new GestureDetector.SimpleOnGestureListener() {
- // velocityY表示触摸停止点Y到触摸起始点Y的速度值 当两点距离值为负时,速度值也为负所以:
- // >0表示从上往下拉
- // <0表示从下往上拉
- public boolean onFling(android.view.MotionEvent e1, android.view.MotionEvent e2, float velocityX,
- float velocityY) {
- if (velocityY > 0) {
- // 滑动到顶部时添加
- if (firstVisibleItem == 0) {
- mOnRefreshListener.ontop();
- }
- }
- if (velocityY < 0) {
- // 滑动到底部时添加
- if ((firstVisibleItem + visibleItemCount) == totalItemCount) {
- mOnRefreshListener.onbuttom();
- }
- }
- return super.onFling(e1, e2, velocityX, velocityY);
- };
- });
- this.setOnTouchListener(new OnTouchListener() {
- // 将触摸事件交给GestureDetector来处理
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return mGestureDetector.onTouchEvent(event);
- }
- });
- this.setOnScrollListener(new OnScrollListener() {
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- }
- @Override
- public void onScroll(AbsListView view, int fvi, int vic, int tic) {
- firstVisibleItem = fvi;
- visibleItemCount = vic;
- totalItemCount = tic;
- }
- });
- }
- }
xml文件:
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context="com.lixu.listviewrefresh.MainActivity" >
- <com.lixu.listviewrefresh.MyRefreshListview
- android:id="@+id/listview"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </RelativeLayout>
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:orientation="vertical" >
- <ImageView
- android:id="@+id/image"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- <TextView
- android:id="@+id/text"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
- </LinearLayout>
运行效果图:
自己定制ListView,上拉刷新和下拉刷新,加载网络图片,并且添加缓存机制。的更多相关文章
- XRecyclerView:实现下拉刷新、滚动到底部加载更多以及添加header功能的RecyclerView
介绍: 一个实现了下拉刷新,滚动到底部加载更多以及添加header功能的的RecyclerView.使用方式和RecyclerView完全一致,不需要额外的layout,不需要写特殊的adater. ...
- ListView(2)最简单的上拉刷新,下拉刷新
最简单的上拉刷新和下拉刷新,当listview滚动到底部时向上拉刷新数据.当listview滚动到最顶部时下拉刷新. 图1,上拉刷新 图2,下拉刷新 1,设置lisview,加载heade ...
- ListView(2)最简单的上拉刷新、下拉刷新代码
效果 最简单的上拉刷新和下拉刷新,当listview滚动到底部时向上拉刷新数据.当listview滚动到最顶部时下拉刷新. 图1,上拉刷新 图2,下拉刷新 1.设置lisview 加载he ...
- Android PullToRefreshListView上拉刷新和下拉刷新
PullToRefreshListView实现上拉和下拉刷新有两个步骤: 1.设置刷新方式 pullToRefreshView.setMode(PullToRefreshBase.Mode.BOTH) ...
- iscroll.js实现上拉刷新,下拉加载更多,应用技巧项目实战
上拉刷新,下拉加载更多...仿原生的效果----iscroll是一款做滚动效果的插件,具体介绍我就不废话,看官方文档,我只写下我项目开发的一些用到的用法: (如果不好使,调试你的css,想必是个很蛋疼 ...
- PullToRefreshGridView上拉刷新,下拉加载
PullToRefreshGridView上拉刷新,下拉加载 布局: <?xml version="1.0" encoding="utf-8"?> ...
- vux (scroller)上拉刷新、下拉加载更多
1)比较关键的地方是要在 scroller 组件上里加一个 ref 属性 <scroller :lockX=true height="-170" :pulldown-conf ...
- iOS--MJRefresh的使用 上拉刷新和下拉加载
1.一般使用MJRefresh 来实现上拉刷新和下拉加载功能 2.MJRefresh 下载地址:https://github.com/CoderMJLee/MJRefresh 3. MJRefresh ...
- 【转】vux (scroller)上拉刷新、下拉加载更多
1)比较关键的地方是要在 scroller 组件上里加一个 ref 属性 <scroller :lockX="true" height="-170" :p ...
随机推荐
- [转载] C++11中的右值引用
C++11中的右值引用 May 18, 2015 移动构造函数 C++98中的左值和右值 C++11右值引用和移动语义 强制移动语义std::move() 右值引用和右值的关系 完美转发 引用折叠推导 ...
- 半平面交模板(O(n*n)&& O(n*log(n))
摘自http://blog.csdn.net/accry/article/details/6070621 首先解决问题:什么是半平面? 顾名思义,半平面就是指平面的一半,我们知道,一条直线可以将平面分 ...
- 算法_栈的Java的通用数组实现
栈是一个常用的最简单的数据结构,这里提供了其实现.内部维护了一个数组,并且可以动态的调整数组的大小.而且,提供了迭代器支持后进先出的迭代功能.Stack的实现是所有集合类抽象数据类型实现的模板,它将所 ...
- 【Todo】【转载】深度学习&神经网络 科普及八卦 学习笔记 & GPU & SIMD
上一篇文章提到了数据挖掘.机器学习.深度学习的区别:http://www.cnblogs.com/charlesblc/p/6159355.html 深度学习具体的内容可以看这里: 参考了这篇文章:h ...
- Tomcat:IOException while loading persisted sessions: java.io.EOFException解决手记
原文:http://blog.csdn.net/lifuxiangcaohui/article/details/37659905 一直用tomcat一段时间都正常无事,最近一次启动tomcat就发生以 ...
- 遮罩、警告框/弹框 - EasyUI
1.遮罩 1.1. $.messager.progress //开启遮罩 $.messager.progress({}); 或 $.messager.progress({ title: 'Please ...
- gdb 调试学习
gdb 是unix/linux 系统下的程序调试工具,和IDE(如VS, Eclipse等)的图形化调试工具相比,gdb在断点,跟踪显示方面有着不足,但是它在某些方面比图形化调试工具更加丰富的功能. ...
- android打开,保存图片到sd卡,显示图片
1.打开根目录下test.jpg Bitmap bm = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory().getA ...
- python网络编程socket之多线程
#coding:utf-8 __author__ = 'similarface' import os,socket,threading,SocketServer SERVER_HOST='localh ...
- VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写
本文转自 http://vistaswx.com/blog/article/category/tutorial/page/2 VB6 GDI+ 入门教程[9] Bitmap魔法(2):数据读写 200 ...