首页 文章

为什么getActivity在ViewPager的Fragment中返回null?

提问于
浏览
1

我有一个MainActivity,从那里我有ViewPager有两个片段 . 我想从FragmentTwo更改FragmentOne视图的属性 . 所以我所拥有的是从FragmentTwo到MainActivity的回调方法 . 回调方法如下所示:

@Override
public void newMessage(String message) {

    CalculatorFragment calculatorFragment = (CalculatorFragment) fragmentPagerAdapter.getItem(CALCULATOR_FRAGMENT);

    switch (message){
        case SettingsFragment.CHANGE_COLOR:
           //((TextView)view.findViewById(R.id.textViewSum)).setTextColor(Color.RED);
            break;
        case SettingsFragment.NEW_PICTURE:
            calculatorFragment.setBackground();
            break;
        default:
            break;
    }
}

这很好用 . 当用户在FragmentTwo中选择一个新图片时,我调用FragmentOne(CalculatorFragment)方法setBackground来设置新图片 . 以下是setBackground方法的样子:

public void setBackground(){
    final Bitmap bitmap = new ImageSaver(getActivity()).load();

    if(bitmap != null){
        imageViewBackground.setImageBitmap(bitmap);

    }
}

这里通过加载图片得到一个nullpointer异常,因为getActivity()返回null .

EDIT 这是我创建ViewPager的代码:

public static final int CALCULATOR_FRAGMENT = 0;
public static final int SETTINGS_FRAGMENT = 1;
public static final int FRAGMENTS = 2;

private FragmentPagerAdapter fragmentPagerAdapter;

private ViewPager viewPager;

private List<Fragment> fragments = new ArrayList<Fragment>();

private void initializeFragments(){
    fragments.add(CALCULATOR_FRAGMENT, new CalculatorFragment());
    fragments.add(SETTINGS_FRAGMENT, new SettingsFragment());

    fragmentPagerAdapter = new FragmentPagerAdapter(getSupportFragmentManager()){
        @Override
        public int getCount() {
            return FRAGMENTS;
        }
        @Override
        public Fragment getItem(final int position) {
            return fragments.get(position);
        }
    };

    viewPager = (ViewPager) findViewById(R.id.pager);

    viewPager.setAdapter(fragmentPagerAdapter);
}

EDIT Logcat:

08-11 11:38:38.189 21996-21996/com.tomhogenkamp.personalcalc E/AndroidRuntime: FATAL EXCEPTION: main
                                                                           Process: com.tomhogenkamp.personalcalc, PID: 21996
                                                                           java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=65537, result=-1, data=Intent { dat=content: flg=0x1 }} to activity {com.tomhogenkamp.personalcalc/com.tomhogenkamp.personalcalc.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
                                                                               at android.app.ActivityThread.deliverResults(ActivityThread.java:4013)
                                                                               at android.app.ActivityThread.handleSendResult(ActivityThread.java:4063)
                                                                               at android.app.ActivityThread.access$1400(ActivityThread.java:150)
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448)
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                               at android.os.Looper.loop(Looper.java:168)
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5885)
                                                                               at java.lang.reflect.Method.invoke(Native Method)
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797)
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687)
                                                                            Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.support.v4.app.FragmentActivity.getApplicationContext()' on a null object reference
                                                                               at com.tomhogenkamp.personalcalc.CalculatorFragment.setBackground(CalculatorFragment.java:558)
                                                                               at com.tomhogenkamp.personalcalc.MainActivity.newMessage(MainActivity.java:69)
                                                                               at com.tomhogenkamp.personalcalc.SettingsFragment.onActivityResult(SettingsFragment.java:118)
                                                                               at android.support.v4.app.FragmentActivity.onActivityResult(FragmentActivity.java:165)
                                                                               at android.app.Activity.dispatchActivityResult(Activity.java:6467)
                                                                               at android.app.ActivityThread.deliverResults(ActivityThread.java:4009)
                                                                               at android.app.ActivityThread.handleSendResult(ActivityThread.java:4063) 
                                                                               at android.app.ActivityThread.access$1400(ActivityThread.java:150) 
                                                                               at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1448) 
                                                                               at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                               at android.os.Looper.loop(Looper.java:168) 
                                                                               at android.app.ActivityThread.main(ActivityThread.java:5885) 
                                                                               at java.lang.reflect.Method.invoke(Native Method) 
                                                                               at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:797) 
                                                                               at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:687) 

nullpointer异常仅在应用程序有时在后台然后重新打开时才会发生 . 所以它似乎与杀死进程的Android系统有关?

我怎么解决这个问题?

2 回答

  • 0

    可能问题是,当您看到 FragmentTwo 时, FragmentOne 未附加到您的活动,因此没有(或 null )引用它 . 请尝试以下代码;把它放在 FragmentOne 内:

    private Activity activity;
    
    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof Activity) {
            activity = (Activity) context;
        }
    }
    
    public void setBackground(){
        final Bitmap bitmap = new ImageSaver(activity).load();
    
        if(bitmap != null){
            imageViewBackground.setImageBitmap(bitmap);
        }
    }
    

    如果这不起作用,请向我们展示 ViewPager 的适配器,如果它未包含在 ViewPager 中,则显示您创建片段的代码 .

  • 0

    好的,我知道这个帖子已经有一年了,你现在可能有更好的解决方案了 . 但我现在遇到了和你一样的问题,我刚刚采用了一个简单的(但也许不是最优雅的)解决方案,似乎效果很好 . 首先,我在我的FragmentOne上添加了一个MainActivity字段

    private MainActivity dad;
    

    然后我插入了一个这样的构造函数:

    public FragmentOne(MainActivity ctx){
        this();
        this.dad = ctx;
    }
    

    另外,我还为api安全插入了一个空构造:

    public FragmentOne(){
        super();
    }
    

    然后,在我通常会插入FragmentOne的Main活动中,我将构造函数与MainActivity构造函数一起使用 .

    new FragmentOne(this)
    

    现在,您可以使用活动实例而不是getActivity()方法 .

    我把它测试,它完美地工作 .


    编辑:虽然这解决了我的getActivity()方法的问题,我仍然在我的onCreate()方法的ListView集上得到一些Null指针(有时它被正常调用,有时它也给了我NPE问题 . 所以,经过深思熟虑之后,我决定改变我的想法

    @Override
    public Fragment getItem(int pos) {
        if (pos == 0){
            return new FragmentOne();
        } else if (pos == 1) {
            return new FragmentTwo();
        }
    }
    

    因为你已经发现并打电话给 List<Fragment>

    @Override
    public Fragment getItem(int pos) {
        return my_frags_list.get(pos);
    }
    

    就像你做的那样 . 在每个 getItem 调用上调用一个新的Fragment实例对我来说似乎很奇怪 . 在执行此List方式后,我的片段字段停止给我NPE . 到现在为止还挺好 . 所以现在我唯一的想法是为什么ViewPagers上的android示例建议在 List<Fragment> 解决方案的每个 getItem(int pos) 调用intead上使用 new FragmentInstance() ?谁知道 .

相关问题