← Назад к вопросам

Можно ли при возвращении фрагмента применить apply и через аргументы передать данные?

2.0 Middle🔥 111 комментариев
#Архитектура и паттерны#Жизненный цикл и навигация

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI26 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Можно ли использовать apply и передать данные через аргументы при возвращении фрагмента?

Да, абсолютно! Это даже рекомендуемый подход в современной разработке Android.

1. Классический способ (неправильно)

// ❌ Старый способ: через конструктор
fun createFragment(name: String): MyFragment {
    return MyFragment(name)  // ❌ Не работает!
}

class MyFragment(val name: String) : Fragment() {
    // Проблема: при пересоздании Activity Fragment потеряет данные
}

Фрагменты могут быть пересоздифицированы системой, поэтому конструкторы с параметрами опасны.

2. Правильный способ: apply + arguments

companion object {
    fun newInstance(name: String, age: Int): MyFragment {
        return MyFragment().apply {
            arguments = bundleOf(
                "name" to name,
                "age" to age
            )
        }
    }
}

class MyFragment : Fragment() {
    private val name: String by lazy { arguments?.getString("name") ?: "" }
    private val age: Int by lazy { arguments?.getInt("age") ?: 0 }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        println("Имя: $name, Возраст: $age")
    }
}

// Использование
val fragment = MyFragment.newInstance("John", 30)
supportFragmentManager.beginTransaction()
    .replace(R.id.container, fragment)
    .commit()

3. Более красивый способ: extension функция

inline fun <reified T : Fragment> fragmentOf(vararg pairs: Pair<String, Any?>): T {
    return T::class.java.newInstance().apply {
        arguments = Bundle().apply {
            for ((key, value) in pairs) {
                when (value) {
                    is String -> putString(key, value)
                    is Int -> putInt(key, value)
                    is Boolean -> putBoolean(key, value)
                    // и т.д.
                }
            }
        }
    }
}

// Использование
val fragment = fragmentOf<MyFragment>(
    "name" to "John",
    "age" to 30
)

4. Современный способ: Fragment Arguments (Android 5.0+)

Используй bundleOf из androidx (самый чистый способ):

class MyFragment : Fragment(R.layout.fragment_my) {
    
    companion object {
        fun newInstance(name: String, age: Int): MyFragment {
            return MyFragment().apply {
                arguments = bundleOf(
                    "name" to name,
                    "age" to age
                )
            }
        }
    }
    
    private val viewModel: MyViewModel by viewModels()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        val name = arguments?.getString("name") ?: ""
        val age = arguments?.getInt("age") ?: 0
        
        println("$name is $age years old")
    }
}

5. С типобезопасностью: Typed Bundle (Android 12+)

data class MyArgs(
    val name: String,
    val age: Int
) : Parcelable  // Или serializable

class MyFragment : Fragment(R.layout.fragment_my) {
    
    companion object {
        fun newInstance(args: MyArgs): MyFragment {
            return MyFragment().apply {
                arguments = bundleOf(
                    "args" to args
                )
            }
        }
    }
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        val args = arguments?.getParcelable<MyArgs>("args")
        println(args?.name)
    }
}

6. Лучший вариант: FragmentArgs (navArgs pattern)

Если используешь Navigation Component:

class MyFragment : Fragment(R.layout.fragment_my) {
    
    private val args: MyFragmentArgs by navArgs()
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        println(args.name)
        println(args.age)
    }
}

// XML (navigation_graph.xml)
<fragment
    android:id="@+id/myFragment"
    android:name=".MyFragment"
    android:label="My Fragment">
    <argument
        android:name="name"
        app:type="string" />
    <argument
        android:name="age"
        app:type="integer" />
</fragment>

7. Полный пример: apply + arguments

class UserFragment : Fragment(R.layout.fragment_user) {
    
    companion object {
        private const val ARG_USER_ID = "user_id"
        private const val ARG_USER_NAME = "user_name"
        
        fun newInstance(userId: Int, userName: String): UserFragment {
            return UserFragment().apply {
                arguments = Bundle().apply {
                    putInt(ARG_USER_ID, userId)
                    putString(ARG_USER_NAME, userName)
                }
            }
        }
    }
    
    private val userId: Int
        get() = arguments?.getInt(ARG_USER_ID) ?: 0
    
    private val userName: String
        get() = arguments?.getString(ARG_USER_NAME) ?: ""
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        println("User: $userName (ID: $userId)")
    }
}

// Использование
val fragment = UserFragment.newInstance(123, "John")
supportFragmentManager.beginTransaction()
    .replace(R.id.container, fragment)
    .addToBackStack(null)
    .commit()

8. Почему именно apply + arguments?

Безопасность: Bundle сохраняется системой при пересоздании ✅ Простота: apply делает код более читаемым ✅ Рекомендуется Android: это стандартный подход ✅ Работает со всеми версиями: вплоть до API 15 ✅ Типизация: bundleOf автоматически определяет тип

9. Обработка null значений

companion object {
    fun newInstance(optional: String?): MyFragment {
        return MyFragment().apply {
            arguments = bundleOf(
                "optional" to optional
            )
        }
    }
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    
    val optional = arguments?.getString("optional")
    if (optional != null) {
        // Используем
    }
}

10. Альтернатива: SharedViewModel

Для более сложных данных используй ViewModel:

class SharedViewModel : ViewModel() {
    val userData = MutableLiveData<User>()
}

class MyFragment : Fragment() {
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        
        val viewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
        viewModel.userData.observe(viewLifecycleOwner) { user ->
            println(user.name)
        }
    }
}

Итог

Да, можно и нужно использовать apply + arguments ✅ Bundle автоматически сохраняется при пересоздании ✅ bundleOf() самый чистый способ в современном коде ✅ Companionobject.newInstance() — стандартный паттерн ✅ Для сложных данных рассмотри SharedViewModel ✅ Navigation Component — лучший вариант с navArgs()

Можно ли при возвращении фрагмента применить apply и через аргументы передать данные? | PrepBro