我有简化的示例程序,如下图所示。当我在第三个片段(ListFragment
)中调用方法时出错。然而,即使从第三个片段中调用其他片段中的方法也没有问题。
当我将ListFragment
更改为第一个或第二个片段时,我在ListFragment
内调用方法时就可以了。我在第三个片段中放置的替代片段在我调用方法时会出错。
我不知道,我的错误在哪里。非常感谢您的回答。
注意:错误意味着程序关闭,并显示"Unfortunately, program has stooped."
这是我的计划:
MainActivity.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import java.util.Locale;
import id.my.zain.tupperware.fragment.ItemFragment;
import id.my.zain.tupperware.fragment.ListFragment;
import id.my.zain.tupperware.fragment.UserFragment;
public class MainActivity extends FragmentActivity {
private UserFragment userFragment;
private ItemFragment itemFragment;
private ListFragment listFragment;
SectionsPagerAdapter mSectionsPagerAdapter;
ViewPager mViewPager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userFragment = new UserFragment();
itemFragment = new ItemFragment();
listFragment = new ListFragment();
mSectionsPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setAdapter(mSectionsPagerAdapter);
}
public class SectionsPagerAdapter extends FragmentPagerAdapter {
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
Fragment fragment = new Fragment();
switch (position) {
case 0:
return fragment = userFragment;
case 1:
return fragment = itemFragment;
case 2:
return fragment = listFragment;
default:
break;
}
return fragment;
}
@Override
public int getCount() {
// Show 3 total pages.
return 3;
}
@Override
public CharSequence getPageTitle(int position) {
Locale l = Locale.getDefault();
switch (position) {
case 0:
return getString(R.string.title_section1).toUpperCase(l);
case 1:
return getString(R.string.title_section2).toUpperCase(l);
case 2:
return getString(R.string.title_section3).toUpperCase(l);
}
return null;
}
}
}
UserFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import id.my.zain.tupperware.R;
import id.my.zain.tupperware.form.UserForm;
public class UserFragment extends Fragment implements View.OnClickListener{
private UserForm form;
private ItemFragment itemFragment;
private ListFragment listFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_user, container, false);
form = new UserForm(rootView);
itemFragment = (ItemFragment) getActivity().getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":1");
listFragment = (ListFragment) getActivity().getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":2");
form.getUser_item().setOnClickListener(this);
form.getUser_list().setOnClickListener(this);
return rootView;
}
public void onClick(View v) {
if (v == form.getUser_item()) {
itemFragment.user();
}
else if (v == form.getUser_list()) {
listFragment.user();
}
}
public void item() {
int a = 1;
}
public void list() {
int a = 1;
}
}
ItemFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import id.my.zain.tupperware.R;
import id.my.zain.tupperware.form.ItemForm;
public class ItemFragment extends Fragment implements View.OnClickListener {
private ItemForm form;
private UserFragment userFragment;
private ListFragment listFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_item, container, false);
form = new ItemForm(rootView);
userFragment = (UserFragment) getActivity().getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":0");
listFragment = (ListFragment) getActivity().getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":2");
form.getItem_user().setOnClickListener(this);
form.getItem_list().setOnClickListener(this);
return rootView;
}
public void onClick(View v) {
if (v == form.getItem_user()) {
userFragment.item();
}
else if (v == form.getItem_list()) {
listFragment.item();
}
}
public void user() {
int a = 1;
}
public void list() {
int a = 1;
}
}
ListFragment.java
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import id.my.zain.tupperware.R;
import id.my.zain.tupperware.form.ListForm;
public class ListFragment extends Fragment implements View.OnClickListener {
private ListForm form;
private UserFragment userFragment;
private ItemFragment itemFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_list, container, false);
form = new ListForm(rootView);
userFragment = (UserFragment) getActivity().getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":0");
itemFragment = (ItemFragment) getActivity().getSupportFragmentManager()
.findFragmentByTag("android:switcher:" + R.id.pager + ":1");
form.getList_user().setOnClickListener(this);
form.getList_item().setOnClickListener(this);
return rootView;
}
public void onClick(View v) {
if (v == form.getList_user()) {
userFragment.list();
}
else if (v == form.getList_item()) {
itemFragment.list();
}
}
public void user() {
int a = 1;
}
public void item() {
int a = 1;
}
}
从UserActivity调用方法时出现错误Logcat
11-11 13:21:09.273 2806-2806/id.my.zain.tupperware E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at id.my.zain.tupperware.fragment.UserFragment.onClick(UserFragment.java:42)
at android.view.View.performClick(View.java:4202)
at android.view.View$PerformClick.run(View.java:17340)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
从ItemActivity调用方法时出现错误Logcat
11-11 15:02:03.104 3291-3291/id.my.zain.tupperware E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at id.my.zain.tupperware.fragment.ItemFragment.onClick(ItemFragment.java:42)
at android.view.View.performClick(View.java:4202)
at android.view.View$PerformClick.run(View.java:17340)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5039)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
ViewPager
存储当前,右边和左边的碎片。当您在UserFragment
时,您只有UserFragment
和ItemFragment
。当你在ItemFragment
时,你拥有所有的碎片。当您在ListFragment
时,您只有ListFragment
和ItemFragment
。
您在UserFragment
处有一个npe:
UserFragment.onClick(UserFragment.java:42)
UserFragment
代码的这一部分导致你的npe:
public void onClick(View v) {
if (v == form.getUser_item()) {
itemFragment.user();
}
else if (v == form.getUser_list()) {
listFragment.user();
// debug here, you'll see that listFragment is null. thus listFragment.user() throws a npe.
}
}
因为listFragment
为空。处理另一个片段中片段的点击事件是个坏主意。尝试将您的点击侦听器放入相关片段。
修改强>
解决你的问题;考虑我的回答。
在UserFragment
,您可以参考ItemFragment
在ItemFragment
,您可以引用UserFragment
和ListFragment
在ListFragment
,您可以参考ItemFragment
其他参考文献将使你获得一个npe。
但正如我之前提到的,从片段到片段的直接引用是一个糟糕的设计。请参阅此文档的Communicating with the Activity部分并实现类似的内容。
编辑2:对于您的实现,ViewPagers setOffscreenPageLimit方法可能是您的解决方案。将其设置为2以上,然后重试。
答案 1 :(得分:0)
这是一个糟糕的方法,你不应该从其他活动或片段调用其他的片段/活动方法,你可以使用Observer模式来实现这一点。
但这是更新的代码,它将适用于您的情况。
P
ublic void onClick(View v) {
if (v == form.getItem_user()) {
if(usreFragment == null)
{
userFragment = new UserFragment();
}
userFragment.item();
}
else if (v == form.getItem_list()) {
if(listFragment == null)
{
listFragment = new ListFragment();
}
listFragment.item();
}
}