Recyclerview Item onclick перекрывает следующий фрагмент вместо его замены - PullRequest
0 голосов
/ 20 января 2020

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

См. Снимок экрана ниже: Screenshot with new fragment overlaying on old one Следующий снимок экрана - старый фрагмент представление: home fragment

Что касается основной активности:

class MainActivity : AppCompatActivity(), RecyclerViewClickListener {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_home,
                R.id.navigation_messages,
                R.id.navigation_notifications,
                R.id.navigation_account
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)

        if (savedInstanceState == null) {
            supportFragmentManager
                .beginTransaction()
                .add(R.id.fragment_home, HomeFragment.newInstance(), "dormList")
                .commit()
        }
    }

    override fun onRecyclerViewItemClick(view: View, dorms: Dorms) {
        val detailsFragment = dormDetailsFragment.newInstance(dorms)
        supportFragmentManager
            .beginTransaction()
            .replace(R.id.fragment_home, detailsFragment, "Dorm Details")
            .addToBackStack(null)
            .commit()
    }
}

HomeFragment:

class HomeFragment : Fragment(), RecyclerViewClickListener {

    private lateinit var factory: HomeViewModelFactory
    private lateinit var viewModel: HomeViewModel
    private var callback : RecyclerViewClickListener? = null

    companion object {
        fun newInstance(): HomeFragment {
            return HomeFragment()
        }
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)

        if(context is RecyclerViewClickListener) callback = context
        else throw ClassCastException("$context must implement Callback")
    }

    override fun onDetach() {
        super.onDetach()
        callback = null
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)

        val api = DormsAPI()
        val repository = DormRepository(api)

        factory = HomeViewModelFactory(repository)
        viewModel = ViewModelProviders.of(this, factory).get(HomeViewModel::class.java)

        viewModel.getDorms()

        viewModel.dorms.observe(viewLifecycleOwner, Observer { dorms ->
            recyclerViewDorms.also{
                it.layoutManager = LinearLayoutManager(requireContext())
                it.setHasFixedSize(true)
                it.adapter = dormAdapter(dorms, this)
            }
        })
    }

    override fun onRecyclerViewItemClick(view: View, dorms: Dorms) {
        when(view.id){
            R.id.button_reserve -> {
                // TODO: Go to new account if not signed up, etc...
                Toast.makeText(requireContext(), "Reserve button clicked", Toast.LENGTH_LONG).show()
            }
            R.id.layoutBox -> {
                // TODO: Go to Dorm Details
                callback?.onRecyclerViewItemClick(view, dorms)
            }
        }
    }
}

Модель Home View

class HomeViewModel(private val repository: DormRepository) : ViewModel() {

    private lateinit var job: Job

    private val _dorms = MutableLiveData<List<Dorms>>()
    val dorms: LiveData<List<Dorms>>
        get() = _dorms

    fun getDorms() {
        job = Coroutines.ioThenMain(
            { repository.getDorms() },
            { _dorms.value = it }
        )
    }

    override fun onCleared() {
        super.onCleared()
        if(::job.isInitialized) job.cancel()
    }
}

Интерфейс:

interface RecyclerViewClickListener {
    fun onRecyclerViewItemClick(view: View, dorms: Dorms)
}

Фрагмент детали:

class dormDetailsFragment : Fragment() {

    companion object {

        private const val DORMS = "model"
        fun newInstance(dorms: Dorms): dormDetailsFragment{
            val args = Bundle()
            args.putSerializable(DORMS, dorms)
            val fragment = dormDetailsFragment()
            fragment.arguments = args
            return fragment
        }
    }

    private lateinit var viewModel: DormDetailsViewModel

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val fragmentDormDetailsBinding =
            FragmentDormDetailsBinding.inflate(inflater,container,false)

        val model = arguments!!.getSerializable(DORMS) as Dorms
        fragmentDormDetailsBinding.dormDetails = model

        return fragmentDormDetailsBinding.root
    }
}

