2017-02-07 5 views
0

Я изучаю использование фрагментов, и я встречал некоторые проблемы с заменой и удалением методов. Вот мой класс активности:Android, фрагменты: проблемы с заменой и удалением методов

public class MainActivity extends AppCompatActivity implements BlankFragment.OnFragmentInteractionListener { 
private BlankFragment fragment1; 
private BlankFragment fragment2; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    FragmentManager fragmentManager = getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 
    fragment1 = BlankFragment.newInstance("Fragment 1",""); 
    fragmentTransaction.add(R.id.linearLayout,fragment1); 
    fragmentTransaction.commit(); 

} 
public void onClick(View arg0) 
{ 
    FragmentManager fragmentManager = getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 

    switch (arg0.getId()) 
    { 

     case R.id.button: 
      fragment2 = BlankFragment.newInstance("Fragment 2", ""); 
      fragmentTransaction.add(R.id.linearLayout, fragment2); 
      fragmentTransaction.commit(); 
      break; 

     case R.id.button2: 
      Toast.makeText(this,"REMOVE",Toast.LENGTH_SHORT).show(); 
      if(fragment2!=null) 
      { 
       fragmentTransaction.remove(fragment2); 
       fragmentTransaction.commit(); 
      } 
      break; 

     case R.id.button3: 
      fragmentTransaction.replace(R.id.linearLayout,fragment2); 
      fragmentTransaction.commit(); 
      break; 

    } 
} 

public void onFragmentInteraction(Uri uri) 
{ 

} 
} 

Вот фрагмент Класс:

public class BlankFragment extends Fragment { 
// TODO: Rename parameter arguments, choose names that match 
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER 
private static final String ARG_PARAM1 = "param1"; 
private static final String ARG_PARAM2 = "param2"; 

// TODO: Rename and change types of parameters 
private String mParam1; 
private String mParam2; 
private OnFragmentInteractionListener mListener; 

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

/** 
* Use this factory method to create a new instance of 
* this fragment using the provided parameters. 
* 
* @param param1 Parameter 1. 
* @param param2 Parameter 2. 
* @return A new instance of fragment BlankFragment. 
*/ 
// TODO: Rename and change types and number of parameters 
public static BlankFragment newInstance(String param1, String param2) { 
    BlankFragment fragment = new BlankFragment(); 
    Bundle args = new Bundle(); 
    args.putString(ARG_PARAM1, param1); 
    args.putString(ARG_PARAM2, param2); 
    fragment.setArguments(args); 
    return fragment; 
} 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    if (getArguments() != null) { 
     mParam1 = getArguments().getString(ARG_PARAM1); 
     mParam2 = getArguments().getString(ARG_PARAM2); 
    } 
} 

@Override 
public View onCreateView(LayoutInflater inflater, ViewGroup container, 
         Bundle savedInstanceState) { 
    // Inflate the layout for this fragment 
    View rootView = inflater.inflate(R.layout.fragment_blank, container, false); 
    TextView textView = ((TextView) rootView.findViewById(R.id.textView)); 
    textView.setText(mParam1); 
    return rootView; 
} 

// TODO: Rename method, update argument and hook method into UI event 
public void onButtonPressed(Uri uri) { 
    if (mListener != null) { 
     mListener.onFragmentInteraction(uri); 
    } 
} 

@Override 
public void onAttach(Context context) { 
    super.onAttach(context); 
    if (context instanceof OnFragmentInteractionListener) { 
     mListener = (OnFragmentInteractionListener) context; 
    } else { 
     throw new RuntimeException(context.toString() 
       + " must implement OnFragmentInteractionListener"); 
    } 
} 

@Override 
public void onDetach() { 
    super.onDetach(); 
    mListener = null; 
} 

/** 
* This interface must be implemented by activities that contain this 
* fragment to allow an interaction in this fragment to be communicated 
* to the activity and potentially other fragments contained in that 
* activity. 
* <p> 
* See the Android Training lesson <a href= 
* "http://developer.android.com/training/basics/fragments/communicating.html" 
* >Communicating with Other Fragments</a> for more information. 
*/ 
public interface OnFragmentInteractionListener { 
    // TODO: Update argument type and name 
    void onFragmentInteraction(Uri uri); 
} 
} 

Вот манифеста:

<?xml version="1.0" encoding="utf-8"?> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 

      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

</application> 

Ну, у меня есть 2 фрагмента. Когда я нажимаю первую кнопку, я хочу добавить второй фрагмент. Если я нажму на эту кнопку 10 раз, будет ли 11 фрагментов в заднем стеке (10 фрагментов номер 2 и 1 номер 1)? Или только два фрагмента? Когда я нажимаю вторую кнопку, я удаляю фрагмент номер 2, если есть, конечно. Но если я нажму два или более раза на первую кнопку, если я нажму 200 секунд второй, второй фрагмент останется ... почему? Когда я нажимаю на третью кнопку, я хочу заменить второй фрагмент на предыдущий фрагмент. Если я нажму два или более раза на первую кнопку, если я нажму на третью кнопку, а затем вторую кнопку, второй фрагмент не останется ... почему? Если открыть приложение и я нажимаю на третью кнопку или я нажимаю первую вторую кнопку, а затем третий, приложение падает

Вот LogCat

