Хорошо, у вас есть пара вопросов, но, пожалуй, лучше, если я просто предоставлю вам подробный пошаговый отчет. Итак, начнем с самого начала.
Итак, сначала выпуск
Вы ссылаетесь не на ту память. Сначала вы помещаете фрагмент в свой XML, затем создаете новый экземпляр, так что это все равно, что налить чашку кофе, затем выпить из новой пустой чашки и спросить, почему кофе там нет.
Теперь для решения.
Сначала ваша MainActivity (или родительская активность фрагмента) ДОЛЖНА содержать элемент фрагмента, который вы пытаетесь включить. У вас есть несколько вариантов сделать это. Начнем с самого простого способа, предполагая, что это статический фрагмент, который не будет заменен.
ВАРИАНТ 1 (Фиксированный фрагмент)
<ParentActivityLayoutOfYourChoice>
<fragment
android:name="com.yourpath.FooFragment"
android:id="@+id/fooFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ParentActivityLayoutOfYourChoice>
Тогда в Activity вы просто создадите переменную-член и получите к ней доступ:
//lateinit only if you guarantee it will be there in the oncreate
private lateinit var fooFragment: FooFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
fooFragment = findViewById(R.id.fooFragment)
}
fun btnSignIn_onClick(){
//onSuccess
fooFragment.isSignedIn(true)
}
ВАРИАНТ 2 (динамические фрагменты)
<ParentActivityLayoutOfYourChoice>
<FrameLayout
android:id="@+id/fragPlaceholder"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</ParentActivityLayoutOfYourChoice>
Тогда, конечно, вы можете создать Фрагмент в вашем onCreate или соответствующем месте (например, фрагменты переключения ящиков) и заменить его в заполнителе.
Пример:
// Inside MainActivity (или родительское действие)
//lazy will new it up the first time you use it.
private val mFooFragment by lazy {
FooFragment()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
swapFragment(mFooFragment) //will auto new the fragment with lazy
}
//Let's start simple before I show you thorough
fun swapFragment(fragment: Fragment){
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()
fragmentTransaction.replace(R.id.fragPlaceholder, fragment)
fragmentTransaction.commit() //puts the fragment into the placeholder
}
fun btnSignIn_onClick(){
//onSuccess
mFooFragment.isSignedIn(true)
}
* Теперь, прежде чем мы пойдем дальше, я чувствую, что важно сказать вам, что, если вы меняете фрагменты динамически, это НАМНОГО больше. Вы должны обрабатывать пакет, вы должны знать, скрываете ли вы, показываете, заменяете и т. Д. Есть много способов обработать транзакцию. Изменяя свой фрагмент, вы должны решить, скрывать ли вы или удаляете. Когда вы вернете их обратно, это повлияет на жизненный цикл onResume против onCreate, поэтому управляйте им с умом.
Я создал простой метод swapFragment, который я использую почти во всех своих проектах в BaseActivity. Я поделюсь этим сейчас, чтобы быть тщательным.
ПРИМЕР ХРАНЕНИЯ ВЫБРАННОГО ФРАГМЕНТА И КОНТРОЛЯ ЗАМЕНЫ ФРАГМЕНТОВ, ДИНАМИЧЕСКИ В ОСНОВНОЙ ДЕЯТЕЛЬНОСТИ
private var mSelectedFragment: BaseFragment? = null
protected fun swapFragment(fragment: BaseFragment, @Nullable bundle: Bundle?, hideCurrentFrag: Boolean = false) {
if (fragment.isVisible) {
A35Log.e(mClassTag, "swapFragment called on already visible fragment")
return
}
A35Log.v(mClassTag, "swapFragment( ${fragment.javaClass.simpleName} )")
val currentFragBundle = fragment.arguments
if (currentFragBundle == null && bundle != null) {
fragment.arguments = bundle
A35Log.v(mClassTag, "current bundle is null, so setting new bundle passed in")
} else if (bundle != null) {
fragment.arguments?.putAll(bundle)
A35Log.v(mClassTag, "current fragment bundle was not null, so add new bundle to it")
}
//make sure no pending transactions are still floating and not complete
val fragmentManager = supportFragmentManager
fragmentManager.executePendingTransactions()
val fragmentTransaction = fragmentManager.beginTransaction()
//Make sure the requested fragment isn't already on the screen before adding it
if (fragment.isAdded) {
A35Log.v(mClassTag, "Fragment is already added")
if (fragment.isHidden) {
A35Log.v(mClassTag, "Fragment is hidden, so show it")
fragmentTransaction.show(fragment)
if(hideCurrentFrag) {
A35Log.v(mClassTag, "hideCurrentFlag = true, hiding current fragment $mSelectedFragment")
fragmentTransaction.hide(mSelectedFragment!!)
}else{
A35Log.v(mClassTag, "hideCurrentFlag = false, removing current fragment $mSelectedFragment")
fragmentTransaction.remove(mSelectedFragment!!)
}
}else{
A35Log.v(mClassTag, "Fragment is already visible")
}
}else if(mSelectedFragment == null){
A35Log.v(mClassTag,"mSelectedFragment = null, so replacing active fragment with new one ${fragment.javaClass.simpleName}")
fragmentTransaction.replace(R.id.fragPlaceholder, fragment)
}else{
A35Log.v(mClassTag, "Fragment is not added, so adding to the screen ${fragment.javaClass.simpleName}")
fragmentTransaction.add(R.id.fragPlaceholder, fragment)
if(hideCurrentFrag) {
A35Log.v(mClassTag, "hideCurrentFlag = true, hiding current fragment $mSelectedFragment")
fragmentTransaction.hide(mSelectedFragment!!)
}else{
A35Log.v(mClassTag, "hideCurrentFlag = false, removing current fragment $mSelectedFragment")
fragmentTransaction.remove(mSelectedFragment!!)
}
}
A35Log.v(mClassTag, "committing swap fragment transaction")
fragmentTransaction.commit()
A35Log.v(mClassTag, "mSelectedFragment = ${fragment.javaClass.simpleName}")
mSelectedFragment = fragment
}
Все примеры представлены в Kotlin, поскольку именно туда движется Android, и вы должны учиться на Kotlin, а не на Java, если вы этого еще не сделали. Если вы работаете с Java, вы можете вставить это в файл Java, и я думаю, что он предложит вам перевести его на Java.
Счастливого кодирования!