2017-02-02 4 views
-1

Я пишу простое приложение для изучения Java, в частности, как управлять транзакциями фрагментов.Андроид сбой во время замены фрагмента действия

Приложение имеет одну MainActivity и три фрагмента (FragmentDefault, добавлено к MainActivity по умолчанию, а фрагменты - один и два, которые можно добавить на кнопку щелчка в MainActivity).

Мое приложение может обрабатывать транзакцию фрагмента, но падает во время второго, независимо от порядка транзакций.

Файл MainActivity.java выглядит следующим образом:

package com.example.connor.fragmenttestapp; 
 

 
import android.content.SharedPreferences; 
 
import android.support.v4.app.FragmentTransaction; 
 
import android.support.v7.app.AppCompatActivity; 
 
import android.os.Bundle; 
 
import android.view.View; 
 

 
public class MainActivity extends AppCompatActivity { 
 
    FragmentDefault fragDefault = new FragmentDefault(); 
 
    Fragment1 frag1 = new Fragment1(); 
 
    Fragment2 frag2 = new Fragment2(); 
 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
 

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

 
     if (savedInstanceState == null) { 
 
      getSupportFragmentManager() 
 
        .beginTransaction() 
 
        .add(R.id.fragment_container, fragDefault) 
 
        .commit(); 
 
     } 
 
    } 
 

 
    public void openFrag(View view) { 
 
    transaction.replace(R.id.fragment_container, frag1); 
 
     transaction.commit(); 
 
     transaction.addToBackStack(null); 
 

 
    } 
 

 
    public void openFrag2(View view) { 
 
    transaction.replace(R.id.fragment_container, frag2); 
 
     transaction.commit(); 
 
     transaction.addToBackStack(null); 
 
    } 
 
}

с .XML файла:

package com.example.connor.fragmenttestapp; 
 

 
import android.content.SharedPreferences; 
 
import android.support.v4.app.FragmentTransaction; 
 
import android.support.v7.app.AppCompatActivity; 
 
import android.os.Bundle; 
 
import android.view.View; 
 

 
public class MainActivity extends AppCompatActivity { 
 
    FragmentDefault fragDefault = new FragmentDefault(); 
 
    Fragment1 frag1 = new Fragment1(); 
 
    Fragment2 frag2 = new Fragment2(); 
 
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); 
 

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

 
     if (savedInstanceState == null) { 
 
      getSupportFragmentManager() 
 
        .beginTransaction() 
 
        .add(R.id.fragment_container, fragDefault) 
 
        .commit(); 
 
     } 
 
    } 
 

 
    public void openFrag(View view) { 
 
    transaction.replace(R.id.fragment_container, frag1); 
 
     transaction.commit(); 
 
     transaction.addToBackStack(null); 
 

 
    } 
 

 
    public void openFrag2(View view) { 
 
    transaction.replace(R.id.fragment_container, frag2); 
 
     transaction.commit(); 
 
     transaction.addToBackStack(null); 
 
    } 
 
}

Мои три фрагмента файлов по существу идентичны с файлов Java:

package com.example.connor.fragmenttestapp; 
 

 
import android.content.Context; 
 
import android.content.SharedPreferences; 
 
import android.net.Uri; 
 
import android.os.Bundle; 
 
import android.support.v4.app.Fragment; 
 
import android.view.LayoutInflater; 
 
import android.view.View; 
 
import android.view.ViewGroup; 
 

 

 
public class Fragment1 extends Fragment { 
 
    @Override 
 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
 
          Bundle savedInstanceState) { 
 
     //Inflate the layout for this fragment 
 
     return inflater.inflate(R.layout.fragment_fragment1, container, false); 
 
    } 
 

 
    @Override 
 
    public void onAttach(Context context) { 
 
     super.onAttach(context); 
 
    } 
 
}

и файлы .xml:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 
 
    xmlns:tools="http://schemas.android.com/tools" 
 
    android:layout_width="match_parent" 
 
    android:layout_height="match_parent" 
 
    tools:context="com.example.connor.fragmenttestapp.Fragment1"> 
 

 
    <TextView 
 
     android:layout_width="match_parent" 
 
     android:layout_height="match_parent" 
 
     android:gravity="center" 
 
     android:text="@string/frag1_text" 
 
     android:id="@+id/textView" /> 
 

 

 
</FrameLayout>

Файл LogCat для этой ошибки показывает:

