我有一个带有4个片段的底部导航主页、以下、通知和配置文件,在backstack上的底部导航没有问题,但现在,例如,从配置文件片段,我跳转到一个名为edit_profile的片段,它不是底部导航的一部分,当按下返回时,我希望它应该返回到配置文件片段,但backstack将我从edit_profile直接跳转到主页片段
这是记录link
我最近将我的项目从java改为Kotlin,我是kotlin的初学者
我很喜欢Pinterest和Instagram的导航
注意:-所有这些代码都自动更改为Kotlin(一些更改是手动完成的),这个问题也是与java,而不是在迁移到kotlin后,另外,如果你想要更多的代码参考,请告诉我,我会更新问题
代码
主要活动.kt//底部导航
class MainActivity : AppCompatActivity() {
var bottomNavigationView: BottomNavigationView? = null
var integerDeque: Deque<Int> = ArrayDeque(3)
var flag = true
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_NO)
setContentView(R.layout.activity_main)
val window = this.window
window.statusBarColor = this.resources.getColor(R.color.black)
bottomNavigationView = findViewById(R.id.bottom_navigation_view)
integerDeque.push(R.id.nav_home)
loadFragments(Home_Fragment())
bottomNavigationView!!.selectedItemId = R.id.nav_home
bottomNavigationView!!.setOnNavigationItemSelectedListener(
BottomNavigationView.OnNavigationItemSelectedListener { item: MenuItem ->
val id = item.itemId
if (integerDeque.contains(id)) {
if (id == R.id.nav_home) {
integerDeque.size
if (flag) {
integerDeque.addFirst(R.id.nav_home)
flag = false
}
}
integerDeque.remove(id)
}
integerDeque.push(id)
loadFragments(getFragment(item.itemId))
false
}
)
}
@SuppressLint("NonConstantResourceId")
private fun getFragment(itemId: Int): Fragment {
when (itemId) {
R.id.nav_home -> {
bottomNavigationView!!.menu.getItem(0).isChecked = true
return Home_Fragment()
}
R.id.nav_following -> {
bottomNavigationView!!.menu.getItem(1).isChecked = true
return Following_Fragment()
}
R.id.nav_notification -> {
bottomNavigationView!!.menu.getItem(2).isChecked = true
return Notification_Fragment()
}
R.id.nav_profile -> {
bottomNavigationView!!.menu.getItem(3).isChecked = true
return Profile_Fragment()
}
}
bottomNavigationView!!.menu.getItem(0).isChecked = true
return Home_Fragment()
}
private fun loadFragments(fragment: Fragment?) {
if (fragment != null) {
supportFragmentManager.beginTransaction()
.replace(R.id.fragment_container, fragment, fragment.javaClass.simpleName)
.commit()
}
}
override fun onBackPressed() {
integerDeque.pop()
if (!integerDeque.isEmpty()) {
loadFragments(getFragment(integerDeque.peek()))
} else {
finish()
}
}
Edit_Profile.kt//我想从这个片段返回到最后一个片段,它应该是配置文件片段
class Edit_Profile : Fragment() {
private var profilePhoto: CircleImageView? = null
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val view = inflater.inflate(R.layout.fragment_edit_profile, container, false)
profilePhoto = view.findViewById(R.id.circleImageView)
initImageLoader()
setProfileImage()
val imageView = view.findViewById<ImageView>(R.id.backArrow)
imageView.setOnClickListener {
val newCase: Fragment = Profile_Fragment()
assert(fragmentManager != null)
val transaction = requireFragmentManager().beginTransaction()
transaction.replace(R.id.fragment_container, newCase)
transaction.addToBackStack(Profile_Fragment.toString())
transaction.commit()
}
return view
}
修改
将事务的一部分从Profile Fragment添加到Edit Profile
配置文件片段.kt
editProfileButton!!.setOnClickListener(View.OnClickListener { v: View? ->
val edit_profile: Fragment = Edit_Profile()
requireActivity().getSupportFragmentManager()
.beginTransaction()
.add(R.id.fragment_container, edit_profile,"TAG")
.addToBackStack("TAG")
.commit()
})
2条答案
按热度按时间idfiyjo81#
现在,您将通过
integerDeque
阵列管理后备堆栈。BottomNavigationView
片段;如果它还不存在,就将它的id添加到数组中。但是由于您在
bottomNavigationView.setOnItemSelectedListener
回调中推送了所有这些id;则x1M3 N1 x阵列仅包含x1M4 N1 x片段ID。因为
Edit_Profile
片段不是BottomNavigationView
片段的一部分,所以它不会被添加/弹出队列。相反,当你试图弹出后栈时,只要Edit_Profile
片段被显示;您在onBackPressed()
中管理的正常行为将继续,并且Profile_Fragment
id将从队列中弹出,使您返回到前面提到的示例中的片段(Home_Fragment
)。对此的一个小修正是考虑在处理
Edit_Profile
片段时向队列中添加一个id,以便将此id从队列中弹出,从而返回到Profile_Fragment
片段。您可以使用片段的id执行此操作,以确保它是唯一的:
这应该可以解决您的问题。
侧面提示:
BNV
上使用setOnItemSelectedListener
,而不是setOnNavigationItemSelectedListener
,因为后者已过时。setOnItemSelectedListener
回调返回true
而不是false
,因为这应该使用事件并将BNV
标记为选定。Edit_Profile
事务replace
中,片段不是将其与add
一起添加,因为已经消耗了容器;这样可以避免容器中的片段重叠。onBackPressed()
为单位;您可以将loadFragments(..)
替换为bottomNavigationView.selectedItemId = integerDeque.peek()
;重用相同的片段而不是重做事务可能更轻松。jxct1oxe2#
通常我遵循
的模式
我在主容器中添加HomeF,它包括所有底部导航标签,所有底部导航标签将在主容器中打开,而那些不是底部导航一部分的片段将在主容器中打开。我通常添加(不是替换)主容器中的所有片段并设置添加到后堆栈,以便如果用户从配置文件(home_container)添加到主容器中的某个内容,在回栈时,我们可以弹出顶部片段,用户将看到配置文件。