Recyclerview Item onclick会覆盖下一个片段,而不是替换它 [英] Recyclerview Item onclick overlays the next fragment instead of replacing it

查看:63
本文介绍了Recyclerview Item onclick会覆盖下一个片段,而不是替换它的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这些活动,片段,其视图模型及其适配器.单击一个recyclerview项,我已经可以调用下一个片段,但是新的片段会覆盖在第一个片段上.

I have these activity, fragments, its viewmodels, and their adapter. I can already call the next fragment on click of a recyclerview item, but the new fragment overlays on the first fragment.

请参考以下屏幕截图: 下一个屏幕截图是旧的片段视图:

Refer to screenshot below: Next screenshot is the old fragment view:

至于主要活动:

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:

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

主视图模型

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>

所需的其他内容将在以后进行编辑.

Anything else that's needed will be edited for later.

推荐答案

删除这些行:

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

您要通过NavHostFragment添加一个HomeFragment,然后手动添加另一个.使用导航时,您无需手动添加片段.

You're adding one HomeFragment via the NavHostFragment and another manually. You don't need to manually add Fragment when using Navigation.

您还应该按照导航到目标文档:

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

查看在目标文档之间传递数据,了解如何在图形中为Dorms对象创建<argument>,以及如何设置安全Args来为您生成Directions类.

You might find it helpful to look at the Pass data between destinations documentation to see how to create an <argument> in your graph for your Dorms object and how to set up Safe Args to generate the Directions class for you.

这篇关于Recyclerview Item onclick会覆盖下一个片段,而不是替换它的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