0

私は、TabLayoutを含むアクティビティを持ち、各タブにフラグメントを使用しています。そのフラグメントには、ViewPagerで使用する別のフラグメントが含まれています。これは私の設定です:FragmentStatePageAdapterを使用してViewPagerでフラグメントの位置を保持

RoutineActivity.java

public class RoutineActivity extends AppCompatActivity { 
private ArrayList<CategoryFragment> categories = new ArrayList<>(); 
private TabLayout tabs; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_routine); 

    // Set the toolbar as the action bar and add the Up button 
    Toolbar toolbar = findViewById(R.id.routine_toolbar); 
    setSupportActionBar(toolbar); 
    getSupportActionBar().setDisplayHomeAsUpEnabled(true); 

    // Get the intent and extract the string array 
    Intent intent = getIntent(); 
    ArrayList<String> selected = 
      intent.getStringArrayListExtra(SelectCategoriesActivity.EXTRA_CATEGORIES); 

    // Set the TabLayout 
    this.setTabs(selected); 
} 

// Set the tabs of the TabLayout given a list of tab names 
private void setTabs(ArrayList<String> tabs) { 
    // Setup the tabs and create a fragment for each category 
    this.tabs = findViewById(R.id.category_tabs); 
    for (int x = 0; x < tabs.size(); x++) { 
     TabLayout.Tab tab = this.tabs.newTab().setText(tabs.get(x)); 
     // Select the first tab 
     if (x == 0) { 
      this.tabs.addTab(tab, true); 
     } else { 
      this.tabs.addTab(tab); 
     } 

     // Store the created fragment 
     CategoryFragment categoryFragment = CategoryFragment.newInstance(tabs.get(x)); 
     this.categories.add(categoryFragment); 
    } 

    // Add the first fragment 
    getSupportFragmentManager() 
      .beginTransaction() 
      .add(R.id.fragment_category_container, this.categories.get(0)) 
      .commit(); 


    // Add the tab selected listener 
    this.tabs.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() { 
     @Override 
     public void onTabSelected(TabLayout.Tab tab) { 
      RoutineActivity.this.replaceFragment(tab.getPosition()); 
     } 

     @Override 
     public void onTabUnselected(TabLayout.Tab tab) {} 

     @Override 
     public void onTabReselected(TabLayout.Tab tab) { 

     } 
    }); 
} 

// Replace the fragment corresponding to the category 
private void replaceFragment(int position) { 
    FragmentManager fm = getSupportFragmentManager(); 
    FragmentTransaction ft = fm.beginTransaction(); 
    ft.replace(R.id.fragment_category_container, this.categories.get(position)); 
    ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
    ft.commit(); 
} 
} 

CategoryFragment.java

public class CategoryFragment extends Fragment { 
private ViewPager pager; 
private ScreenSlidePagerAdapter pagerAdapter; 

public CategoryFragment() {} // Required empty public constructor 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    ArrayList<String> selected = new ArrayList<>(); 
    selected.add("1 " + getArguments().get("CATEGORY")); 
    selected.add("2 " + getArguments().get("CATEGORY")); 
    selected.add("3 " + getArguments().get("CATEGORY")); 
    selected.add("4 " + getArguments().get("CATEGORY")); 

    // Instantiate the PageAdapter 
    this.pagerAdapter = new ScreenSlidePagerAdapter(getChildFragmentManager(), selected); 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View view = inflater.inflate(R.layout.fragment_category, container, false); 

    // Instantiate ViewPager and set its adapter 
    this.pager = view.findViewById(R.id.exercise_pager); 
    this.pager.setAdapter(this.pagerAdapter); 

    return view; 
} 

// Return a new instance of this fragment 
public static CategoryFragment newInstance(String category) { 
    Bundle args = new Bundle(); 
    args.putString("CATEGORY", category); 

    CategoryFragment categoryFragment = new CategoryFragment(); 
    categoryFragment.setArguments(args); 

    return categoryFragment; 
} 

// The page adapter 
private class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter { 

    private ArrayList<String> selected; 

