【问题标题】:NPE refreshing YoutubeThumbnailView's within a gridviewNPE 在 gridview 中刷新 YoutubeThumbnailView
【发布时间】:2014-07-16 00:52:46
【问题描述】:

ARRRRGGHHHH

我正在创建一个 YoutubeThumbnailViews 和图像的网格视图,并通过来自 sharedpreferences 的 URL 字符串加载它们。

我在 gridview 的内部适配器类中获得了一个 NPE

thumbnail.setTag(favorites.get(position).substring(32));

因为缩略图为空。

此事件仅在我从“收藏夹”列表字符串中删除 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));

我将它包裹在 ** ** 中以便更容易识别。

这是类(它从共享首选项中的 URL 加载 YoutubeThumbnailViews 和类似图像的小缩略图:

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,所以我不确定这是否会导致标签出现问题,但这段代码 sn-p 在适配器类之外:

static class ViewHolder {
    ImageView imageView;
    ProgressBar progressBar;

}

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

【问题讨论】:

  • 您是否 100% 确定缩略图为空?根本没有机会成为 favourites.get(position).substring(32) ?
  • 是的,100% 确定!我什至数了数,它作为视频的正确 ID 出来了。此外,我做了 Log.d(favorites.get(position).substring(32)) 并获得了正确的 URL。有什么额外的想法吗? ;(我本来希望是这样的。我真的被卡住了

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


【解决方案1】:

尝试使用 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));**

【讨论】:

  • 该死,我在尝试这种方法时遇到了这个问题。另外,我在 edward.m.FavoritesActivity$FavoritesMediaAdapter.getView(FavoritesActivity.java:302) 处创建了名为 ThumbnailViewHolder java.lang.ClassCastException: e.m.m.FavoritesActivity$ViewHolder cannot be cast to edward.m.m.FavoritesActivity$FavoritesMediaAdapter$ThumbnailViewHolder对持有人不好,但是您认为这可能与我在原始帖子底部发布的适配器之外的代码冲突吗?它是用于来自 UniversalImageLoader 的图像的静态视图。
  • 你不是在尝试获取和设置不同类型的 ViewHolder 吗?编辑您的问题并更新 getView 方法
  • 我一开始并没有试图惹恼观众。老实说,我不确定 ViewHolder 在有 NPE 的情况下会如何帮助我。 ViewHolder 不会给问题增加一层复杂性,因为它不仅仅是一个 NPE,而是一个包含不可避免 NPE 的元素的 ViewHolder?回到家后我会编辑原始帖子,并向您介绍最新情况。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-22
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多