如何在Kotlin中使用RecyclerView [英] How to use RecyclerView in kotlin

查看:87
本文介绍了如何在Kotlin中使用RecyclerView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以前,我曾问过分片调用API ,现在我有了我的应用程序中返回的数据我想知道如何在此片段中制作RecyclerView?

Previously I have asked about calling API in fragments and now that I have my data returning in my app I would like to know how to make RecyclerView in this fragments?

基本上,这就是我最终要实现的目标

Basically this is what i'm looking for to achieve at the end

HomeFragment.kt

class HomeFragment : Fragment() {

    private lateinit var homeViewModel: HomeViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)

        val root = inflater.inflate(R.layout.fragment_home, container, false)

        val textView: TextView = root.findViewById(R.id.text_home)

        //calling the API
        callAPIDemo(textView)

        // homeViewModel.text.observe(this, Observer {
        //     textView.text = it
        // })

        return root
    }

    fun callAPIDemo(textView: TextView) {
        // Instantiate the RequestQueue.
        val queue = Volley.newRequestQueue(activity)
        val url = "https://example.com/api/listings"

        // Request a string response from the provided URL.
        val stringRequest = StringRequest(
            Request.Method.GET, url,
            Response.Listener<String> { response ->
                // Display the first 500 characters of the response string.
                textView.text = "Response is: ${response.substring(0, 500)}"
            },
            Response.ErrorListener { textView.text = "Something is wrong!" })

        // Add the request to the RequestQueue.
        queue.add(stringRequest)
    }

}

fragment_home.xml

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <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.constraintlayout.widget.ConstraintLayout>

这就是我目前的全部.

请注意,我是新手,非常感谢您提供一些详细的解释.

Please note that I'm newbie in this, giving help with little bit of detailed explanation is much appreciated.

更新

这是我到目前为止创建的内容

Update

Here is what I've created so far

HomeFragment.kt

class HomeFragment : Fragment() {

    private lateinit var homeViewModel: HomeViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        homeViewModel = ViewModelProviders.of(this).get(HomeViewModel::class.java)

        val root = inflater.inflate(R.layout.fragment_home, container, false)

        val textView: TextView = root.findViewById(R.id.recycler)

        //calling the API
        //callAPIDemo(textView)

        val adapter = RecyclerAdapter(callAPIDemo(textView))
        recycler.adapter = adapter

        return root
    }

    fun callAPIDemo(textView: TextView) {
        // Instantiate the RequestQueue.
        val queue = Volley.newRequestQueue(activity)
        val url = "https://example.com/api/listings"

        // Request a string response from the provided URL.
        val stringRequest = StringRequest(
            Request.Method.GET, url,
            Response.Listener<String> { response ->
                // Display the response.
                textView.text = "Response is: ${response.substring(0)}"
            },
            Response.ErrorListener { textView.text = "Something is wrong!" })

        // Add the request to the RequestQueue.
        queue.add(stringRequest)
    }

}

ListingAdapter.kt

此类为红色,返回错误

参数必须具有类型注释

Parameters must have type annotation

class RecyclerAdapter(List) :
    RecyclerView.Adapter<RecyclerAdapter.RecyclerViewHolder>() {

    //Binding data for each tile
    override fun onBindViewHolder(holder: RecyclerViewHolder, position: Int) {
    }

    //Creation of view holder for each tile
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerViewHolder {
        val inflater = LayoutInflater.from(parent.context)
        context = parent.context  //this context is red
        return RecyclerViewHolder(inflater, parent)
    }

    //View Holder for each item in recycler
    inner class RecyclerViewHolder(inflater: LayoutInflater, parent: ViewGroup) :
        RecyclerView.ViewHolder(inflater.inflate(R.layout.listings_layout, parent, false)) {
    }

    override fun getItemCount(): Int {
        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
    }
}

listings_layout.xml

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <androidx.cardview.widget.CardView
            android:layout_margin="3dp"
            android:layout_width="match_parent"
            android:layout_height="wrap_content">

            <RelativeLayout
                android:orientation="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <ImageView
                    android:id="@+id/imageViewImage"
                    android:layout_width="match_parent"
                    android:layout_height="195dp"
                    android:background="@color/colorPrimary"
                    android:contentDescription="@string/Image"
                    android:scaleType="matrix" />

                <TextView
                    android:id="@+id/textViewTitle"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/MakeUp"
                    android:textAppearance="@style/TextAppearance.AppCompat.Large" />

                <TextView
                    android:id="@+id/textViewSlug"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:text="@string/MakeUp"
                    android:textAppearance="@style/TextAppearance.AppCompat.Large" />


            </RelativeLayout>

        </androidx.cardview.widget.CardView>
    </LinearLayout>

最后是我的fragment_home.xml

<androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        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"
        android:id="@+id/recycler" />

推荐答案

首先,您需要创建一个布局,以使列表中单行的外观(考虑到我们正在创建水平列表)

First You will need to create a layout for how a single row in your list will look(considering we are creating horizontal listing)

在项目中导航到res>布局文件夹,在布局文件夹中创建一个布局资源文件(花式名称,但这只是一个XML文件)

