无论我尝试以何种方式更改其内容,TextView Id 都会继续调用 null
TextView Id keeps calling on null no matter what way I try to change its content
我有一个 TabLayout
,里面有 3 个片段。片段 0 包含详细信息,1 是描述,2 是位置。
但是无论我如何尝试在我的 carDetailsActivity
中调用片段 ID,或者我尝试将值从 activity 传递给片段,它都会继续调用 null 并给出以下结果:
选项卡片段
现在我尝试了多种方法,其中一种方法 Bundle
从 activity 到片段的文本值,但我仍然得到 null "IllegaleStateException"。 (据我所知,这是最好的选择)但它仍然没有用。
这就是我想要的样子(设计是阿拉伯语):
这是我的 Activity,我现在正在给他们打电话,但我只得到空字符串(必须给他们?因为如果我不这样做,应用程序会一直崩溃):
class CarDetailsActivity : BaseActivity() {
val TAG = "CarDetailsActivity"
override fun onCreate(savedInstanceState: Bundle?) {
val car = intent.extras!!.getParcelable<Car>(DETAILS_TRANSFER) as Car
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_car_details)
activateToolbar(true)
carPriceDetails?.text = car.price.toString()
carDate?.text = car.date
carCategory?.text = car.category
carModel?.text = car.brandModel
carYear?.text = car.modelYear
carKilometer?.text = car.kilometer.toString()
carGear?.text = car.gearType
carFuel?.text = car.fuelType
val fragmentAdapter = FragmentCarInfo(supportFragmentManager)
viewPager.adapter = fragmentAdapter
tabLayout.setupWithViewPager(viewPager)
carBrand.text = car.brand
carModel.text = car.brandModel
carYear.text = car.modelYear
Picasso.with(this).load(car.image)
.error(R.drawable.ic_cars)
.placeholder(R.drawable.ic_cars)
.into(carImage)
}
}
这是主要的 Fragment
,其中包含包含详细信息的布局:
class InfoFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_car_details_info, container, false)
}
}
我以前问过类似的问题,但不够清楚,所以我希望这是解决 post 我的问题的更好方法。
-编辑
我的 tabLayout viewPager 使用这个
class FragmentCarInfo (fm : FragmentManager) : FragmentPagerAdapter(fm){
override fun getItem(position: Int): Fragment {
return when (position) {
0-> {
InfoFragment()
}
1 -> {
AboutFragment()
}
else -> {
return LocationFragment()
}
}
}
override fun getCount(): Int {
return 3
}
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0-> "Details"
1-> "About"
else -> {
return "Locations"
}
}
}
}
您不应该将值分配给片段中的字段吗?
首先,我建议放弃旧的和讨厌的 TabLayout 并切换到新的 ViewPager2 而不是旧的 ViewPager。 UI明智的做法是,在 LinearLayout 或 ConstraintLayout 中创建自定义 3 个按钮,而不是 TabLayout。
现在,在您的情况下,我会将 ViewPager2 与 FragmentStateAdapter 一起使用,因为它旨在与 Fragment 配合使用,您可以根据需要创建任意数量的 Fragment。我什至有一个项目,其中我使用 FragmentStateAdapter 创建了 80 个片段。
其次,您的片段需要一个 newInstance 构造函数作为安全模式。如果您不使用它,您稍后可能会在您的应用程序中遇到一些异常,但除此之外,您还将使用该函数将数据传递给每个片段。
这是我的做法:
class FragmentStateAdapter(
fragmentManager: FragmentManager,
lifecycle: Lifecycle,
car: Car
) : FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int = 3
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> InfoFragment.newInstance(car)
1 -> AboutFragment.newInstance(car)
else -> LocationFragment.newInstance(car)
}
}
基本上,我将您的汽车对象(假设它是唯一需要到达片段的数据对象)作为参数传递给 FragmentStateAdapter,将 itemCount 锁定为 3,因为您有 3 个片段,然后返回每个片段的实例覆盖方法 createFragment() 中的片段。现在,创建实例函数:
class InfoFragment : Fragment() {
companion object {
private const val BUNDLE_KEY = "car_object"
fun newInstance(car: Car) = InfoFragment().apply {
arguments = Bundle().apply {
putParcelable<Car>(BUNDLE_KEY, car)
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_car_details_info, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val car = arguments.getParcelable<Car>(BUNDLE_KEY)
}
}
这就是将汽车对象放入片段中的方法。基本上在 newInstance() 函数中,您创建片段的新实例并通过 bundle 将数据传递给它。在您的 activity 中,这是您初始化适配器的方式:
val adapter = FragmentStateAdapter(supportFragmentManager, lifecycle, car)
现在,关于选项卡视图的替换,做一个像这样的自定义 LinearLayout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0">
<Button
android:id="@+id/button1"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.333"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="Details"
android:textAllCaps="true" />
<Button
android:id="@+id/button2"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.333"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="About"
android:textAllCaps="true" />
<Button
android:id="@+id/button3"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.333"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="Locations"
android:textAllCaps="true" />
然后根据自己的喜好设置按钮的初始颜色 android:background="#COLOR_OR_CHOICE"
在 activity 中,将三个按钮添加到按钮的 ArrayList 中,并在 viewPager2 上使用此侦听器:
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
// here, get the position of the viewPager2 and change the color of the current button using the arrayList index that matches the viewPager2 position.
})
然后,在每个按钮的点击侦听器上,执行 viewPager2.setCurrentItem(position_you_want_to_go_to, true),其中 true 是对平滑滚动的检查。
希望这对您有所帮助。
我有一个 TabLayout
,里面有 3 个片段。片段 0 包含详细信息,1 是描述,2 是位置。
但是无论我如何尝试在我的 carDetailsActivity
中调用片段 ID,或者我尝试将值从 activity 传递给片段,它都会继续调用 null 并给出以下结果:
选项卡片段
现在我尝试了多种方法,其中一种方法 Bundle
从 activity 到片段的文本值,但我仍然得到 null "IllegaleStateException"。 (据我所知,这是最好的选择)但它仍然没有用。
这就是我想要的样子(设计是阿拉伯语):
这是我的 Activity,我现在正在给他们打电话,但我只得到空字符串(必须给他们?因为如果我不这样做,应用程序会一直崩溃):
class CarDetailsActivity : BaseActivity() {
val TAG = "CarDetailsActivity"
override fun onCreate(savedInstanceState: Bundle?) {
val car = intent.extras!!.getParcelable<Car>(DETAILS_TRANSFER) as Car
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_car_details)
activateToolbar(true)
carPriceDetails?.text = car.price.toString()
carDate?.text = car.date
carCategory?.text = car.category
carModel?.text = car.brandModel
carYear?.text = car.modelYear
carKilometer?.text = car.kilometer.toString()
carGear?.text = car.gearType
carFuel?.text = car.fuelType
val fragmentAdapter = FragmentCarInfo(supportFragmentManager)
viewPager.adapter = fragmentAdapter
tabLayout.setupWithViewPager(viewPager)
carBrand.text = car.brand
carModel.text = car.brandModel
carYear.text = car.modelYear
Picasso.with(this).load(car.image)
.error(R.drawable.ic_cars)
.placeholder(R.drawable.ic_cars)
.into(carImage)
}
}
这是主要的 Fragment
,其中包含包含详细信息的布局:
class InfoFragment : Fragment() {
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_car_details_info, container, false)
}
}
我以前问过类似的问题,但不够清楚,所以我希望这是解决 post 我的问题的更好方法。
-编辑 我的 tabLayout viewPager 使用这个
class FragmentCarInfo (fm : FragmentManager) : FragmentPagerAdapter(fm){
override fun getItem(position: Int): Fragment {
return when (position) {
0-> {
InfoFragment()
}
1 -> {
AboutFragment()
}
else -> {
return LocationFragment()
}
}
}
override fun getCount(): Int {
return 3
}
override fun getPageTitle(position: Int): CharSequence? {
return when (position) {
0-> "Details"
1-> "About"
else -> {
return "Locations"
}
}
}
}
您不应该将值分配给片段中的字段吗?
首先,我建议放弃旧的和讨厌的 TabLayout 并切换到新的 ViewPager2 而不是旧的 ViewPager。 UI明智的做法是,在 LinearLayout 或 ConstraintLayout 中创建自定义 3 个按钮,而不是 TabLayout。
现在,在您的情况下,我会将 ViewPager2 与 FragmentStateAdapter 一起使用,因为它旨在与 Fragment 配合使用,您可以根据需要创建任意数量的 Fragment。我什至有一个项目,其中我使用 FragmentStateAdapter 创建了 80 个片段。
其次,您的片段需要一个 newInstance 构造函数作为安全模式。如果您不使用它,您稍后可能会在您的应用程序中遇到一些异常,但除此之外,您还将使用该函数将数据传递给每个片段。
这是我的做法:
class FragmentStateAdapter(
fragmentManager: FragmentManager,
lifecycle: Lifecycle,
car: Car
) : FragmentStateAdapter(fragmentManager, lifecycle) {
override fun getItemCount(): Int = 3
override fun createFragment(position: Int): Fragment {
return when (position) {
0 -> InfoFragment.newInstance(car)
1 -> AboutFragment.newInstance(car)
else -> LocationFragment.newInstance(car)
}
}
基本上,我将您的汽车对象(假设它是唯一需要到达片段的数据对象)作为参数传递给 FragmentStateAdapter,将 itemCount 锁定为 3,因为您有 3 个片段,然后返回每个片段的实例覆盖方法 createFragment() 中的片段。现在,创建实例函数:
class InfoFragment : Fragment() {
companion object {
private const val BUNDLE_KEY = "car_object"
fun newInstance(car: Car) = InfoFragment().apply {
arguments = Bundle().apply {
putParcelable<Car>(BUNDLE_KEY, car)
}
}
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_car_details_info, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val car = arguments.getParcelable<Car>(BUNDLE_KEY)
}
}
这就是将汽车对象放入片段中的方法。基本上在 newInstance() 函数中,您创建片段的新实例并通过 bundle 将数据传递给它。在您的 activity 中,这是您初始化适配器的方式:
val adapter = FragmentStateAdapter(supportFragmentManager, lifecycle, car)
现在,关于选项卡视图的替换,做一个像这样的自定义 LinearLayout:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:weightSum="1.0">
<Button
android:id="@+id/button1"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.333"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="Details"
android:textAllCaps="true" />
<Button
android:id="@+id/button2"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.333"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="About"
android:textAllCaps="true" />
<Button
android:id="@+id/button3"
style="@style/Widget.AppCompat.Button.Borderless"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.333"
android:minWidth="0dp"
android:minHeight="0dp"
android:paddingTop="14dp"
android:paddingBottom="14dp"
android:text="Locations"
android:textAllCaps="true" />
然后根据自己的喜好设置按钮的初始颜色 android:background="#COLOR_OR_CHOICE"
在 activity 中,将三个按钮添加到按钮的 ArrayList 中,并在 viewPager2 上使用此侦听器:
viewPager2.registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
// here, get the position of the viewPager2 and change the color of the current button using the arrayList index that matches the viewPager2 position.
})
然后,在每个按钮的点击侦听器上,执行 viewPager2.setCurrentItem(position_you_want_to_go_to, true),其中 true 是对平滑滚动的检查。
希望这对您有所帮助。