    public ScreenSlidePagerAdapter(FragmentManager fm, ArrayList<String> data) { 
     super(fm); 
     this.selected = data; 
    } 

    @Override 
    public Fragment getItem(int position) { 
     return ExerciseFragment.newInstance(this.selected.get(position)); 
    } 

    @Override 
    public int getCount() { 
     return this.selected.size(); 
    } 
} 
} 

ExerciseFragment.java

public class ExerciseFragment extends Fragment { 

public ExerciseFragment() {} // Required empty public constructor 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    View rootView = inflater.inflate(
      R.layout.fragment_exercise_page, container, false); 

    // Change the header to the category 
    TextView tv = rootView.findViewById(R.id.textView_header); 
    tv.setText(getArguments().getString("CAT")); 

    return rootView; 
} 

public static ExerciseFragment newInstance(String category) { 
    Bundle args = new Bundle(); 
    args.putString("CAT", category); 

    ExerciseFragment exerciseFragment = new ExerciseFragment(); 
    exerciseFragment.setArguments(args); 

    return exerciseFragment; 
} 

} 

LogCat

java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.util.SparseArray.get(int)' on a null object reference 
at android.support.v4.app.FragmentManagerImpl.getFragment(FragmentManager.java:902) 
at android.support.v4.app.FragmentStatePagerAdapter.restoreState(FragmentStatePagerAdapter.java:216) 
at android.support.v4.view.ViewPager.onRestoreInstanceState(ViewPager.java:1453) 
at android.view.View.dispatchRestoreInstanceState(View.java:16886) 
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3470) 
at android.view.ViewGroup.dispatchRestoreInstanceState(ViewGroup.java:3476) 
at android.view.View.restoreHierarchyState(View.java:16864) 
at android.support.v4.app.Fragment.restoreViewState(Fragment.java:500) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1445) 
at android.support.v4.app.FragmentManagerImpl.moveFragmentToExpectedState(FragmentManager.java:1740) 
at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1809) 
at android.support.v4.app.BackStackRecord.executeOps(BackStackRecord.java:799) 
at android.support.v4.app.FragmentManagerImpl.executeOps(FragmentManager.java:2580) 
at android.support.v4.app.FragmentManagerImpl.executeOpsTogether(FragmentManager.java:2367) 
at android.support.v4.app.FragmentManagerImpl.removeRedundantOperationsAndExecute(FragmentManager.java:2322) 
at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:2229) 
at android.support.v4.app.FragmentManagerImpl$1.run(FragmentManager.java:700) 
at android.os.Handler.handleCallback(Handler.java:751) 
at android.os.Handler.dispatchMessage(Handler.java:95) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6682) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520) 

は、問題は、私は新しいタブを選択すると、すべてが正常に動作することで、私は戻って前のタブ、全アプリのクラッシュに行くときに、新しいフラグメントはしかし、追加されます。 ViewPagerがどのようにフラグメントを復元しているのかという問題だと思いますが、私はそれを修正する手がかりがありません。私はFragmentStatePagerAdapterFragmentPagerAdapterに置き換えました。問題は解決しません。しかし、私は多くのページ(20以上)を使用するので、前者を使用する必要があります。私はそれが中断した断片を保持するためにCategoryFragmentが必要です。何か案は?

+0

方法は、次にとして残りますか? – Juan

+0

@JuanエラーのLogCatを追加しました。 – qND

答えて

1

SupportFragmentManagerで問題が見つかりました。最初の要素がnullで、その結果、NullPointerExceptionが発生しています。

コミットする前にft.addToBackStack(null);を追加すると、その問題は解消されます。あなたがcreashのスタックトレースを追加でき

// Replace the fragment corresponding to the category 
    private void replaceFragment(int position) { 
     FragmentTransaction ft = fm.beginTransaction(); 
     ft.replace(R.id.fragment_category_container, this.categories.get(position)); 
     ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
     ft.addToBackStack(null); 
     ft.commit(); 
    } 
+0

ありがとうございましたが、私はViewPagerでTabLayoutを設定することに切り替えました。 – qND

+0

答えがあなたを助けてくれたら、それを受け入れてください:)。 – Juan

関連する問題