Ошибка при вызове метода у третьего фрагмента
У меня есть пример программы, как показано ниже, что я упростил. При вызове метода в третьем фрагменте возникает ошибка (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;
}
}
Ошибка Logcat, когда я вызываю метод из 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)
Ошибка Logcat при вызове метода из 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)
2 ответа
ViewPager
хранит текущий, правый и, если есть, левый фрагменты. Когда ты в UserFragment
у вас есть только UserFragment
а также ItemFragment
, когда ты в ItemFragment
у вас есть все ваши фрагменты. И когда ты в ListFragment
у вас есть только ListFragment
а также ItemFragment
,
У вас есть npe в UserFragment
:
UserFragment.onClick(UserFragment.java:42)
Эта часть вашего кода на UserFragment
, вызывает ваш нпэ:
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.
Но, как я уже упоминал ранее, иметь прямые ссылки от фрагментов к фрагментам - это плохо. Посмотрите, как этот документ связывается с частью Activity, и реализуйте что-то подобное.
РЕДАКТИРОВАТЬ 2: Для вашей реализации ViewPager метод setOffscreenPageLimit может быть решением для вас. Установите более 2 и попробуйте снова.
Это плохой подход, вы не должны вызывать другие методы фрагментов / действий из другого действия или фрагмента. Вы можете использовать шаблон Observer для достижения этой цели.
Но вот обновленный код, он будет работать в вашем случае.
п
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();
}
}