问题描述
我有下面简化的示例程序.当我在第三个片段( ListFragment
)中调用方法时出现错误.而即使我从第三个片段中调用另一个片段中的方法也没关系.
I have sample program like at bellow that I have simplified. There is an error when I call a method in third fragment (ListFragment
). Whereas there is alright when I call method in other fragment even though from third fragment.
当我将 ListFragment
更改为第一个或第二个片段时,然后当我在 ListFragment
中调用一个方法时,就可以了.当我在第三个片段中调用一个方法时,放置在第三个片段中的替换片段会出错.
When I change ListFragment
to first or second fragment, then there is alright when I call a method inside ListFragment
. And the substitutes fragment that I place in third fragment get error when I call a method on that.
我不知道,我的错误在哪里.非常感谢您的回答.
I have no idea, where is my mistakes. Thank you very much for any answer.
注意:错误表示程序已关闭,并出现不幸的是,程序已弯曲."
Note: Error meaning that program close, and appear "Unfortunately, program has stooped."
这是我的程序:
MainActivity.java
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
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
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
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
Error Logcat when I call method from UserActivity
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
Error Logcat when I call method from ItemActivity
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)
推荐答案
ViewPager
存储当前,右边和任何左边的片段.当您使用 UserFragment
时,您只有 UserFragment
和 ItemFragment
.当您位于 ItemFragment
中时,便拥有了所有片段.当您位于 ListFragment
中时,您只有 ListFragment
和 ItemFragment
.
ViewPager
stores current,right and if any left fragments. When you are in UserFragment
you only have UserFragment
and ItemFragment
. when you are in ItemFragment
you have all your fragments. And when you are in ListFragment
you only have ListFragment
and ItemFragment
.
您在 UserFragment
处有一个npe:
UserFragment.onClick(UserFragment.java:42)
这部分代码位于 UserFragment
,导致您的npe:
This part of your code at UserFragment
, causes your 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
为空.处理另一个片段中的一个片段的单击事件是一个坏主意.尝试将点击侦听器放到相关片段中.
Because listFragment
is null. It is a bad idea to handle click events of a fragment in another fragment. Try to put your click listeners in to the relevant fragments.
解决你的问题考虑我的答案.
在 UserFragment
上,您可以引用 ItemFragment
.
在 ItemFragment
上,您可以同时引用 UserFragment
和 ListFragment
.
在 ListFragment
上,您可以引用 ItemFragment
.
其他参考文献会使您感到不安.
To solve your npe; consider my answer.
On UserFragment
, you can have reference to ItemFragment
.
On ItemFragment
, you can have references to both UserFragment
and ListFragment
.
On ListFragment
, you can have reference to ItemFragment
.
Other references are going to make you get a npe.
但是正如我之前提到的,要直接从片段引用到片段是一个不好的打算.请参见本文档的与Activity通讯部分并实现类似的功能.
But as I mentioned before, it is a bad desing to have direct references from fragments to fragments. See this document's Communicating with the Activity part and implement something like that.
对于您的实现,ViewPagers setOffscreenPageLimit方法可能是您的解决方案.将其设置为2以上,然后重试.
EDIT 2: For your implementation ViewPagers setOffscreenPageLimit method maybe a solution for you. Set it more than 2 and try again.
这篇关于第三个片段的调用方法时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!