我正在尝试获取JSON数据并使用ArrayAdapter在我的ListView中显示它。无论如何,在我的适配器中,我正在使用来自https://github.com/nostra13/Android-Universal-Image-Loader的通用图像加载器,除了图像之外,其他数据都已正确加载。一些图像显示正确,一些图像不应该在特定项目上,有些图像没有完全加载。
这是我的调用片段:
public class SampleFragment extends Fragment implements
OnItemClickListener {
private ListView songsListView;
private ArrayList<String> list;
private ArrayAdapter<String> dataAdapter;
private View rootView;
private Button selectReferenceSong;
private Fragment memberFragment;
private String[] songsArray;
private ArrayAdapter<String> arrayAdapter;
private ArrayList<ReferenceTracks> arrayOfList;
private String bufferString;
private static final String rssFeed = "https://dl.dropboxusercontent.com/u/32769459/reference_tracks.json";
private static final String TAG_MUSIC = "music";
private static final String TAG_SONG = "song";
private static final String TAG_TITLE = "title";
private static final String TAG_ARTIST = "artist";
private static final String TAG_DURATION = "duration";
private static final String TAG_THUMBURL = "thumb_url";
public SampleFragment() {
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
rootView = inflater.inflate(R.layout.sample_layout, container, false);
songsListView = (ListView) rootView.findViewById(R.id.songsListView);
songsListView.setOnItemClickListener(this);
arrayOfList = new ArrayList<ReferenceTracks>();
if (Utility.isNetworkAvailable(getActivity())) {
new AsynchronousTask().execute(rssFeed);
} else {
Toast.makeText(getActivity().getApplicationContext(),
"No Network Connection!", Toast.LENGTH_SHORT).show();
}
return rootView;
}
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
// TODO Auto-generated method stub
}
/**
*
* @Asynchronous class
*/
public class AsynchronousTask extends AsyncTask<String, Void, String> {
ProgressDialog pDialog;
private RowAdapter objRowAdapter;
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(getActivity());
pDialog.setMessage("Loading...");
pDialog.setCancelable(false);
pDialog.show();
}
@Override
protected String doInBackground(String... params) {
Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
return Utility.getJSONString(params[0]);
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
if (null != pDialog && pDialog.isShowing()) {
pDialog.dismiss();
}
if (null == result || result.length() == 0) {
Toast.makeText(getActivity().getApplicationContext(),
"No data found from web.", Toast.LENGTH_SHORT).show();
} else {
try {
JSONObject topObject = new JSONObject(result);
JSONObject musicObject = topObject.getJSONObject(TAG_MUSIC);
JSONArray jsonArray = musicObject.getJSONArray(TAG_SONG);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject objJson = jsonArray.getJSONObject(i);
ReferenceTracks objItem = new ReferenceTracks();
objItem.setTitle(objJson.getString(TAG_TITLE));
objItem.setArtist(objJson.getString(TAG_ARTIST));
objItem.setDuration(objJson.getString(TAG_DURATION));
objItem.setThumbUrl(objJson.getString(TAG_THUMBURL));
arrayOfList.add(objItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
setAdapterToListview();
}
}
public void setAdapterToListview() {
objRowAdapter = new RowAdapter(getActivity(), R.layout.reference_song_list_item, arrayOfList);
songsListView.setAdapter(objRowAdapter);
}
}}
这是我的自定义适配器:
public class RowAdapter extends ArrayAdapter<ReferenceTracks> {
private Context activity;
private ArrayList<ReferenceTracks> items;
private ReferenceTracks objBean;
private int row;
private ImageLoader imageLoader;
private DisplayImageOptions options;
public RowAdapter(Context act, int resource, ArrayList<ReferenceTracks> arrayList) {
super(act, resource, arrayList);
this.activity = act;
this.row = resource;
this.items = arrayList;
imageLoader = ImageLoader.getInstance();
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
View view = convertView;
ViewHolder holder;
if (view == null) {
LayoutInflater inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(row, null);
holder = new ViewHolder();
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
if ((items == null) || ((position + 1) > items.size()))
return view;
objBean = items.get(position);
holder.tvImage = (ImageView) view.findViewById(R.id.list_image);
holder.tvTitle = (TextView) view.findViewById(R.id.title);
holder.tvArtist = (TextView) view.findViewById(R.id.artist);
holder.tvDuration = (TextView) view.findViewById(R.id.duration);
holder.pbar = (ProgressBar) view.findViewById(R.id.progressbar);
if (holder.tvImage != null) {
if (null != objBean.getThumbUrl()
&& objBean.getThumbUrl().trim().length() > 0) {
final ProgressBar pbar = holder.pbar;
imageLoader.destroy();
imageLoader.init(ImageLoaderConfiguration.createDefault(activity));
imageLoader.displayImage(objBean.getThumbUrl(), holder.tvImage,
options, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri,
View view) {
// TODO Auto-generated method stub
pbar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri,
View view, FailReason failReason) {
// TODO Auto-generated method stub
pbar.setVisibility(View.INVISIBLE);
}
@Override
public void onLoadingComplete(String imageUri,
View view, Bitmap loadedImage) {
// TODO Auto-generated method stub
pbar.setVisibility(View.INVISIBLE);
}
@Override
public void onLoadingCancelled(String imageUri,
View view) {
// TODO Auto-generated method stub
}
});
} else {
holder.tvImage.setImageResource(R.drawable.ic_launcher);
}
}
if (holder.tvTitle != null && null != objBean.getTitle()
&& objBean.getTitle().trim().length() > 0) {
holder.tvTitle.setText(Html.fromHtml(objBean.getTitle()));
}
if (holder.tvArtist != null && null != objBean.getArtist()
&& objBean.getArtist().trim().length() > 0) {
holder.tvArtist.setText(Html.fromHtml(objBean.getArtist()));
}
if (holder.tvDuration != null && null != objBean.getDuration()
&& objBean.getDuration().trim().length() > 0) {
holder.tvDuration.setText(Html.fromHtml(objBean.getDuration()));
}
return view;
}
public class ViewHolder {
public ImageView tvImage;
public ProgressBar pbar;
public TextView tvTitle, tvArtist, tvDuration;
}}
虽然这是我的应用程序类:
public class SampleApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
DisplayImageOptions displayimageOptions = new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_stub)
.showImageOnFail(R.drawable.ic_error)
.showImageForEmptyUri(R.drawable.ic_empty)
.cacheInMemory()
.cacheOnDisc()
.bitmapConfig(Bitmap.Config.RGB_565)
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.build();
File cacheDir = StorageUtils.getCacheDirectory(getApplicationContext());
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(getApplicationContext())
.threadPoolSize(4)
.threadPriority(Thread.NORM_PRIORITY)
.tasksProcessingOrder(QueueProcessingType.LIFO)
.defaultDisplayImageOptions(displayimageOptions)
.discCacheSize(50 * 1024 * 1024)
.discCacheFileCount(1000000)
.memoryCache(new WeakMemoryCache())
.build();
ImageLoader.getInstance().init(config);
}}
这也是日志:
06-24 11:18:12.935: E/ImageLoader(6428): null
06-24 11:18:12.935: E/ImageLoader(6428): java.io.EOFException
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.io.Streams.readAsciiLine(Streams.java:203)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpEngine.readResponseHeaders(HttpEngine.java:561)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpEngine.readResponse(HttpEngine.java:801)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:274)
06-24 11:18:12.935: E/ImageLoader(6428): at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromNetwork(BaseImageDownloader.java:113)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:84)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.getImageStream(BaseImageDecoder.java:84)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.decode.BaseImageDecoder.decode(BaseImageDecoder.java:73)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.decodeImage(LoadAndDisplayImageTask.java:290)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:250)
06-24 11:18:12.935: E/ImageLoader(6428): at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:131)
06-24 11:18:12.935: E/ImageLoader(6428): at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076)
06-24 11:18:12.935: E/ImageLoader(6428): at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569)
06-24 11:18:12.935: E/ImageLoader(6428): at java.lang.Thread.run(Thread.java:856)
我的应用程序类中是否有任何错误或遗漏的设置?我一直在寻找相同的例外,但似乎没有接近修复。任何帮助都可以。非常感谢!
答案 0 :(得分:3)
我正在使用Universal图像加载器很长一段时间。所以,我更喜欢将它设置在一个类中,然后我的应用程序能够简单地访问它。
这是通用图像加载器的设置类。我有一个实用程序包,这个类在这个包下面。您可以通过在onLoadingComplete()中注释掉行来制作图像曲线的角。
public class ImageDownloader {
private static final String TAG = "ImageDownloader";
public static final String DIRECTORY_NAME = "YOUR_DIRECTORY_NAME";
private static ImageDownloader instance = null;
private ImageLoader imageLoader;
protected ImageDownloader(Context context) {
// Exists only to defeat instantiation.
configImageDownloader(context);
}
public static ImageDownloader getInstance(Context context) {
if(instance == null) {
instance = new ImageDownloader(context);
}
return instance;
}
/**
* This constructor will configure loader object in order to display image.
* @param context
*/
private void configImageDownloader(Context context) {
File cacheDir = StorageUtils.getOwnCacheDirectory(context, DIRECTORY_NAME + "/Cache");
// Get singleton instance of ImageLoader
imageLoader = ImageLoader.getInstance();
// Create configuration for ImageLoader (all options are optional)
ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context).denyCacheImageMultipleSizesInMemory()
.memoryCache(new UsingFreqLimitedMemoryCache(4 * 1024 * 1024))
.discCache(new UnlimitedDiscCache(cacheDir))
.discCacheFileNameGenerator(new HashCodeFileNameGenerator())
.defaultDisplayImageOptions(
new DisplayImageOptions.Builder()
.showStubImage(R.drawable.ic_default_logo)
.resetViewBeforeLoading()
.cacheInMemory()
.cacheOnDisc()
.imageScaleType(ImageScaleType.IN_SAMPLE_POWER_OF_2)
.build())
.tasksProcessingOrder(QueueProcessingType.FIFO)
.build();
// Initialize ImageLoader with created configuration.
imageLoader.init(config);
}
public void displayImage(final ImageView imageView, String imageURI) {
if(imageView == null || imageURI == null) {
Log.e(TAG, "Either of image view or image uri is null");
return;
}
// Load and display image
imageLoader.displayImage(imageURI, imageView, new ImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {}
@Override
public void onLoadingFailed(String imageUri, View view, FailReason failReason) {}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
// imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 30));
}
@Override
public void onLoadingCancelled(String imageUri, View view) {}
});
}
public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final int color = 0xff424242;
final Paint paint = new Paint();
final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
final RectF rectF = new RectF(rect);
final float roundPx = pixels;
paint.setAntiAlias(true);
canvas.drawARGB(0, 0, 0, 0);
paint.setColor(color);
canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
canvas.drawBitmap(bitmap, rect, rect, paint);
return output;
}
}
在适配器类中,首先需要将所有定义移到if (view == null) {...}
方法中。我的样本适配器是这样的。你可以忽略我的监听器,因为我的每一行都有一个按钮。
public class MyCrowdAdapter extends BaseAdapter {
public interface OnCrowdRemoveUserListener {
public void OnRemoveUserClicked(User user);
}
private final String TAG = "*** MyCrowdAdapter ***";
private Context context;
private OnCrowdRemoveUserListener listener;
private LayoutInflater myInflater;
private ImageDownloader imageDownloader;
private List<User> userList;
public MyCrowdAdapter(Context context) {
this.context = context;
myInflater = LayoutInflater.from(context);
imageDownloader = ImageDownloader.getInstance(context);
}
public void setData(List<User> userList) {
this.userList = userList;
Log.i(TAG, "List passed to the adapter.");
}
@Override
public int getCount() {
try {
return userList.size();
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
@Override
public View getView(final int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = myInflater.inflate(R.layout.list_my_crowd_row, null);
holder = new ViewHolder();
Typeface font = Typeface.createFromAsset(context.getAssets(), "fonts/ITCAvantGardeStd-Demi.ttf");
holder.tvUserName = (TextView) convertView.findViewById(R.id.tvUserName);
holder.tvUserName.setTypeface(font);
holder.ivPicture = (ImageView) convertView.findViewById(R.id.ivPicture);
holder.btnRemove = (Button) convertView.findViewById(R.id.btnRemove);
holder.btnRemove.setFocusable(false);
holder.btnRemove.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Integer pos = (Integer)v.getTag();
Log.i(TAG, "Item: " + pos);
listener.OnRemoveUserClicked(userList.get(pos));
}
});
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
holder.btnRemove.setTag(position);
holder.tvUserName.setText(userList.get(position).getFirstName());
imageDownloader.displayImage(holder.ivPicture, userList.get(position).getProfilePictureUrl());
return convertView;
}
public void setOnRemoveClickedListener(OnCrowdRemoveUserListener listener) {
this.listener = listener;
}
static class ViewHolder {
TextView tvUserName;
ImageView ivPicture;
Button btnRemove;
}
}
一个建议,而不是像这样的验证: if(holder.tvTitle!= null&amp;&amp; null!= objBean.getTitle() &安培;&安培; objBean.getTitle()。trim()。length()&gt; 0){...} 只需使用静态方法TextUtils,如下所示: 如果(TextUtils.isEmpty(objBean.getTitle);!
===========
<强>更新强>
===========
关于您的问题,请在图片上方显示进度条: 它既简单又复杂:)有两种方式, 第一种方式基于您的代码: 1 - 在ImageDownloader类中定义一个接口,就像我在适配器中的接口一样。应该是这样的:
public interface OnImageDownloaderListener {
public void OnDownloadStarted();
public void OnDownloadFinished();
}
2-在decleration部分声明它
OnImageDownloaderListener listener;
3-改变thosr这样的两个听众
@Override
public void onLoadingStarted(String imageUri, View view) {
listener.OnDownloadStarted();
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
// Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
// imageView.setImageBitmap(getRoundedCornerBitmap(bitmap, 30));
listener.OnDownloadFinished();
}
4-将此方法添加到ImageDownloader类
public void setOnImageDownloaderListener(OnImageDownloaderListener listener) {
this.listener = listener;
}
5-在适配器中以及此行下方:
imageDownloader = ImageDownloader.getInstance(context);
实现这样的两个方法:
imageDownloader.setOnImageDownloaderListener(new ImageDownloader.OnImageDownloaderListener{
@Override
public void OnDownloadStarted() {
pbar.start();
}
@Override
public void OnDownloadFinished(){
pbar.stop();
}
}
);
它应该对你有所帮助。但是,如果我是你,我会采用第二种方法来创建新组件。该组件包括两个视图,一个图像视图和顶部的进度条(与您当前的相同)。然后在该组件类中添加上述所有方法。因此,轻松通过您的应用程序,您可以在任何您想要的活动中添加视图并只传递URL,然后组件负责显示进度条并停止它。根据您的代码,如果您有10个similr活动,则需要复制/粘贴代码。
希望它可以帮助你:)