NPE在网格视图中刷新YoutubeThumbnailView

时间:2014-07-16 00:52:46

标签: android gridview nullpointerexception baseadapter android-youtube-api

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;

}

感谢任何勇于提供帮助的人:)

1 个答案:

答案 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));**