我有一个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。
修改 以下是我创建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);
}
编辑 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系统有关?
我该如何解决这个问题?
答案 0 :(得分:0)
问题可能是FragmentOne
在您看到FragmentTwo
时未附加到您的活动中,因此没有(或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
中,则显示您创建片段的代码。
答案 1 :(得分: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>
,因为你已经DID并且正在调用
@Override
public Fragment getItem(int pos) {
return my_frags_list.get(pos);
}
像你一样。
在每个getItem
调用中调用一个新的Fragment实例似乎很奇怪。在执行此List方式后,我的片段字段停止给我NPE。到现在为止还挺好。所以现在我唯一的想法是为什么ViewPagers上的Android示例建议在new FragmentInstance()
解决方案的每个getItem(int pos)
调用intead上使用List<Fragment>
?谁知道呢。