先把xml上上... main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<ListView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/lv_list"
></ListView>
</LinearLayout>
item.xml<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:orientation="horizontal"
android:layout_height="wrap_content">
<ImageView android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:layout_weight="7"
android:paddingLeft="10px"
/>
<TextView android:id="@+id/text"
android:layout_width="wrap_content"
android:textSize="16sp"
android:textStyle="bold|italic"
android:gravity="right"
android:layout_weight="3"
android:layout_height="wrap_content"/>
</LinearLayout>
package com.wangs.demo;
/** 获取的对象 **/
public class ImageAndText {
private String imageUrl;
private String text;
public ImageAndText(String imageUrl, String text) {
this.imageUrl = imageUrl;
this.text = text;
}
public String getImageUrl() {
return imageUrl;
}
public String getText() {
return text;
}
}
package com.wangs.demo;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
*
*UI布局要用到的view
*/
public class ViewCache {
private View baseView; //需要孵化的listview
private TextView textView;
private ImageView imageView;
public ViewCache(View baseView) {
this.baseView = baseView;
}
public TextView getTextView() {
if (textView == null) {
textView = (TextView) baseView.findViewById(R.id.text);
}
return textView;
}
public ImageView getImageView() {
if (imageView == null) {
imageView = (ImageView) baseView.findViewById(R.id.image);
}
return imageView;
}
}
package com.wangs.demo;
/** 获取的对象 **/
public class ImageAndText {
private String imageUrl;
private String text;
public ImageAndText(String imageUrl, String text) {
this.imageUrl = imageUrl;
this.text = text;
}
public String getImageUrl() {
return imageUrl;
}
public String getText() {
return text;
}
}package com.wangs.demo;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
/**
*
*UI布局要用到的view
*/
public class ViewCache {
private View baseView; //需要孵化的listview
private TextView textView;
private ImageView imageView;
public ViewCache(View baseView) {
this.baseView = baseView;
}
public TextView getTextView() {
if (textView == null) {
textView = (TextView) baseView.findViewById(R.id.text);
}
return textView;
}
public ImageView getImageView() {
if (imageView == null) {
imageView = (ImageView) baseView.findViewById(R.id.image);
}
return imageView;
}
}异步加载图片,保存到map
package com.wangs.demo;
import java.io.IOException;
import java.io.InputStream;
import java.lang.ref.SoftReference;
import java.net.URL;
import java.text.Collator;
import java.util.HashMap;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
/**
* 异步加载图片
*
*/
public class AsyncImageLoader {
private HashMap<String, SoftReference<Drawable>> imageCache;
public AsyncImageLoader() {
imageCache = new HashMap<String, SoftReference<Drawable>>();
}
public Drawable loadDrawable(final String imageUrl,
final ImageCallback imageCallback) {
if (imageCache.containsKey(imageUrl)) {
SoftReference<Drawable> softReference = imageCache.get(imageUrl); //软引用释放内存
Drawable drawable = softReference.get(); //软引用取出图片
if (drawable != null) {
return drawable; //返回
}
}
/**
* 后2步是开启新线程异步用handler发送drawable对象 (用来保存到hashmap)
*/
final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
imageCallback.imageLoaded((Drawable) message.obj, imageUrl);
}
};
new Thread() {
@Override
public void run() {
Drawable drawable = loadImageFromUrl(imageUrl); //加载图片
imageCache.put(imageUrl, new SoftReference<Drawable>(drawable)); //把图片的弱引用路径放入hashmap
Message message = handler.obtainMessage(0, drawable);
handler.sendMessage(message);
}
}.start();
return null;
}
public static Drawable loadImageFromUrl(String url) {
InputStream inputStream;
try {
inputStream = new URL(url).openStream();
} catch (IOException e) {
throw new RuntimeException(e);
}
return Drawable.createFromStream(inputStream, "src");
}
public interface ImageCallback {
public void imageLoaded(Drawable imageDrawable, String imageUrl);
}
}listview适配器
package com.wangs.demo;
import java.util.List;
import com.wangs.demo.AsyncImageLoader.ImageCallback;
import android.app.Activity;
import android.graphics.drawable.Drawable;
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;
/* 适配器,接收3个参数*/
public class ImageAndTextListAdapter extends ArrayAdapter<ImageAndText> {
private ListView listView;
private AsyncImageLoader asyncImageLoader;
public ImageAndTextListAdapter(Activity activity, List<ImageAndText> imageAndTexts, ListView listView) {
super(activity, 0, imageAndTexts);
this.listView = listView;
asyncImageLoader = new AsyncImageLoader();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Activity activity = (Activity) getContext();
// Inflate the views from XML
View rowView = convertView;
ViewCache viewCache;
if (rowView == null) {
LayoutInflater inflater = activity.getLayoutInflater();
rowView = inflater.inflate(R.layout.image_and_text_row, null);
viewCache = new ViewCache(rowView); //孵化出布局内容
rowView.setTag(viewCache); //设置布局缓存对象标记 ,,这个方法很重要
System.out.println("new rowview");
} else {
viewCache = (ViewCache) rowView.getTag(); //布局有了就直接获取
System.out.println("no new rowview"); //第一次创建后,都是从这边取的
}
ImageAndText imageAndText = getItem(position); //每一个item就是一个imageandtext对象
// Load the image and set it on the ImageView 加载图片和设置
String imageUrl = imageAndText.getImageUrl();
ImageView imageView = viewCache.getImageView();
imageView.setTag(imageUrl);
Drawable cachedImage = asyncImageLoader.loadDrawable(imageUrl, new ImageCallback() {
public void imageLoaded(Drawable imageDrawable, String imageUrl) { //实现自定义的回调函数
ImageView imageViewByTag = (ImageView) listView.findViewWithTag(imageUrl);
if (imageViewByTag != null) {
imageViewByTag.setImageDrawable(imageDrawable);
}
}
});
imageView.setImageDrawable(cachedImage);//设置异步加载的image
// Set the text on the TextView //通过布局UI得到信息并设置到内容上
TextView textView = viewCache.getTextView();
textView.setText(imageAndText.getText());
return rowView;
}
}activity启动:
package com.wangs.demo;
import java.util.ArrayList;
import java.util.List;
import com.wangs.demo.AsyncImageLoader.ImageCallback;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
public class ImageListURLActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView listview = (ListView) this.findViewById(R.id.lv_list);
List<ImageAndText> imageAndTexts = new ArrayList<ImageAndText>();
ImageAndText it = new ImageAndText("http://www.169pp.com/files/images/20773.jpg", "漫画妹妹");
ImageAndText it2 = new ImageAndText("http://www.169pp.com/files/images/26580.jpg", "大波妹妹");
ImageAndText it3 = new ImageAndText("http://www.169pp.com/files/images/28048.jpg", "大波妹妹");
imageAndTexts.add(it);
imageAndTexts.add(it2);
imageAndTexts.add(it3);
for(int i=0;i<100;i++){ //测试正常,但如果url图片太大了会造成内存溢出
ImageAndText it4= new ImageAndText("http://www.169pp.com/files/images/28048.jpg", "大波妹妹");
imageAndTexts.add(it4);
}
ImageAndTextListAdapter adapter = new ImageAndTextListAdapter(this, imageAndTexts, listview);
listview.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}修改: loadimage方法,2.2提供的微缩图的类的静态方法
public static Bitmap loadImageFromUrl(String url) {
InputStream inputStream;
try {
inputStream = new URL(url).openStream();
Bitmap b = BitmapFactory.decodeStream(inputStream);
return ThumbnailUtils.extractThumbnail(b, 40, 40);
} catch (IOException e) {
throw new RuntimeException(e);
}
//return Drawable.createFromStream(inputStream, "src");
}