02-07 21:33:31.040 17090-17090/com.example.utente.fragment E/AndroidRuntime: FATAL EXCEPTION: main 
                     Process: com.example.utente.fragment, PID: 17090 
                     java.lang.IllegalStateException: Could not execute method for android:onClick 
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:293) 
                      at android.view.View.performClick(View.java:5610) 
                      at android.view.View$PerformClick.run(View.java:22265) 
                      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:6077) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
                      Caused by: java.lang.reflect.InvocationTargetException 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                      at android.view.View.performClick(View.java:5610)  
                      at android.view.View$PerformClick.run(View.java:22265)  
                      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:6077)  
                      at java.lang.reflect.Method.invoke(Native Method)  
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)  
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)  
                      Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Class java.lang.Object.getClass()' on a null object reference 
                      at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:380) 
                      at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:430) 
                      at android.support.v4.app.BackStackRecord.replace(BackStackRecord.java:421) 
                      at com.example.utente.fragment.MainActivity.onClick(MainActivity.java:50) 
                      at java.lang.reflect.Method.invoke(Native Method)  
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288)  
                      at android.view.View.performClick(View.java:5610)  
                      at android.view.View$PerformClick.run(View.java:22265)  
                      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:6077)  
                      at java.lang.reflect.Method.invoke(Native Method)  
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)  
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)  

Если я нажимаю на первую кнопку, а затем в-третьих, приложение не падает ... почему? Где ошибки? Кнопки не во фрагментах, но в деятельности

+0

вы не могли использовать onClick() в фрагменте – ste9206

+0

@ ste9206 кнопки не находятся в фрагментах, но в действии – Curio

+0

он дает вам эту ошибку: не удалось выполнить метод для android: onClick .. вы могли бы использовать .setOnClickListener() вместо этого, а также удалить onClick в макете xml – ste9206

ответ

1

Прежде всего, проверьте this post.

Well, I have 2 fragments. When I click the first button, I want to add the second fragment. If I click this button 10 times, will there be 11 fragments in the back stack (10 fragments number 2 and 1 number 1)? Or only two fragments?

Если вы хотите добавить транзакцию в стек обратно, добавить

fragmentTransaction.addToBackStack(null); 

, прежде чем совершить сделку. Затем вы можете использовать popBackStack() в FragmentManager.

When I click the second button, I remove the fragment number 2, if there is, of course. But if I click two or more times the first button, if I click 200 times the second button, the second fragment remains...why?

Это происходит потому, что при нажатии на первую кнопку, вы установите FRAGMENT2 новый экземпляр фрагмента, даже если она уже есть один, и тем самым теряя ссылку на старую.

Каждый раз, когда вы нажимаете вторую кнопку после двухкратной нажатия первой кнопки, она будет пытаться удалить последний созданный фрагмент каждый раз. Поэтому он всегда будет показывать второй последний фрагмент, который вы создали, который всегда будет «Фрагмент 2».

When I click the third button, I want to replace the second fragment with the previous fragment. If I click two or more times the first button, if I click the third button and then the second button, the second fragment doesn't remain...why?

Метод replace() удалит все ранее добавленные фрагменты и добавит тот, который вы пытаетесь добавить. Когда вы нажмете третью кнопку, вы удалите все остальные фрагменты, которые у вас есть, и добавьте фрагмент2. Когда вы затем нажмете вторую кнопку, она удалит фрагмент2, а затем больше ничего не появится.

If I open the app and I click the third button or I click first the second button and then the third, the app crashes

Это потому, что если вы не нажмете первую кнопку, фрагмент2 будет пустым. Нажатие второй кнопки ничего не сделает, так как фрагмент2 равен нулю. Нажатие третьей кнопки будет пытаться добавить фрагмент2, который является нулевым, что указывает на ошибку.

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

+0

это нормально, но я не понял, почему метод remove не удаляет фрагмент, когда я нажимаю два раза или больше, первая кнопка – Curio

+1

Давайте скажем, когда вы начинаете приложения, вы начинаете с фрагмента n.1, который вы сохранили в переменной фрагмент1. Когда вы затем нажимаете первую кнопку, вы получаете фрагмент n.2, который сохраняется в фрагменте2. Затем вы нажмете его еще раз, а затем получите фрагмент n.3, который вы снова сохраните для фрагмента2. Когда вы нажимаете вторую кнопку, вы удаляете фрагмент n.3, а затем он показывает фрагмент n.2. Когда вы снова нажимаете вторую кнопку, она по-прежнему пытается удалить фрагмент n.3, потому что вы потеряли ссылку на фрагмент n.2, когда вы нажали первую кнопку во второй раз. – h3rmanj

+0

Я понял, спасибо большое – Curio

0

Удалить метод onClick(), вы могли бы сделать это первичный раз вы это сделать:

FragmentManager fragmentManager = getSupportFragmentManager(); 
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); 




    Button button = (Button)findViewById(R.id.button); 
    Button button2 = (Button)findViewById(R.id.button2); 
    Button button3 = (Button)findViewById(R.id.button3); 
    button.setOnClickListener(new View.OnClickListener() 
    { 
     @Override 
     public void onClick(View v) 
     { 
      fragment2 = BlankFragment.newInstance("Fragment 2", ""); 
      fragmentTransaction.add(R.id.linearLayout, fragment2); 
      fragmentTransaction.commit(); 
     } 
    }); 

    button2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) 
     { 
      Toast.makeText(this,"REMOVE",Toast.LENGTH_SHORT).show(); 
      if(fragment2!=null) 
      { 
       fragmentTransaction.remove(fragment2); 
       fragmentTransaction.commit(); 
      }  
     } 
    }); 

    button3.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) 
     { 
      fragmentTransaction.replace(R.id.linearLayout,fragment2); 
      fragmentTransaction.commit();  
     } 
    }); 
+0

это не работает, но теперь я знаю ошибки – Curio