#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
часть. Ну, на это указал @ianhanniballake3. Действительно, еще раз спасибо за помощь (не совсем уверен, что если мы закроем сообщение после ответа на них, это произойдет?)
4. Вы должны сохранить этот пост. Чтобы другие разработчики, такие как мы, могли действительно увидеть ваш пост и также могли получить помощь в решении своих проблем.