02-01 21: 01: 51,608 15413-15413/com.example.connor.fragmenttestapp Е/AndroidRuntime: неустранимый: Основной процесс: com.example.connor.fragmenttestapp, ПИД: 15413 java.lang.IllegalStateException : Не удалось выполнить метод для android: onClick на android.support.v7.app.AppCompatViewInflater $ DeclaredOnClickListener.onClick (AppCompatViewInflater.java:293) на android.view.View.performClick (View.java:5702) на android .widget.TextView.performClick (TextView.java:10896) на android.view.View $ PerformClick.run (View.java:22546) на android.os.Handler. handleCallback (Handler.java:739) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:158) на android.app.ActivityThread.main (ActivityThread.java:7224) at java.lang.reflect.Method.invoke (собственный метод) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:1230) at com.android.internal .os.ZygoteInit.main (ZygoteInit.java:1120) Вызвано: java.lang.reflect.InvocationTargetException в java.lang.reflect.Method.invoke (собственный метод) на android .support.v7.app.AppCompatViewInflater $ DeclaredOnClickListener.onClick (AppCompatViewInflater.java:288) at android.view.View.performClick (View.java: 5702) на android.widget.TextView.performClick (TextView.java:10896) на android.view.View $ PerformClick.run (View.java:22546) на android.os.Handler.handleCallback (Handler. java: 739) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:158) на android.app.ActivityThread.main (ActivityThread.java: 7224) at java.lang.reflect.Method.invoke (собственный метод) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:1230) at com.andro id.internal.os.ZygoteInit.main (ZygoteInit.java:1120) Вызвано: java.lang.IllegalStateException: commit уже вызвал на android.support.v4.app.BackStackRecord.commitInternal (BackStackRecord.java:630) на android.support.v4.app.BackStackRecord.commit (BackStackRecord.java:603) на com.example.connor.fragmenttestapp.MainActivity.openFrag2 (MainActivity.java:37) на java.lang.reflect.Method.invoke (Нативный метод) на android.support.v7.app.AppCompatViewInflater $ DeclaredOnClickListener.onClick (AppCompatViewInflater.java:288) на android.view.View.performClick (View.java:5702) на android.widget.TextView.performClick (TextView.java:10896) на android.view.View $ PerformClick.run (View.java:22546) на android.os.Handler.handleCallback (Handler.java:739) на android.os.Handler.dispatchMessage (Handler.java:95) на android.os.Looper.loop (Looper.java:158) на android.app.ActivityThread.main (ActivityThread.java:7224) на java .lang.reflect.Method.invoke (собственный метод) at com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run (ZygoteInit.java:1230) at com.android.internal.os.ZygoteInit.main (ZygoteInit. Java: 11 20)

Что вызывает эту ошибку и как я могу исправить код, чтобы избежать этого?

+0

Вы какой-то образом вызов совершать дважды. – Mike

+0

Пожалуйста, обратитесь к нам за помощью по написанию хороших вопросов/отладки, таких как: http://stackoverflow.com/help/mcve – nhouser9

+0

Вы используете то же самое «FragmentTransaction» во всем мире. Не делай этого. Просто вызовите 'beginTransaction()' каждый раз, когда вам это нужно. И переместите вызовы 'addToBackStack()' перед вызовами 'commit()'. –

ответ

0

Вы должны начать транзакцию каждый раз, вместо того, чтобы создать только один.

У вас может быть один FragmentManager, но каждый раз нужно начинать переход.

package com.example.connor.fragmenttestapp; 
 

 
import android.content.SharedPreferences; 
 
import android.support.v4.app.FragmentTransaction; 
 
import android.support.v7.app.AppCompatActivity; 
 
import android.os.Bundle; 
 
import android.view.View; 
 

 
public class MainActivity extends AppCompatActivity { 
 
    FragmentDefault fragDefault = new FragmentDefault(); 
 
    Fragment1 frag1 = new Fragment1(); 
 
    Fragment2 frag2 = new Fragment2(); 
 
    FragmentManager fm; 
 

 
    @Override 
 
    protected void onCreate(Bundle savedInstanceState) { 
 
     super.onCreate(savedInstanceState); 
 
     setContentView(R.layout.activity_main); 
 
     fm = = getSupportFragmentManager(); 
 
     if (savedInstanceState == null) { 
 
      fm.beginTransaction() 
 
        .add(R.id.fragment_container, fragDefault) 
 
        .commit(); 
 
     } 
 
    } 
 

 
    public void openFrag(View view) { 
 
    fm.beginTransition().replace(R.id.fragment_container, frag1) 
 
     .addToBackStack(null).commit(); 
 

 
    } 
 

 
    public void openFrag2(View view) { 
 
    fm.beginTransition().replace(R.id.fragment_container, frag2); 
 
     .addToBackStack(null).commit(); 
 
    } 
 
}

0

создайте это каждый раз, когда вы хотите совершить транзакцию. transaction = getSupportFragmentManager(). BeginTransaction();

1

Вы можете использовать эти две функции

public void openNoHistoryFragment(Fragment fragment) { 
      FragmentTransaction ft = getActivity().getSupportFragmentManager() 
        .beginTransaction(); 
      ft.replace(R.id.container, 
        fragment); 
      ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN); 
      ft.commitAllowingStateLoss(); 
     } 

     public void openFragment(Fragment fragment) { 
      FragmentManager fragmentManager = getActivity().getSupportFragmentManager(); 

      FragmentTransaction transaction = fragmentManager.beginTransaction(); 
//   transaction.setCustomAnimations(R.anim.enter, R.anim.exit, R.anim.pop_enter, R.anim.pop_exit); 

      transaction.replace(R.id.container, fragment); 
      transaction.addToBackStack(null); 
      transaction.commit(); 
     } 
Смежные вопросы