来自backstack的流行片段

时间:2014-12-23 13:10:54

标签: java android android-fragments runtime-error back-stack

我正在尝试创建一个包含两个片段的活动。活动开始时会显示一个片段,而当用户按下工具栏中的按钮时会显示另一个片段。

在第二个片段中,我想添加返回导航,当用户按下后退按钮时,第二个片段应该关闭,第一个片段应该出现。

但是我遇到了一些错误,我无法修复它们。

MainActivity.java

package com.geapps.notapp.activities;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.widget.Toolbar;
import android.view.MenuItem;
import android.view.View;

import com.geapps.notapp.R;
import com.geapps.notapp.fragments.MainFragment;
import com.geapps.notapp.fragments.NewNoteFragment;

public class MainActivity extends ActionBarActivity
{
    @Override
    protected void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) 
        {
            loadFragment(new MainFragment(), "Main");
        }

        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        toolbar.setTitle("Toolbar");
        toolbar.inflateMenu(R.menu.main);


        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() 
        {
            @Override
            public boolean onMenuItemClick(MenuItem menuItem) 
            {
                switch (menuItem.getItemId())
                {
                    case R.id.action_new:
                        loadFragment(new NewNoteFragment(), "New Note");
                        break;
                }

                return false;
            }
        });
    }

    public void loadFragment(Fragment fragment, String tag)
    {
        FragmentManager fragmentManager = getSupportFragmentManager();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

        fragmentTransaction.replace(R.id.main_container, fragment, tag);
        fragmentTransaction.addToBackStack(tag);
        fragmentTransaction.commit();
    }
} 

MainFragment.java

package com.geapps.notapp.fragments;

import java.util.ArrayList;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListView;

import com.geapps.notapp.R;
import com.geapps.notapp.adapters.NotesListAdapter;
import com.geapps.notapp.models.Note;

public class MainFragment extends Fragment 
{
    private View view;

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

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

        loadNotes();

        return view;
    }

    private void loadNotes()
    {
        ListView notesList = (ListView)view.findViewById(R.id.notes_list);

        ArrayList<Note> notes = new ArrayList<Note>();
        notes.add(new Note("Sunday homework", "1. Do math homework and then sleep"));
        notes.add(new Note("Job details", "Programming job especially iOS and Android development"));
        notes.add(new Note("Journal Part 1", "What am I going to do now? I have no way to run .. :("));

        NotesListAdapter notesListAdapter = new NotesListAdapter(this.getActivity(), notes);
        notesList.setAdapter(notesListAdapter);
    }
}

NewNoteFragment.java

package com.geapps.notapp.fragments;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

import com.geapps.notapp.R;

public class NewNoteFragment extends Fragment 
{
    private View view;

    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    }

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        view = inflater.inflate(R.layout.fragment_new_note, container, false);

        Toolbar toolbar = (Toolbar)getActivity().findViewById(R.id.toolbar);
        toolbar.getMenu().findItem(R.id.action_new).setVisible(false);

        toolbar.setNavigationIcon(R.drawable.ic_action_back);
        toolbar.setNavigationOnClickListener(new View.OnClickListener() 
        {
            @Override
            public void onClick(View v) 
            {
                FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
                fragmentManager.popBackStack("Main", FragmentManager.POP_BACK_STACK_INCLUSIVE);
            }
        });

        return view;
    }
}

以下是错误:

PathClassLoader(BaseDexClassLoader).findClass(String) line: 61  
PathClassLoader(ClassLoader).loadClass(String, boolean) line: 501   
PathClassLoader(ClassLoader).loadClass(String) line: 461    
BackStackRecord.getEnterTransition(Fragment, boolean) line: 1056    
BackStackRecord.configureTransitions(int, BackStackRecord$TransitionState, boolean, SparseArray, SparseArray) line: 1138    
BackStackRecord.beginTransition(SparseArray, SparseArray, boolean) line: 1029   
BackStackRecord.popFromBackStack(boolean, BackStackRecord$TransitionState, SparseArray, SparseArray) line: 883  
FragmentManagerImpl.popBackStackState(Handler, String, int, int) line: 1593 
FragmentManagerImpl$3.run() line: 509   
FragmentManagerImpl.execPendingActions() line: 1489 
FragmentManagerImpl$1.run() line: 454   
Handler.handleCallback(Message) line: 615   
FragmentActivity$1(Handler).dispatchMessage(Message) line: 92   
Looper.loop() line: 137 
ActivityThread.main(String[]) line: 4921    
Method.invokeNative(Object, Object[], Class, Class[], Class, int, boolean) line: not available [native method]  
Method.invoke(Object, Object...) line: 511  
ZygoteInit$MethodAndArgsCaller.run() line: 1038 
ZygoteInit.main(String[]) line: 805 
NativeStart.main(String[]) line: not available [native method]  

4 个答案:

答案 0 :(得分:3)

尝试使用此

getActivity().getSupportFragmentManager().popBackStack();

答案 1 :(得分:3)

让系统自行处理,而不是自定义。进行以下更改并尝试一下:

 public void loadFragment(Fragment fragment, String tag)
{
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

    fragmentTransaction.replace(R.id.main_container, fragment, tag);


//    fragmentTransaction.addToBackStack(tag);
    fragmentTransaction.addToBackStack(null);

    fragmentTransaction.commit();
}

 toolbar.setNavigationOnClickListener(new View.OnClickListener() 
    {
        @Override
        public void onClick(View v) 
        {
            FragmentManager fragmentManager = getActivity().getSupportFragmentManager();
   //         fragmentManager.popBackStack("Main", FragmentManager.POP_BACK_STACK_INCLUSIVE);
   //         fragmentManager.popBackStack(); 
              getActivity().onBackPressed(); 
        }
    });

答案 2 :(得分:0)

虽然很晚但是为了一个简单的方法尝试这个:

在提交之前将第一个片段添加到活动中时调用addToBackStack(null)。这将允许第二个片段的用户返回第一个Fragment by back按钮。

getFragmentManager().beginTransaction().replace(R.id.main_container, fragment).addToBackStack(null).commit();

现在在你的第二个片段中点击方法添加它以删除第二个片段并返回到第一个片段。

 getActivity().getFragmentManager().beginTransaction().remove(this).commit();
            //now recreating main activity to return to first fragment
                getActivity().recreate();

使用界面see android docs here

替代且更好的方法

答案 3 :(得分:0)

尝试这三种方法中的任何一个

1。#

getActivity().getSupportFragmentManager().popBackStack();

2。#

    getActivity().getSupportFragmentManager().popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);

3。#

getActivity().getSupportFragmentManager().popBackStackImmediate(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);