-------------------------------------------------------------------------------scroll---------------
public class MainActivity extends Activity {
ListView listView;
private ArrayAdapter<String> adapter;
List<String> data = new ArrayList<String>();
View loadingView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// data = PersonService.getNames(0, 20);
loadingView = getLayoutInflater().inflate(R.layout.loading, null);
adapter = new ArrayAdapter<String>(this, R.layout.list_item,
R.id.name, data);
listView = (ListView) this.findViewById(R.id.listView);
listView.setOnScrollListener(new ScrollListener());
// listView.addFooterView(loadingView);
listView.setAdapter(adapter);
}
int nextpage = 1;
int currentpage = 0;
private final class ScrollListener implements OnScrollListener{
private int number = 20;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.i("Test", "onScrollStateChanged(scrollState="+ scrollState + ")");
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.i("Test", "onScroll(firstVisibleItem="+ firstVisibleItem+
"visibleItemCount="+visibleItemCount+ "totalItemCount="+totalItemCount + ")");
//listView.getLastVisiblePosition()
if(firstVisibleItem + visibleItemCount == totalItemCount){//下一页
if(totalItemCount>0) nextpage = totalItemCount / number + 1;
if(currentpage!=nextpage){
listView.addFooterView(loadingView);//显示数据正在加载
//开线程{得到数据,然后发送消息}
handler.sendMessageDelayed(handler.obtainMessage(1, totalItemCount), 3000);
currentpage = nextpage;
}
}
}
}
Handler handler = new Handler(){
public void handleMessage(Message msg) {
data.addAll(PersonService.getNames((Integer)msg.obj, 20));
adapter.notifyDataSetChanged();
listView.removeFooterView(loadingView);//当数据加载完后,删除提示
}
};
--------------------------------------------------------------------------------------另外一个异步加载的--------------------------
public class ImageAdapter extends BaseAdapter {
private List<String> data;//存放图片路径
private int sourceid;
private LayoutInflater layoutInflater;
File saveDir;
public ImageAdapter(List<String> data, Context context, int sourceid) {
this.data = data;
this.sourceid = sourceid;
layoutInflater = LayoutInflater.from(context);
saveDir = new File(Environment.getExternalStorageDirectory(),"cache");
if(!saveDir.exists()) saveDir.mkdirs();
}
@Override
public int getCount() {
return data.size();
}
@Override
public Object getItem(int position) {
return data.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageView imageView;
if(convertView == null){
convertView = layoutInflater.inflate(sourceid, null);
imageView = (ImageView) convertView.findViewById(R.id.imageView);
convertView.setTag(imageView);
}else{
imageView = (ImageView) convertView.getTag();
}
showImage2(imageView, data.get(position));
return convertView;
}
/*
private void showImage(final ImageView imageView, final String imagepath) {
final Handler handler = new Handler(){
public void handleMessage(Message msg) {
imageView.setImageURI((Uri) msg.obj);//显示照片
}
};
Runnable loadImageTask = new Runnable() {
public void run() {
try {
Uri uri = ImageService.getImage(imagepath, saveDir);
handler.sendMessage(handler.obtainMessage(1, uri));
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(loadImageTask).start();
}
*/
private void showImage2(ImageView imageView, String path) {
LoadImageTask task = new LoadImageTask();
task.execute(imageView, path);//参数传给了doInBackground()
}
private final class LoadImageTask extends AsyncTask<Object, Integer, Uri>{
ImageView imageView;
String imagepath;
@Override
protected Uri doInBackground(Object... params) {//耗时操作,运行在子线程
imageView = (ImageView) params[0];
imagepath = (String) params[1];
try {
return ImageService.getImage(imagepath, saveDir);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Uri result) {//doInBackground()的结果传入该方法,运行在UI线程
imageView.setImageURI(result);//显示照片
}
}public class ImageService {
/**
* 获取图片,具有缓存功能
* @param path
* @param saveDir
* @return
* @throws Exception
*/
public static Uri getImage(String path, File saveDir) throws Exception{
String filename = MD5.getMD5(path) + path.substring(path.lastIndexOf("."));
File imageFile = new File(saveDir, filename);
if(imageFile.exists()){
return Uri.fromFile(imageFile);
}
//否则从网络获取图片
HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() == 200){
copyStream(conn.getInputStream(), new FileOutputStream(imageFile));
return Uri.fromFile(imageFile);
}
return null;
}
private static void copyStream(InputStream inputStream, OutputStream outStream) throws Exception{
byte[] buffer = new byte[1024];
int len = 0;
while((len = inputStream.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
inputStream.close();
outStream.close();
}
public static List<String> getImageInfos() throws Exception{
String path = "http://192.168.1.101/web/list.xml";
HttpURLConnection conn = (HttpURLConnection) new URL(path).openConnection();
conn.setConnectTimeout(5000);
conn.setRequestMethod("GET");
if(conn.getResponseCode() == 200){
return parseXML(conn.getInputStream());
}
return null;
}
private static List<String> parseXML(InputStream xml) throws Exception{
List<String> paths = new ArrayList<String>();
XmlPullParser pullParser = Xml.newPullParser();
pullParser.setInput(xml, "UTF-8");
int event = pullParser.getEventType();
while(event != XmlPullParser.END_DOCUMENT){
if(event == XmlPullParser.START_TAG){
if("image".equals(pullParser.getName())){
paths.add(pullParser.getAttributeValue(0));
}
}
event = pullParser.next();
}
return paths;
}public class MainActivity extends Activity {
ListView listView;
View loadingView;
List<String> data = new ArrayList<String>();
ImageAdapter adapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loadingView = getLayoutInflater().inflate(R.layout.loading, null);
listView = (ListView) this.findViewById(R.id.listView);
try {
//data = ImageService.getImageInfos(); //放在滚动的时候再加载
adapter =new ImageAdapter(data, this, R.layout.list_item);
listView.setOnScrollListener(new ScrollListener());
listView.setAdapter(adapter);
} catch (Exception e) {
Toast.makeText(this, "获取图片失败", 1).show();
e.printStackTrace();
}
}
@Override
protected void onDestroy() { //销毁的时候把缓存清空了
super.onDestroy();
File saveDir = new File(Environment.getExternalStorageDirectory(),"cache");
if(saveDir.exists()){
for(File file : saveDir.listFiles()){
file.delete();
}
}
}
//监听器
int nextpage = 1;
int currentpage = 0;
private final class ScrollListener implements OnScrollListener{
private int number = 10;
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
Log.i("Test", "onScrollStateChanged(scrollState="+ scrollState + ")");
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
Log.i("Test", "onScroll(firstVisibleItem="+ firstVisibleItem+
"visibleItemCount="+visibleItemCount+ "totalItemCount="+totalItemCount + ")");
//listView.getLastVisiblePosition()
if(firstVisibleItem + visibleItemCount == totalItemCount){//下一页
if(totalItemCount>0) nextpage = totalItemCount / number + 1;
if(currentpage!=nextpage){
listView.addFooterView(loadingView);//显示数据正在加载
//开线程{得到数据,然后发送消息}
try {
//data = ImageService.getImageInfos();
} catch (Exception e) {
e.printStackTrace();
}
handler.sendMessageDelayed(handler.obtainMessage(1, totalItemCount), 3000);
currentpage = nextpage;
}
}
}
}
Handler handler = new Handler(){
public void handleMessage(Message msg) {
try {
data.addAll(ImageService.getImageInfos()); //每次往下拖后又重新获取数据。
adapter.notifyDataSetChanged();
listView.removeFooterView(loadingView);//当数据加载完后,删除提示
} catch (Exception e) {
Toast.makeText(MainActivity.this, "获取图片失败了..", 2).show();
e.printStackTrace();
}
}
};
public class MD5 {
public static String getMD5(String content) {
try {
MessageDigest digest = MessageDigest.getInstance("MD5");
digest.update(content.getBytes());
return getHashString(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return null;
}
private static String getHashString(MessageDigest digest) {
StringBuilder builder = new StringBuilder();
for (byte b : digest.digest()) {
builder.append(Integer.toHexString((b >> 4) & 0xf));
builder.append(Integer.toHexString(b & 0xf));
}
return builder.toString();
}
本文深入探讨了Android应用开发过程中的关键技术和性能优化策略,包括使用最新开发工具、优化代码结构、提升用户体验等方面,旨在帮助开发者提高应用的运行效率和稳定性。
4253

被折叠的 条评论
为什么被折叠?



