[英]Android Custom ListView Using Image from URL
我一直在嘗試讓ListView填充適配器已知的來自網站URL的圖像。 該活動會誇大每個圖像,但是我的模擬器甚至無法啟動,只會顯示黑色。 我在整個代碼中搜索都沒有結果,並且嘗試了很多事情,但是不幸的是,我現在陷入了困境。 第一類是我的適配器類,它為每個索引提供一個視圖。第二類是我的活動類,它加載視圖。 第三類是助手類。
還有兩個布局XML文件和一個XML清單
GalleryAdapter.java
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import com.example.imageshow.R;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
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.TextView;
public class GalleryAdapter extends ArrayAdapter<JSONObject>{
DrawableManager dM = new DrawableManager();
Server s = new Server();
Context ctx;
LayoutInflater myInflater = (LayoutInflater) ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
public GalleryAdapter(Context context, int resource) {
super(context, resource);
ctx = context;
// TODO Auto-generated constructor stub
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// TODO Auto-generated method stub
if (convertView==null){
convertView = myInflater.inflate(R.layout.gallery_item, parent, true);
}
TextView name = (TextView) convertView.findViewById(R.id.name);
name.setText(s.galleryObjects.get(position).getName());
TextView eventDate = (TextView) convertView.findViewById(R.id.eventDate);
eventDate.setText(s.galleryObjects.get(position).getEventDate());
ImageView image = (ImageView) convertView.findViewById(R.id.image);
String imageUrl = s.galleryObjects.get(position).getImageURL();
//which one works??
//1
image.setImageDrawable(dM.fetchDrawable(imageUrl));
//2
try {
image = (ImageView) convertView.findViewById(R.id.image);
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(imageUrl).getContent());
image.setImageBitmap(bitmap);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//3
//new DownloadImageTask(image).execute(s.galleryObjects.get(position).getImageURL());
return convertView;
}
public static Bitmap getBitmapFromURL(String src) {
try {
Log.e("src",src);
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
Log.e("Bitmap","returned");
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
Log.e("Exception",e.getMessage());
return null;
}
}
class DownloadImageTask extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(result);
}
}
}
GalleryActivity.java
import com.example.imageshow.R;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.widget.ListView;
public class GalleryActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
GalleryAdapter p = new GalleryAdapter(this,0);
setContentView(R.layout.galleries);
ListView l = (ListView) findViewById(R.id.galleryList);
ImageView moreButton = (ImageView) findViewById(R.id.moreButton);
ImageView cameraButton = (ImageView) findViewById(R.id.cameraButton);
moreButton.setOnClickListener(new MoreButtonListener());
cameraButton.setOnClickListener(new CameraButtonListener());
l.setAdapter(p);
setVisible(true);
}
public class MoreButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
public class CameraButtonListener implements OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
}
DrawableManager.Java
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.util.HashMap;
import java.util.Map;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;
public class DrawableManager {
private final Map<String, Drawable> drawableMap;
public DrawableManager() {
drawableMap = new HashMap<String, Drawable>();
}
public Drawable fetchDrawable(String urlString) {
if (drawableMap.containsKey(urlString)) {
return drawableMap.get(urlString);
}
try {
InputStream is = fetch(urlString);
Drawable drawable = Drawable.createFromStream(is, "src");
if (drawable != null) {
drawableMap.put(urlString, drawable);
Log.d(this.getClass().getSimpleName(), "got a thumbnail drawable: " + drawable.getBounds() + ", "
+ drawable.getIntrinsicHeight() + "," + drawable.getIntrinsicWidth() + ", "
+ drawable.getMinimumHeight() + "," + drawable.getMinimumWidth());
} else {
Log.w(this.getClass().getSimpleName(), "could not get thumbnail");
}
return drawable;
} catch (MalformedURLException e) {
Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
return null;
} catch (IOException e) {
Log.e(this.getClass().getSimpleName(), "fetchDrawable failed", e);
return null;
}
}
public void fetchDrawableOnThread(final String urlString, final ImageView imageView) {
if (drawableMap.containsKey(urlString)) {
imageView.setImageDrawable(drawableMap.get(urlString));
}
final Handler handler = new Handler() {
@Override
public void handleMessage(Message message) {
imageView.setImageDrawable((Drawable) message.obj);
}
};
Thread thread = new Thread() {
@Override
public void run() {
//TODO : set imageView to a "pending" image
Drawable drawable = fetchDrawable(urlString);
Message message = handler.obtainMessage(1, drawable);
handler.sendMessage(message);
}
};
thread.start();
}
private InputStream fetch(String urlString) throws MalformedURLException, IOException {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet(urlString);
HttpResponse response = httpClient.execute(request);
return response.getEntity().getContent();
}
}
布局文件
<?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" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#fbfbfb" >
<ImageView
android:id = "@+id/cameraButton"
android:layout_height="wrap_content"
android:layout_width = "wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:clickable = "true"
android:adjustViewBounds="true"
android:padding="10dp"
android:maxHeight="400dp"
android:src="@drawable/ic_launcher"
android:background="#b9b9b9">
</ImageView>
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:clickable="false"
android:maxHeight="400dp"
android:text="SPORTSPHOTOS.com"
android:textColor="#123123" >
</TextView>
<ImageView
android:id = "@+id/moreButton"
android:layout_height="wrap_content"
android:layout_width = "wrap_content"
android:layout_alignParentRight="true"
android:adjustViewBounds="true"
android:clickable="true"
android:padding="10dp"
android:maxHeight="60dp"
android:layout_centerVertical="true"
android:src="@drawable/more"
>
</ImageView>
</RelativeLayout>
<ScrollView
android:layout_width = "fill_parent"
android:layout_height="fill_parent">
<ListView
android:id="@+id/galleryList"
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
</ListView>
</ScrollView>
</LinearLayout>
</LinearLayout>
布局文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
android:layout_width = "match_parent"
android:layout_height = "wrap_content"
android:padding="20dp"
android:orientation="vertical"
>
<TextView
android:id="@+id/name"
android:text="Great Wall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp">
</TextView>
<TextView
android:id="@+id/eventDate"
android:text="08-15-2014"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="2dp">
</TextView>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:adjustViewBounds="true"
android:maxHeight="200dp"
android:padding="10dp">
</ImageView>
</LinearLayout>
</LinearLayout>
</RelativeLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.imageshow"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="18"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.SECOND" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name=".GalleryActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
我認為所有解決方案都不會起作用。 確保通過http加載圖像在后台(不是解決方案2)。 在列表視圖內的后台加載圖像的主要問題是視圖回收( ListView的回收機制如何工作 )。 重用視圖時,不應將要加載的圖像設置為初始imageView。 當您的視圖被回收時,應該在imageView中加載另一個圖像。 因此,請跟蹤imageView和url之間的關系。 (例如,將url放在imageView.setTag(url)中)在將圖像設置為imageView之前,請檢查imageView.getTag()是否與您剛剛加載的url相匹配。
但是,為了使其更容易一點,我始終使用AndroidQuery。 從網絡異步加載映像僅需要兩行:
//load an image to an ImageView from network, cache image to file and memory
AQuery aq = new AQuery(convertView);
aq.id(R.id.image).image("http://www.vikispot.com/z/images/vikispot/android-w.png");
有關更多選項,請參見https://code.google.com/p/android-query/wiki/ImageLoading 。 (例如緩存等)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.