ARRRRGGHHHH
我正在创建YoutubeThumbnailViews和图像的网格视图,我通过共享偏好中的URL字符串加载它们。
我在gridview的内部适配器类中获得了一个NPE
thumbnail.setTag(favorites.get(position).substring(32));
因为缩略图为空。
仅当我从'favorites'列表String中删除URL然后再发送notifyDataSetChanged()时才会发生此事件。
我不明白的是为什么会这样,因为我在它上面创建了几行缩略图对象,所以我看不出它是如何为空。
这是我的菜单方法delete,它删除了gridview中点击的链接,然后调用notifydatasetchanged()
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
switch(item.getItemId()) {
case R.id.delete:
SharedPreferences sharedPreferences = this.getSharedPreferences("favorites", Activity.MODE_PRIVATE);
String prefFavoritesList = sharedPreferences.getString(PREFERENCES_FAVORITES, null);
String updatedFavoriteList = prefFavoritesList.replace(favorites.get(info.position)+",", "");
updatedFavoriteList = prefFavoritesList.replace(","+favorites.get(info.position),"");
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("favorites", updatedFavoriteList);
editor.commit();
favorites.remove(info.position);
favoritesMediaAdapter.notifyDataSetChanged();
return true;
default:
return super.onContextItemSelected(item);
}
更具体地说,这是我的适配器类,同样在调用时发生错误
thumbnail.setTag(favorites.get(position).substring(32));
我把它包裹在** **中,以便更容易识别。
这是类(它在共享偏好中加载YoutubeThumbnailViews和像URL一样的小缩略图:
private class FavoritesMediaAdapter extends BaseAdapter {
private final Map<YouTubeThumbnailView, YouTubeThumbnailLoader> thumbnailViewToLoaderMap;
private final LayoutInflater inflater;
private final ThumbnailListener thumbnailListener;
private ArrayList<String> favorites;
public FavoritesMediaAdapter(Context context, ArrayList<String> favorites) {
this.favorites = favorites;
thumbnailViewToLoaderMap = new HashMap<YouTubeThumbnailView, YouTubeThumbnailLoader>();
inflater = LayoutInflater.from(context);
thumbnailListener = new ThumbnailListener();
}
public void releaseLoaders() {
for (YouTubeThumbnailLoader loader : thumbnailViewToLoaderMap.values()) {
loader.release();
}
}
@Override
public int getCount() {
return favorites.size();
}
@Override
public Object getItem(int position) {
return null;
}
@Override
public long getItemId(int position) {
return position;
}
/**
* good to go. This initializes the youtubethumbnailview inside item_grid_video.xml
* @param position
* @param convertView
* @param parent
* @return
*/
@Override
public final View getView(int position, View convertView, ViewGroup parent) {
final ViewHolder holder;
View view = convertView;
if(favorites.get(position).contains("youtube")) // Loading youtube video thumbnails
{
if (view == null) {
// The view is null so initialize the loader
view = inflater.inflate(R.layout.item_grid_video, parent, false);
YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.youtubethumbnailview);
thumbnail.setTag(favorites.get(position).substring(32));
thumbnail.initialize(DeveloperKey.DEVELOPER_KEY, thumbnailListener);
} else {
// The view is not null
YouTubeThumbnailView thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.youtubethumbnailview);
//TODO figure out why thumbnail is null...
if(thumbnail == null)
{
Log.d("frustration", "why is it null?");
}
YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(thumbnail);
if (loader == null) {
// 2) The view is already created, and is currently being initialized. We store the
// current videoId in the tag.
Log.d("frustration", favorites.get(position));
**thumbnail.setTag(favorites.get(position).substring(32));**
} else {
// 3) The view is already created and already initialized. Simply set the right videoId
// on the loader.
//thumbnail.setImageResource(R.drawable.loading_thumbnail);
loader.setVideo(favorites.get(position).substring(32));
}
}
}
else // Loading small images to act as thumbnails.
{
if (view == null) {
view = getLayoutInflater().inflate(R.layout.item_grid_image, parent, false);
holder = new ViewHolder();
assert view != null;
holder.imageView = (ImageView) view.findViewById(R.id.image);
holder.progressBar = (ProgressBar) view.findViewById(R.id.progress);
view.setTag(holder);
} else {
holder = (ViewHolder) view.getTag();
}
imageLoader.displayImage(favorites.get(position), holder.imageView, options, new SimpleImageLoadingListener() {
@Override
public void onLoadingStarted(String imageUri, View view) {
holder.progressBar.setProgress(0);
holder.progressBar.setVisibility(View.VISIBLE);
}
@Override
public void onLoadingFailed(String imageUri, View view,
FailReason failReason) {
holder.progressBar.setVisibility(View.GONE);
}
@Override
public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) {
holder.progressBar.setVisibility(View.GONE);
}
}, new ImageLoadingProgressListener() {
@Override
public void onProgressUpdate(String imageUri, View view, int current,
int total) {
holder.progressBar.setProgress(Math.round(100.0f * current / total));
}
}
);
}
return view;
}
private final class ThumbnailListener implements
YouTubeThumbnailView.OnInitializedListener,
YouTubeThumbnailLoader.OnThumbnailLoadedListener {
@Override
public void onInitializationSuccess(
YouTubeThumbnailView view, YouTubeThumbnailLoader loader) {
loader.setOnThumbnailLoadedListener(this);
thumbnailViewToLoaderMap.put(view, loader);
//view.setImageResource(R.drawable.loading_thumbnail);
String videoId = (String) view.getTag();
loader.setVideo(videoId);
}
@Override
public void onInitializationFailure(
YouTubeThumbnailView view, YouTubeInitializationResult loader) {
//view.setImageResource(R.drawable.no_thumbnail);
}
@Override
public void onThumbnailLoaded(YouTubeThumbnailView view, String videoId) {
}
@Override
public void onThumbnailError(YouTubeThumbnailView youTubeThumbnailView, YouTubeThumbnailLoader.ErrorReason errorReason) {
}
}
}
另外,我使用的是UniversalImageLoader的示例gridview代码,它在适配器外部实现了ViewHolder。我不了解ViewHolder,所以我不确定这是否会导致标签出现问题,但此代码段不在适配器类中:
static class ViewHolder {
ImageView imageView;
ProgressBar progressBar;
}
感谢任何勇于提供帮助的人:)
答案 0 :(得分:0)
尝试使用ViewHolder:
private class ViewHolder {
YouTubeThumbnailView thumbnail;
}
@Override
public final View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder = null;
View view = convertView;
if(favorites.get(position).contains("youtube")) // Loading youtube video thumbnails
{
if (view == null) {
// The view is null so initialize the loader
view = inflater.inflate(R.layout.item_grid_video, parent, false);
holder = new ViewHolder();
holder.thumbnail = (YouTubeThumbnailView) view.findViewById(R.id.youtubethumbnailview);
holder.thumbnail.setTag(favorites.get(position).substring(32));
holder.thumbnail.initialize(DeveloperKey.DEVELOPER_KEY, thumbnailListener);
view.setTag(holder);
} else {
holder = (ViewHolder)view.getTag();
//TODO figure out why thumbnail is null...
if(holder.thumbnail == null)
{
Log.d("frustration", "why is it null?");
}
YouTubeThumbnailLoader loader = thumbnailViewToLoaderMap.get(thumbnail);
if (loader == null) {
// 2) The view is already created, and is currently being initialized. We store the
// current videoId in the tag.
Log.d("frustration", favorites.get(position));
**holder.thumbnail.setTag(favorites.get(position).substring(32));**