无论我尝试以何种方式更改其内容,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 是对平滑滚动的检查。

希望这对您有所帮助。