Идентификатор TextView продолжает вызывать ноль независимо от того, каким образом я пытаюсь изменить его содержимое - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть TabLayout с 3 фрагментами внутри. Фрагмент 0 содержит подробности, 1 - описание, а 2 - местоположение.

Но независимо от того, как я пытаюсь вызвать идентификаторы фрагмента внутри моего carDetailsActivity, или я пытаюсь передать значение из действия во фрагменты, которые оно содержит продолжает вызывать ноль и дает следующий результат: Фрагмент вкладки

enter image description here

Теперь я попробовал несколько способов, чтобы один из них Bundle текстовое значение из активность к фрагменту, но я все еще получил нулевое "IllegaleStateException". (который был лучшим вариантом, насколько мне известно), но он все еще не работал.

Вот как я хочу, чтобы это выглядело (дизайн на арабском c):

enter image description here

Вот моя активность где я звоню им в данный момент, но я просто получаю пустые строки (должен был дать их? потому что приложение продолжало падать, если я этого не делал):

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)
    }
}

Я задавал этот похожий вопрос раньше, но он не был достаточно ясен, поэтому я надеюсь, что это был лучший способ опубликовать мою проблему.

-EDIT Моя вкладкаLayout 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"
            }
        }
    }
}

Ответы [ 2 ]

1 голос
/ 21 февраля 2020

Прежде всего, я бы порекомендовал отказаться от старого и неприятного TabLayout и переключиться на новый ViewPager2 вместо старого ViewPager. В пользовательском интерфейсе вместо TabLayout создайте пользовательские 3 кнопки внутри LinearLayout или ConstraintLayout.

Теперь, в вашем случае, я бы использовал ViewPager2 с FragmentStateAdapter, потому что он был разработан, чтобы хорошо работать с Fragments, и вы можете создать столько, сколько вам нужно. У меня даже был проект, в котором у меня было 80 фрагментов, созданных с помощью FragmentStateAdapter.

Во-вторых, вам нужен конструктор 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 () вы создаете новый экземпляр вашего фрагмента и передаете ему данные через связку. Внутри вашей деятельности вы инициализируете свой адаптер следующим образом:

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"

. В действии добавьте три кнопки в 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 - это проверка для плавной прокрутки.

Надеюсь, это поможет.

0 голосов
/ 21 февраля 2020

Разве вы не должны присваивать значения полям в вашем фрагменте?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...