navigate to res > layout folder in your project, in layout folder create a Layout Resource File (fancy name, but it's just a XML file)

例如:-

layout_demo_item.xml

<?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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="8dp">


    <ImageView
        android:id="@+id/a_image"
        android:layout_width="80dp"
        android:layout_height="80dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/text_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/a_image"
        app:layout_constraintStart_toEndOf="@+id/a_image"
        app:layout_constraintTop_toTopOf="@+id/a_image" />


    <TextView
        android:id="@+id/text_random"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="20dp"
        android:layout_marginEnd="20dp"
        android:textSize="18sp"
        app:layout_constraintBottom_toBottomOf="@+id/text_title"
        app:layout_constraintStart_toEndOf="@+id/text_title"
        app:layout_constraintTop_toTopOf="@+id/text_title" />

</androidx.constraintlayout.widget.ConstraintLayout>

第二,您需要一个适配器.

Second you need an Adapter.

适配器会从您那里获取一个数据列表/数组,根据列表的大小呈现行数,并根据列表上的位置将数据分配给每一行

An Adapter will take a list/array of data from you, render number of rows based on size of list and assign the data to each row based on position on list

例如:-

您有一个包含6个名称的数组,然后适配器将基于layout_demo_item.xml创建6个相同的行,并分配数据,例如将数组中的第0个位置数据分配给列表的第一个元素

You have an array of 6 names, then the adapter will create 6 identical row based on layout_demo_item.xml and assign data like 0th position data in array will be assigned to first element of list

MyAdapter.kt

    class MyAdapter(var dataList: MutableList<DataModelObject>) : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {


        // inflating a layout in simple word is way of using a xml layout inside a class.
        // if you look this is the same thing that your fragment doing inside onCreateView and storing that into "root" variable, we just did that in "view"
        // we passed "view" to MyViewHolder and returned an object of MyViewHolder class(this object actually a single row without data)
        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {

            val view = LayoutInflater.from(parent.context).inflate(R.layout.layout_demo_item, parent, false)

            return MyViewHolder(view)
        }


        //the returned object of MyViewHolder class will come here and also with the position on which it gonna show,
        // now based on this position we can get the value from our list and finally set it to the corresponding view that we have here in variable "holder"
        override fun onBindViewHolder(holder: MyViewHolder, position: Int) {

            holder.textView.text = dataList.get(position).title
            holder.textViewRandom.text = dataList.get(position).randomText

            //hardcoding the image, just for simplicity, you can set this also from data list same as above
            holder.aImage.setImageResource(R.mipmap.ic_launcher)


   //here is the image setup by using glide
 //Glide.with(holder.aImage.context).load(dataList.get(position).image).into(holder.aImage)

        }

        // this method telling adapter to how many total rows will be rendered based on count, so we returning the size of list that we passing
        override fun getItemCount(): Int {
            return dataList.size
        }


        // while creating the object in onCreateViewHolder, we received "view" here, and as you can see in your fragment,
        // we can do find views by id on it same as we doing in fragment
        // so your MyViewHolder now hold the reference of the actual views, on which you will set data
        class MyViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {


            var textView: TextView
            var textViewRandom: TextView
            var aImage: ImageView


            init {

                textViewRandom = itemView.findViewById(R.id.text_random)
                textView = itemView.findViewById(R.id.text_title)
                aImage = itemView.findViewById(R.id.a_image)

            }

        }
    }

这是我们用作模型类的数据类(与Java中的POJO类相同,但仅在Kotlin中)

here is the data class that we using as our model class(same as a POJO class in Java but it's just in Kotlin)

  data class DataModelObject(var randomText:String,var title :String) {
    }

我们已经设置了创建recyclerView的所有内容,因此现在我们将像

We have all things set to create a recyclerView, so now we will define recyclerView in Fragment like

fragment_home.xml

<?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"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <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.recyclerview.widget.RecyclerView
        android:id="@+id/recycler_view_home"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/text_home" />

</androidx.constraintlayout.widget.ConstraintLayout>

最后,在kotlin类中设置了recyclerView

Finally Inside kotlin class setting up a recyclerView

HomeFragment.kt

(我不包含此片段中不相关的方法和变量,请考虑一下)

(i'm not including the irrelevant methods and variable that you have in this fragment, please consider them)

class HomeFragment : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? {



        val root = inflater.inflate(R.layout.fragment_home, container, false)

        val textView: TextView = root.findViewById(R.id.text_home)
        val recyclerView: RecyclerView = root.findViewById(R.id.recycler_view_home)

        callAPIDemo(textView)

        setUpRecyclerView(recyclerView);


        return root
    }

    private fun setUpRecyclerView(recyclerView: RecyclerView) {

        // first our data list that can come from API/Database
        // for now i'm just manually creating the list in getDummyData()
        val list: MutableList<DataModelObject> = getDummyData()

        // created an adapter object by passing the list object
        var myAdapter = MyAdapter(list)

        //it's a layoutManager, that we use to tell recyclerview in which fashion  we want to show list,
        // default is vertical even if you don't pass it and just pass the activity , and we don't want to reversing it so false
        // by customizing it you can create Grids,vertical and horizontal lists, even card swipe like tinder
        val linearLayoutManager = LinearLayoutManager(activity,LinearLayoutManager.VERTICAL,false)




        // just set the above layout manager on RecyclerView
        recyclerView.layoutManager = linearLayoutManager

        //and give it a adapter for data
        recyclerView.adapter = myAdapter


    }



    private fun getDummyData(): MutableList<DataModelObject> {

        val list: MutableList<DataModelObject> = mutableListOf(

                DataModelObject("dfgdfg", "title 1"),
                DataModelObject("tyuityui", "title 2"),
                DataModelObject("yuti", "title 3"),
                DataModelObject("uY9NOrc-=s180-rw", "title 4"),
                DataModelObject("logo_color_272x92dp.png", "title 5"),
                DataModelObject("NOVtP26EKH", "title 6"),
                DataModelObject("googlelogo_color", "title 7"),
                DataModelObject("sNOVtP26EKHePkwBg-PkuY9NOrc-", "title 8")

        )

        return list

    }

}

这篇关于如何在Kotlin中使用RecyclerView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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