[英]How to prevent activity to restart after changing its orientation
我是使用 KOTLIN 开发 android 的新手,我的活动包含如下图所示的片段(图 1),问题是每当我尝试将方向从纵向更改为横向时,活动都会返回到以前的活动(例如重新启动它)。
我尝试将android:configChanges="orientation|screenSize|keyboardHidden"
添加到我的AndroidManifest.xml
中,效果很好,但有人说不建议使用它。
你们能告诉我或向我展示解决此问题的最佳实践吗?
图片 1
代码
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = resources.getString(R.string.title_visit)
loadFragment(VisitFragment())
navigation_menu.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener)
}
private val mOnNavigationItemSelectedListener =
BottomNavigationView.OnNavigationItemSelectedListener { item ->
when (item.itemId) {
R.id.menu_visit -> {
loadFragment(VisitFragment())
title = resources.getString(R.string.title_visit)
return@OnNavigationItemSelectedListener true
}
R.id.menu_customer -> {
loadFragment(CustomerFragment())
title = resources.getString(R.string.title_customer)
return@OnNavigationItemSelectedListener true
}
R.id.menu_new_merchant -> {
loadFragment(NewMerchantFragment())
title = resources.getString(R.string.title_new_merchant)
return@OnNavigationItemSelectedListener true
}
R.id.menu_history -> {
loadFragment(HistoryFragment())
title = resources.getString(R.string.title_history)
return@OnNavigationItemSelectedListener true
}
R.id.menu_profile -> {
loadFragment(ProfileFragment())
title = resources.getString(R.string.title_profile)
return@OnNavigationItemSelectedListener true
}
}
false
}
private fun loadFragment(fragment: Fragment) {
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.container, fragment)
transaction.addToBackStack(null)
transaction.commit()
}
}
访问Fragment.kt
class VisitFragment : Fragment() {
private lateinit var viewPager: ViewPager
private lateinit var tabs: TabLayout
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_visit, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val fragmentAdapter = PagerAdapter(childFragmentManager)
pager.adapter = fragmentAdapter
tabs_main.setupWithViewPager(pager)
}
fun setNumber() {
val tabs = tabs_main.getTabAt(0)
val badge = tabs?.orCreateBadge
// Customize badge
badge?.number = 1
}
}
最新访问片段.kt
class LatestVisitFragment : Fragment() {
lateinit var latestVisitAdapter: LatestVisitAdapter
lateinit var recyclerView: RecyclerView
private val testinstance: ArrayList<TestResponseItem> = ArrayList()
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_latest_visit, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
loadDataLatestVisit()
}
private fun loadDataLatestVisit(){
ApiConfig().getService()
.getUsers()
.enqueue(object : Callback<List<TestResponseItem>> {
override fun onFailure(call: Call<List<TestResponseItem>>, t: Throwable) {
Toast.makeText(context, t.localizedMessage, Toast.LENGTH_SHORT).show()
}
override fun onResponse(
call: Call<List<TestResponseItem>>,
response: Response<List<TestResponseItem>>
) {
rv_latest_visit.adapter = LatestVisitAdapter(response.body())
}
})
}
}
最新访问适配器.kt
class LatestVisitAdapter(val data: List<TestResponseItem>?) :
RecyclerView.Adapter<LatestVisitAdapter.MyHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyHolder {
val v =
LayoutInflater.from(parent.context).inflate(R.layout.item_latest_visit, parent, false)
return MyHolder(v)
}
override fun getItemCount(): Int = data?.size ?: 0
override fun onBindViewHolder(holder: LatestVisitAdapter.MyHolder, position: Int) {
holder.bind(data?.get(position))
}
class MyHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bind(get: TestResponseItem?) {
itemView.txt_merchant_name.text = get?.name
itemView.txt_owner_name.text = get?.email
val address =
"${get?.address?.street},${get?.address?.city}, ${get?.address?.suite}, ${get?.address?.zipcode}"
itemView.txt_address.text = address
}
}
}
确实不建议在配置更改时阻止活动重启。
推荐的方法是保存和恢复 UI state或使用 ViewModel 。 其中任何一个都可以解决您的问题,但最好使用 ViewModel 方法。
在活动开始之前,但在配置更改发出信号之后,如果您要保存活动 state,则覆盖Activity.onSaveInstanceState(Bundle)
,如果要保存片段 state,则覆盖 `Fragment.onSaveInstanceState(Bundle)。
override fun onSaveInstanceState(outState: Bundle?) {
// Save your data into outState data bundle. And then make sure to
// call the super method.
super.onSaveInstanceState(outState)
}
由于配置更改而重新启动活动后,恢复以前保存的数据并将其应用到 UI。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ... inflate layout, etc...
if (savedInstanceState != null) {
// If savedInstanceState is not null, that means this activity is restoring from
// config changes. All your saved data in onSaveInstanceState() should be accessible
// from savedInstanceState bundle.
// ... restore values from savedInstanceState and apply to your views ...
} else {
// Initialize vie
}
}
这种方法是 Google 作为 Android Jetpack 库的一部分引入的相对较新的方法。 您的数据不会覆盖onSaveInstanceState(Bundle) and checking
null for null, your data is persisted inside a
ViewModel` 中,并且不会因配置更改而保留。
在ViewModel
中初始化您的数据并从您的活动或片段中访问它们。
class MyViewModel : ViewModel() {
var myList: List<User> = emptyList()
var currentTabIndex: Int = 0
init {
// Initialize your data here...
}
}
class MyFragment : Fragment() {
private val model by viewModels<MyViewModel>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// ... inflate layout, etc...
viewPager.setCurrentItem(model.currentTabIndex, false)
// Fetch the values from `ViewModel` and apply to your fragment.
}
}
ViewModel
为了更好地使用ViewModel
,最好从官方综合指南中学习。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.