用于 onActivityCreated 中通用图像加载器的片段中进度条的 NullPointerException

Posted

技术标签:

【中文标题】用于 onActivityCreated 中通用图像加载器的片段中进度条的 NullPointerException【英文标题】:NullPointerException for progressbar in fragment for Universal Image Loader in onActivityCreated 【发布时间】:2014-08-13 00:08:40 【问题描述】:

我遇到了无法诊断的奇怪 NPE。我知道它来自引用我的 ProgressBar 微调器,但我不知道为什么,因为我在 onCreateView 中为片段实例化它。

下面是我的片段的代码。在你看之前,我正在使用通用图像加载器来加载图像。如果我完全删除微调器 E.G. 的代码行,图像会加载。 spinner.setVisibility(View.GONE); spinner.setVisibility(View.VISIBLE);

import android.app.Activity;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.nostra13.universalimageloader.core.DisplayImageOptions;
import com.nostra13.universalimageloader.core.ImageLoader;
import com.nostra13.universalimageloader.core.assist.FailReason;
import com.nostra13.universalimageloader.core.assist.ImageScaleType;
import com.nostra13.universalimageloader.core.display.FadeInBitmapDisplayer;
import com.nostra13.universalimageloader.core.listener.SimpleImageLoadingListener;


/**
 * A simple @link Fragment subclass.
 * Activities that contain this fragment must implement the
 *
 * to handle interaction events.
 * Use the @link ImageFragment#newInstance factory method to
 * create an instance of this fragment.
 *
 */
public class ImageFragment extends Fragment 
    // TODO: Rename parameter arguments, choose names that match
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private int mImageNum;

    private ImageView imageDisplay;
    private TextView textTest;

    public ProgressBar spinner;

    private String mUrl;

    private ImageLoader imageLoader = ImageLoader.getInstance();

    DisplayImageOptions options;


    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @return A new instance of fragment ImageFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static ImageFragment newInstance(int position, String url)
    
        ImageFragment fragment = new ImageFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_PARAM1, position);
        args.putString(ARG_PARAM2, url);
        fragment.setArguments(args);
        return fragment;
    
    public ImageFragment()
    
        // Required empty public constructor
    

    @Override
    public void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        mImageNum = getArguments() != null ? getArguments().getInt(ARG_PARAM1) : -1;
        mUrl = getArguments() != null ? getArguments().getString(ARG_PARAM2) : null;
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) 
        final View v = inflater.inflate(R.layout.fragment_image, container, false);
        imageDisplay = (ImageView) v.findViewById(R.id.imageView);
        spinner = (ProgressBar) imageDisplay.findViewById(R.id.loading);

        options = new DisplayImageOptions.Builder()
                .showImageForEmptyUri(R.drawable.ic_empty)
                .showImageOnFail(R.drawable.ic_error)
                .resetViewBeforeLoading(true)
                .cacheOnDisk(true)
                .imageScaleType(ImageScaleType.EXACTLY)
                .bitmapConfig(Bitmap.Config.RGB_565)
                .considerExifParams(true)
                .displayer(new FadeInBitmapDisplayer(300))
                .build();

        return v;
    

    @Override
    public void onActivityCreated(Bundle savedInstanceState) 
        super.onActivityCreated(savedInstanceState);



        imageLoader.displayImage(mUrl, imageDisplay, options, new SimpleImageLoadingListener() 
            @Override
            public void onLoadingStarted(String imageUri, View view) 
                spinner.setVisibility(View.VISIBLE);
            

            @Override
            public void onLoadingFailed(String imageUri, View view, FailReason failReason) 
                String message = null;
                switch (failReason.getType()) 
                    case IO_ERROR:
                        message = "Input/Output error";
                        break;
                    case DECODING_ERROR:
                        message = "Image can't be decoded";
                        break;
                    case NETWORK_DENIED:
                        message = "Downloads are denied";
                        break;
                    case OUT_OF_MEMORY:
                        message = "Out Of Memory error";
                        break;
                    case UNKNOWN:
                        message = "Unknown error";
                        break;
                

                spinner.setVisibility(View.GONE);
            

            @Override
            public void onLoadingComplete(String imageUri, View view, Bitmap loadedImage) 
                spinner.setVisibility(View.GONE);
            
        );




    

请帮忙!我不擅长使用 Fragments,我不知道为什么它不起作用

【问题讨论】:

【参考方案1】:
final View v = inflater.inflate(R.layout.fragment_image, container, false);
imageDisplay = (ImageView) v.findViewById(R.id.imageView);
spinner = (ProgressBar) imageDisplay.findViewById(R.id.loading);

这个“微调器”是片段视图的子视图还是“imageDisplay”?

或许,应该是spinner = (ProgressBar) v.findViewById(R.id.loading);

【讨论】:

【参考方案2】:

你应该改变这个

    spinner = (ProgressBar) imageDisplay.findViewById(R.id.loading);

    spinner = (ProgressBar) v.findViewById(R.id.loading);

您应该从Fragment 的膨胀视图中找到View

【讨论】:

下面这个人最先回答,但你们都是我书中的赢家! @user2977650 哦,那我想你是我希望的新伙伴!

以上是关于用于 onActivityCreated 中通用图像加载器的片段中进度条的 NullPointerException的主要内容,如果未能解决你的问题,请参考以下文章

对onActivityCreated片段回调有啥误解吗?

onActivityCreated 已弃用,如何正确使用 LifecycleObserver?

为啥会调用fragment的onCreateView、onCreate、onActivityCreated

如何在 OnActivityCreated 中解决这个不受欢迎的问题?

onactivitycreated啥时候执行

在 onActivityCreated() 之后再次调用 Fragment 的 onAttach()