在VIewPager(Android)中的两个片段之间传递数据(NullPointerException)

时间:2014-01-30 20:55:00

标签: java android android-fragments nullpointerexception android-viewpager

所以基本上我有 2 片段 - FragmentConverterFragmentFavourites,我有一个MainActivity。我正在尝试使用名为Communicator的接口将第一个片段中的4个数组传递给第二个数组。具体的片段如下所示:

public interface Communicator {

    public void respond(String[] names, String[] codes, String[] symbols, int[] images);
}

这是FragmentFavourites内的方法:

@Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // TODO Auto-generated method stub

        String[] checkedNames = new String[counter];
        String[] checkedCodes = new String[counter];
        String[] checkedSymbols = new String[counter];
        int[] checkedImages = new int[counter];
        comm = (Communicator) getActivity();
        int index = 0;
        if (item.getItemId() == R.id.action_save){
            for (int i=0;i<checked.size();i++){
                if (checked.get(i) == true){
                    checkedNames[index] = names[i];
                    checkedCodes[index] = codes[i];
                    checkedSymbols[index] = symbols[i];
                    checkedImages[index] = images[i];
                    index++;
                }

            }
            comm.respond(checkedNames, checkedCodes, checkedSymbols, checkedImages);
        }

        return super.onOptionsItemSelected(item);
    }

这是MainActivity中实现的接口方法:

@Override
public void respond(String[] names, String[] codes, String[] symbols,
        int[] images) {
    // TODO Auto-generated method stub
    FragmentConverter frag = (FragmentConverter) fragmentPagerAdapter.getItem(1);
    frag.changeData(names, codes, symbols, images);
}

这是一种收集FragmentConverter中的数据的方法:

public void changeData(String[] names, String[] codes, String[] symbols, int[] images){
        this.names = names;
        this.codes = codes;
        this.symbols = symbols;
        this.images = images;

        Log.d("TEST", symbols.length + names.length + codes.length + images.length + "");
        tvOneRate.setText(names[1]); 
}

现在的问题是,每当我尝试更改FragmentConverter内的ui组件时,我都会得到NullPointerException,但Log.d语句会返回正确的结果。

EDIT1:FragmentPagerAdapter的getItem()方法:

@Override
    public Fragment getItem(int i) {
        // TODO Auto-generated method stub
        Fragment frag = null;
        if (i == 0){
            frag = new FragmentFavourites();
        }
        if (i == 1){
            frag = new FragmentConverter();
        }
        return frag;
    }

4 个答案:

答案 0 :(得分:6)

编辑:

当您调用fragmentPagerAdapter.getItem(1)时,您将获得该片段的新实例,因此您指的是另一个对象。这就是为什么视图为null并且你得到NullPointerException。如果您只需要一个适用于2个片段的适配器,您可以试试类似的东西:

public class YourPagerAdapter extends android.support.v4.app.FragmentPagerAdapter {

        private FragmentFavourites mFragFavourites;
        private FragmentConverter mFragConverter;

        public YourPagerAdapter() {

            // ... your code above
            this.mFragFavourites = new FragmentFavourites();
            this.mFragConverter = new FragmentConverter();
        }

        @Override
        public Fragment getItem(int position) {

            switch (position) {
                case 0:  
                    return mFragFavourites;

                case 1:
                    return mFragConverter;                      
                default:
                    return null;
            }    
        }
    }

答案 1 :(得分:2)

如上所述,carlo.marinangeli建议您在调用fragmentPagerAdapter.getItem(1)时获取片段的新实例,以便引用其他对象

因此,要从适配器获取相同的对象,您需要存储对象。您可以在适配器中尝试以下方法 -

public Fragment getFragmentAtPosition(int position) {
            return registeredFragments.get(position);
}

其中registeredFragments是 -

private SparseArray<Fragment> registeredFragments = new SparseArray<Fragment>();

并在getItem方法中填充此sparseArray,如下所示 -

@Override
        public Fragment getItem(int position) {
            switch (position) {
                case 0:
                    fragment = FragmentPost.newInstance(position);
                    registeredFragments.put(position, fragment);
                    return fragment;
               }
            return null;
        }

答案 2 :(得分:1)

通过使用fragmentPagerAdapter.getItem(pos)方法,每次调用respond()方法时,我都会引用一个新对象。我使用findFragmentByTag()方法修改了它:

    @Override
    public void respond(String[] names, String[] codes, String[] symbols,
            int[] images) {
        FragmentManager manager = getSupportFragmentManager();
        FragmentConverter frag = (FragmentConverter) manager.findFragmentByTag("android:switcher:" + pager.getId() + ":" + 1);
        frag.changeData(names, codes, symbols, images);
    }

答案 3 :(得分:0)

您可以获得该错误,因为您假设您已经获得了FragmentConverter以及与之关联的视图。

如果没有logcat,帮助你会变得有点困难,但基本上我想在这种情况下做的就是通过活动传递一切,而不知道片段中是否存在其他片段。

  • F1将状态对象修改为活动
  • F2必须注册为 监听活动(请注意片段可以附加 并在视图分页器中分离)
  • 活动收到更新后,会立即查找所有已注册的听众,如果有人提供更新的