使用 FragmentStatePagerAdapter 更改 Fragment 中 ImageView 的图像

Changing image of ImageView in Fragment using FragmentStatePagerAdapter

我在片段中有一个 viewpager,我想在运行时修改由 viewPager 托管的片段的内容。

我想从 Firebase 获取数据并将查询结果添加到适配器。每当在 onChildAdded 上收到响应时,我都会将数据添加到我的数组列表并调用响应,其中更新适配器的数据并调用 notifyDataSetChanged

FindSlideFragment 中更改图像时出现 NullPointerException,我无法弄清楚为什么布局不正确已填充或如果我遗漏了什么。

如果这不是更新我的片段的正确方法,那么什么是合适的方法?

FindFragment.java

public class FindFragment extends Fragment {

private Firebase ref;
private String name="";
private String email="";
private String pass="";
private String image="";
private String uid="";

ArrayList<Snap> snapsList = new ArrayList<>();

private ViewPager viewPager;
private ScreenSlidePagerAdapter mPagerAdapter;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View root = inflater.inflate(R.layout.find_fragment, container, false);

    Bundle bundle = getArguments();
    uid = bundle.getString("uid");
    email = bundle.getString("email");
    pass = bundle.getString("pass");


    Firebase ref = new Firebase(Constants.FIREBASE_URL+"snaps/");
    Query queryRef = ref.orderByKey();


    queryRef.addChildEventListener(new ChildEventListener() {

        @Override
        public void onChildAdded(DataSnapshot snapshot, String previousChild) {
            Iterator<DataSnapshot> it = snapshot.getChildren().iterator();
            Snap snap = snapshot.getValue(Snap.class);
            snapsList.add(snap);
            reload();
        }

        @Override
        public void onChildChanged(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onChildRemoved(DataSnapshot dataSnapshot) {

        }

        @Override
        public void onChildMoved(DataSnapshot dataSnapshot, String s) {

        }

        @Override
        public void onCancelled(FirebaseError firebaseError) {

        }

    });


    viewPager = (ViewPager) root.findViewById(R.id.pager);
    /** Important: Must use the child FragmentManager or you will see side effects. */
    mPagerAdapter= new ScreenSlidePagerAdapter(getChildFragmentManager(), snapsList.size(), getContext(), snapsList);
    viewPager.setAdapter(mPagerAdapter);

    return root;
}

private void reload() {
    mPagerAdapter.setData(snapsList);
    mPagerAdapter.setSlideCount();
    mPagerAdapter.notifyDataSetChanged();
    viewPager.invalidate();
    //viewPager.setCurrentItem(0);
}


/**
 * A simple pager adapter that represents 5 ScreenSlidePageFragment objects, in
 * sequence.
 */
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    private int slideCount;
    private Context context;
    ArrayList<Snap> snapsList = new ArrayList<>();

    public ScreenSlidePagerAdapter(FragmentManager fm, int slideCount, Context context, ArrayList<Snap> snaps) {
        super(fm);
        this.slideCount = slideCount;
        this.context = context;
        this.snapsList = snaps;
    }

    @Override
    public Fragment getItem(int position) {
        FindSlideFragment fragment = new FindSlideFragment();
        if(!snapsList.isEmpty())
        fragment.setImage(snapsList.get(position).getImage());
        return fragment;
    }

    @Override
    public int getCount() {
        return slideCount;
    }

    public void setSlideCount(){
        slideCount = snapsList.size();
    }

    public void setData(ArrayList<Snap> snaps) {
        this.snapsList = snaps;
    }

}
}

FindSlideFragment.java

public class FindSlideFragment extends Fragment {


ViewGroup rootView;

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {


    rootView = (ViewGroup) inflater.inflate(
            R.layout.find_content_fragment, container, false);

    return rootView;
}


public void setImage(String image) {
    ImageView iv_snap = (ImageView)rootView.findViewById(R.id.imageView_snap);
    byte[] imageAsBytes = Base64.decode(image, Base64.DEFAULT);
    Bitmap bmp = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
    iv_snap.setImageBitmap(bmp);
}
  }

StackTrace

03-18 21:09:52.980 10354-10354/com.codelycan.foodtinder E/AndroidRuntime: FATAL EXCEPTION: main
                                                                      Process: com.codelycan.foodtinder, PID: 10354
                                                                      java.lang.NullPointerException
                                                                          at com.codelycan.foodtinder.FindSlideFragment.setImage(FindSlideFragment.java:39)
                                                                          at com.codelycan.foodtinder.FindFragment$ScreenSlidePagerAdapter.getItem(FindFragment.java:156)
                                                                          at android.support.v4.app.FragmentStatePagerAdapter.instantiateItem(FragmentStatePagerAdapter.java:105)
                                                                          at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:943)
                                                                          at android.support.v4.view.ViewPager.populate(ViewPager.java:1091)
                                                                          at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:608)
                                                                          at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:570)
                                                                          at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:1019)
                                                                          at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2989)
                                                                          at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:279)
                                                                          at com.codelycan.foodtinder.FindFragment.reload(FindFragment.java:129)
                                                                          at com.codelycan.foodtinder.FindFragment.access[=12=]0(FindFragment.java:28)
                                                                          at com.codelycan.foodtinder.FindFragment.onChildAdded(FindFragment.java:64)
                                                                          at com.firebase.client.core.ChildEventRegistration.fireEvent(ChildEventRegistration.java:48)
                                                                          at com.firebase.client.core.view.DataEvent.fire(DataEvent.java:45)
                                                                          at com.firebase.client.core.view.EventRaiser.run(EventRaiser.java:38)
                                                                          at android.os.Handler.handleCallback(Handler.java:733)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:136)
                                                                          at android.app.ActivityThread.main(ActivityThread.java:5426)
                                                                          at java.lang.reflect.Method.invokeNative(Native Method)
                                                                          at java.lang.reflect.Method.invoke(Method.java:515)
                                                                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
                                                                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
                                                                          at dalvik.system.NativeStart.main(Native Method)

试试这个:

public class FindSlideFragment extends Fragment {
    ViewGroup rootView;
    ImageView iv_snap;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        rootView = (ViewGroup) inflater.inflate(R.layout.find_content_fragment, container, false);
        iv_snap = (ImageView)rootView.findViewById(R.id.imageView_snap);

        return rootView;
    }

    public void setImage(String image) {

        byte[] imageAsBytes = Base64.decode(image, Base64.DEFAULT);
        Bitmap bmp = BitmapFactory.decodeByteArray(imageAsBytes, 0, imageAsBytes.length);
        iv_snap.setImageBitmap(bmp);
    }
}

我试图在填充之前更改片段的视图

@Override
public Fragment getItem(int position) {
    FindSlideFragment fragment = new FindSlideFragment();
    if(!snapsList.isEmpty())
    fragment.setImage(snapsList.get(position).getImage());
    return fragment;
}

此处片段在返回之前不会被填充,但我尝试在片段被填充之前更改图像视图,这很自然会引发空指针异常。

周转可能有多种方式,但我所做的是填充一次片段并不断更改同一片段的图像视图源。