Первый фрагмент остается в фоновом режиме после перехода

#android #android-fragments #android-recyclerview

#java #Android #xml #android-фрагменты

Вопрос:

В настоящее время я пытаюсь создать приложение с заставкой, экраном входа в систему и экраном регистрации.

Единственный способ достичь именно того, что мне нужно, — это использовать фрагменты. Хотя, когда я пытаюсь перейти от заставки к фрагменту входа, текстовое представление, которое было частью заставки, остается. То же самое происходит после перехода от фрагмента входа к фрагменту регистра, а также от фрагмента регистра обратно к фрагменту входа. Важно отметить, что при переходе между login и register или между register и login проблем не возникает — за исключением того факта, что текст редактирования остается там.

Мой MainActivity.java

 public class StartActivity extends AppCompatActivity {

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

    @Override
    public void onBackPressed(){
        Toast.makeText(getApplicationContext(), "Back button is disabled", Toast.LENGTH_SHORT).show();
    }
}
  

Мой макет для MainActivity

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StartActivity"
    android:background="@mipmap/background">

    <fragment
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@ id/viewpagerstart"
        android:layout_centerInParent="true"
        android:name="com.example.distributedsystemsui.SplashFragment">

    </fragment>
</RelativeLayout>
  

В SplashScreen.java

 public class SplashFragment extends Fragment {
    LinearLayout linearLayout;

    @Nullable
    @Override
    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_splash, container, false);
        linearLayout = (LinearLayout) view.findViewById(R.id.f_linearsplash);
        Animation animation_fadein = AnimationUtils.loadAnimation((StartActivity)getActivity(), R.anim.fade_in);
        linearLayout.startAnimation(animation_fadein);
        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            public void run() {
                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.setCustomAnimations(R.anim.slide_enter_left, R.anim.slide_exit_left,
                        R.anim.slide_enter_right, R.anim.slide_exit_right);
                LoginFragment loginFragment = LoginFragment.newInstance();
                ft.replace(R.id.viewpagerstart, loginFragment);
                ft.commit();
            }
        }, 3000);
        return view;

    }
}

  

И макет для SplashScreen фрагмента.

 <?xml version="1.0" encoding="utf-8"?>
<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=".LoginFragment"
    android:background="@color/Tranparent"
    android:id="@ id/frame_splash">

    <LinearLayout
        android:id="@ id/f_linearsplash"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <ImageView
            android:id="@ id/f_splashlogo"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="70dp"
            android:background="#FFFFFF"/>

        <TextView
            android:id="@ id/f_splashtext"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="100dp"
            android:background="#FFFFFF"/>
    </LinearLayout>
</FrameLayout>
  

Все мои поиски ни к чему не привели.

Я могу только предположить, что либо нижеприведенное, содержащееся в MainActivity.xml создает путаницу (которую я пытался изменить, но безуспешно).:

 android:name="com.example.distributedsystemsui.SplashFragment"
  

или что я делаю ошибку в SplashScreen.java том, что я не могу найти, хотя я пытался более 5 часов заставить его работать.

Ответ №1:

Проблема в том, что вы не можете заменить фрагменты, добавленные с помощью <fragment> тега.

Вместо этого вы должны либо:

1) Переключитесь на FragmentContainerView , который был добавлен во фрагменте 1.2.0 . Он не страдает от той же проблемы, <fragment> что и тег, и позволяет выполнять replace операции без проблем:

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StartActivity"
    android:background="@mipmap/background">

    <androidx.fragment.app.FragmentContainerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@ id/viewpagerstart"
        android:layout_centerInParent="true"
        android:name="com.example.distributedsystemsui.SplashFragment">

    </androidx.fragment.app.FragmentContainerView>
</RelativeLayout>
  

2) Используйте a FrameLayout в своем макете и вручную добавьте SplashFragment в свою активность (это, по сути, то, что FragmentContainerView вам нужно):

 <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".StartActivity"
    android:background="@mipmap/background">

    <FrameLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@ id/viewpagerstart"
        android:layout_centerInParent="true">

    </FrameLayout>
</RelativeLayout>
  

это означает, что вам нужно добавить фрагмент SplashFragment вручную:

 @Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_start);
    if (savedInstanceState == null) {
        getSupportFragmentManager().beginTransaction()
            .add(R.id.viewpagerstart, new SplashFragment())
            .commit()
    }
}
  

Комментарии:

1. FragmentContainerView выполнил эту работу за меня. Я искал ответ на этот вопрос в течение нескольких дней. Большое вам спасибо

Ответ №2:

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

 public class StartActivity extends AppCompatActivity {

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

    public void goToLoginFragment() {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.slide_enter_left, R.anim.slide_exit_left,
                R.anim.slide_enter_right, R.anim.slide_exit_right);
        LoginFragment loginFragment = LoginFragment.newInstance();
        ft.replace(R.id.viewpagerstart, loginFragment);
        ft.commit();
    }

    public void goToRegisterFragment() {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        ft.setCustomAnimations(R.anim.slide_enter_left, R.anim.slide_exit_left,
                R.anim.slide_enter_right, R.anim.slide_exit_right);
        LoginFragment registerFragment = RegisterFragment.newInstance();
        ft.replace(R.id.viewpagerstart, registerFragment);
        ft.commit();
    }

    @Override
    public void onBackPressed(){
        Toast.makeText(getApplicationContext(), "Back button is disabled", Toast.LENGTH_SHORT).show();
    }
}
  

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

 Handler handler = new Handler();
handler.postDelayed(new Runnable() {
    public void run() {
        ((MainActivity) getActivity()).goToLoginFragment();
    }
}, 3000);
  

Я надеюсь, что это решит проблему.

Комментарии:

1. На самом деле это не решило проблему, хотя это было полезно в качестве хорошей практики, большое спасибо (также за редактирование, которое улучшило вопрос)!

2. да, я пропустил fragment часть. Ну, на это указал @ianhanniballake

3. Действительно, еще раз спасибо за помощь (не совсем уверен, что если мы закроем сообщение после ответа на них, это произойдет?)

4. Вы должны сохранить этот пост. Чтобы другие разработчики, такие как мы, могли действительно увидеть ваш пост и также могли получить помощь в решении своих проблем.