有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

所以基本上我有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。语句返回正确的结果

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) 个答案

  1. # 1 楼答案

    编辑:

    当您调用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;
                }    
            }
        }
    
  2. # 2 楼答案

    如上所述,卡洛。marinangeli建议你叫fragmentPagerAdapter。getItem(1)您将获得片段的一个新实例,因此您引用的是另一个对象

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

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

    凡注册碎片是—

    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;
            }
    
  3. # 3 楼答案

    您可能会得到该错误,因为您假设您已经获得了FragmentConverter及其关联的视图

    如果没有logcat,帮助您变得有点困难,但在这种情况下,基本上我想做的是通过活动传递所有信息,而不让其他片段知道它们的存在

    • F1将状态对象修改到活动中
    • F2必须注册为 活动的侦听器(请注意,可以附加片段 (并在视图寻呼机中分离)
    • 活动收到更新的消息后,会立即查找所有已注册的侦听器,如果有人,则会发送更新的消息
  4. # 4 楼答案

    通过使用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);
        }