Макет фрагмента дома

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/fragment_home">

    <TextView
        android:id="@+id/text_home"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <androidx.swiperefreshlayout.widget.SwipeRefreshLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/refreshLayout">

        <androidx.recyclerview.widget.RecyclerView
            tools:listitem="@layout/layout_home"
            android:id="@+id/recyclerViewDorms"
            android:layout_width="0dp"
            android:layout_height="0dp"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintBottom_toBottomOf="parent" />

    </androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Макет детали

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>
        <import type="android.view.View" />
        <variable
            name="dormDetails"
            type="com.pptt.roomy.data.models.Dorms" />
    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context="com.pptt.roomy.ui.home.dormDetails.DormDetailsFragment"
        android:id="@+id/DormDetailsFrag">

        <ImageView
            app:image="@{dormDetails.image}"
            android:id="@+id/image"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            app:layout_constraintDimensionRatio="1:1"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            android:background="@drawable/propertysample"
            />

        <TextView
            android:text="@{String.valueOf(dormDetails.dormPrice)}"
            tools:text="Php 2500"
            android:id="@+id/textViewPrice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="6dp"
            android:layout_marginStart="10dp"
            android:textSize="20sp"
            android:textStyle="normal"
            android:textColor="#000000"
            app:layout_constraintTop_toBottomOf="@id/image"
            app:layout_constraintLeft_toLeftOf="parent" />

        <TextView
            android:text="@{dormDetails.dormName}"
            tools:text="Dorm ni Jupa"
            android:id="@+id/textViewPropertyName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="1dp"
            android:layout_marginStart="10dp"
            android:textSize="24sp"
            android:textStyle="bold"
            android:textColor="#000000"
            app:layout_constraintTop_toBottomOf="@id/textViewPrice"
            app:layout_constraintLeft_toLeftOf="parent" />

        <TextView
            android:text="@{dormDetails.dormType}"
            tools:text="1 BR with Dining and Kitchen"
            android:id="@+id/textViewRoomType"
            android:layout_below="@id/textViewPropertyName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:paddingTop="5dp"
            android:layout_marginLeft="40dp"
            android:textSize="16sp"
            app:layout_constraintTop_toBottomOf="@+id/textViewPropertyName"
            app:layout_constraintLeft_toLeftOf="parent"/>

        <TextView
            android:text="@{dormDetails.dormAddress}"
            android:id="@+id/textViewAddress"
            android:layout_marginBottom="5dp"
            tools:text="455 San Jose II St., Brgy. 425, Sampaloc, Manila"
            android:textAppearance="@style/Base.TextAppearance.AppCompat.Small"
            android:padding="5dp"
            android:layout_marginLeft="40dp"
            android:layout_width="wrap_content"
            android:textAlignment="center"
            android:layout_height="wrap_content"
            app:layout_constraintTop_toBottomOf="@+id/textViewRoomType"
            app:layout_constraintLeft_toLeftOf="parent"/>

        <TextView
            android:text="@{dormDetails.dormDetails}"
            android:id="@+id/textViewDescription"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            tools:text="A very long textarea to contain dorm description. Should be multiline"
            android:padding="5dp"
            android:layout_marginLeft="20dp"
            app:layout_constraintTop_toBottomOf="@id/textViewAddress"
            app:layout_constraintLeft_toLeftOf="parent"/>

    </androidx.constraintlayout.widget.ConstraintLayout>
</layout>

Все остальное, что нужно, будет отредактировано на потом.

1 Ответ

1 голос
/ 20 января 2020

Удалите эти строки:

if (savedInstanceState == null) {
    supportFragmentManager
        .beginTransaction()
        .add(R.id.fragment_home, HomeFragment.newInstance(), "dormList")
        .commit()
}

Вы добавляете одну HomeFragment через NavHostFragment, а другую вручную. Вам не нужно вручную добавлять фрагмент при использовании навигации.

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

override fun onRecyclerViewItemClick(view: View, dorms: Dorms) {
    val navController = findNavController(R.id.nav_host_fragment)
    // If you're using Safe Args, use the ID generated from
    // the navigation graph and make sure you have
    // an argument of the correct type
    navController.navigate(
        HomeFragmentDirections.actionHomeToDetails(dorms))
}

Возможно, вам будет полезно взглянуть на документацию Передача данных между получателями , чтобы узнать, как создать <argument> на вашем графике для объекта Dorms и как настроить Safe Args для создания класса Directions для вас.

...