Android 基础可展开列表适配器示例
什么是 Android 中的基础可展开列表适配器?
Android 中的基础可展开列表适配器用于显示嵌套列表视图。我们将通过一个示例来理解嵌套列表视图。我们需要显示技术栈及其使用的编程语言。因此,我们可以显示列表视图中的技术栈,例如 Android 开发、iOS 开发和 Web 开发。每个技术栈都有其各自的编程语言列表,因此当用户点击任何技术栈时,我们可以显示编程语言列表。这样,我们就可以实现嵌套列表视图。为了实现嵌套列表视图,我们将在 Android 应用程序中使用基础可展开列表适配器。
基础可展开列表适配器的实现
在本文中,我们将创建一个简单的应用程序,在其中我们将显示技术栈列表。当用户点击任何技术栈时,我们将显示可用于该特定技术栈的编程语言。我们将遵循分步指南在 Android 应用程序中实现吐司消息。
步骤 1:在 Android Studio 中创建一个新项目
导航到 Android Studio,如下图所示。在下面的屏幕中,点击“新建项目”以创建一个新的 Android Studio 项目。
点击“新建项目”后,您将看到下面的屏幕。
在这个屏幕中,我们只需选择“空活动”,然后点击“下一步”。点击“下一步”后,您将看到下面的屏幕。
在这个屏幕中,我们只需指定项目名称。然后包名将自动生成。
注意 – 确保选择 Kotlin 作为语言。
指定所有详细信息后,点击“完成”以创建一个新的 Android Studio 项目。
项目创建完成后,我们将看到打开的两个文件,即 activity_main.xml 和 MainActivity.kt 文件。
步骤 2:使用 activity_main.xml
导航到 activity_main.xml。如果此文件不可见,则要打开此文件,请在左侧面板中导航到 app>res>layout>activity_main.xml 以打开此文件。打开此文件后,向其中添加以下代码。代码中添加了注释以便详细了解。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout 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" tools:context=".MainActivity"> <!-- creating text view for name on below line--> <TextView android:id="@+id/idTVTitle" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_margin="10dp" android:gravity="center" android:padding="4dp" android:text="Base Expandable List Adapter" android:textAlignment="center" android:textColor="@color/black" android:textSize="20sp" android:textStyle="bold" /> <!-- creating an expandable list view on below line--> <ExpandableListView android:id="@+id/idExpandableListView" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_below="@id/idTVTitle" /> </RelativeLayout>
说明 – 在上面的代码中,我们将相对布局作为根布局。在这个相对布局中,我们创建了一个简单的文本视图,用于显示应用程序的标题。之后,我们创建了一个可展开列表视图小部件,我们将使用它来显示应用程序中的技术栈列表及其编程语言。
步骤 3:为 TechStackItem 创建一个新的模型类
现在,我们将为我们的技术栈项目创建一个新的模型类,它将包含两个变量,一个用于技术栈名称,一个用于我们必须在该技术栈中显示的编程语言列表的数组列表变量。要创建此类,请导航到 app>java>您的应用程序包名称>右键单击它>新建>Java/Kotlin 类,并将其命名为 TechStackItem,然后向其中添加以下代码。
package com.example.gptapp data class TechStackItem( // on below line creating a string variable for tech stack/ // creating an array list for programming languages within this to display programming languages. var techStack: String, var programmingLanguages: ArrayList<String> )
步骤 4:为编程语言列表项创建一个新的布局文件。
由于我们将创建一个可展开列表视图,因此我们必须创建一个单独的项目视图,我们必须将其显示在我们的编程语言列表视图中。要创建它,请导航到 app>res>layout>右键单击它>新建>布局资源文件,并将其命名为 programming_lng_list_item,然后向其中添加以下代码。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- on below line creating a text view for displaying a programming language --> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="3dp" android:id="@+id/idTVProgrammingLng" android:padding="4dp" android:text="Programming Language Item" android:textColor="#FF000000" android:textSize="15sp" /> </RelativeLayout>
说明:在上面的代码中,我们创建了一个简单的文本视图,我们将使用它来显示编程语言列表视图中的项目。
步骤 5:为技术栈列表项创建一个新的布局文件
当我们点击技术栈时,我们将显示编程语言列表。为了显示技术栈,我们将必须为此创建一个单独的布局文件。要创建一个新的布局文件,请导航到 app>res>layout>右键单击它>新建>布局资源文件,并将其命名为 tech_stack_list_item,然后向其中添加以下代码。
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="40dp"> <!-- on below line creating a text view for displaying a tech stack --> <TextView android:id="@+id/idTvTechStack" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="3dp" android:gravity="center" android:padding="4dp" android:text="Tech Stack List Item" android:textColor="#FF000000" android:textSize="16sp" android:textStyle="bold" /> </RelativeLayout>
说明 – 在上面的代码中,我们只是创建了一个文本视图,我们将使用它来显示技术栈的文本。我们将此布局文件用于技术栈列表视图。
步骤 6:创建一个适配器类来将数据设置为我们的布局文件
现在我们已经创建了用于显示 UI 的布局文件。之后,我们必须设置我们必须在布局文件中显示哪些数据。要设置此数据,我们必须创建一个适配器类。要创建此适配器类,请导航到 app>java>您的应用程序包名称>右键单击它>新建>Java/Kotlin 类,并将其命名为 CustomListViewAdapter,然后向其中添加以下代码。
package com.example.gptapp import android.content.Context import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import android.widget.BaseExpandableListAdapter import android.widget.TextView // Creating a custom list view adapter on below line. class CustomListViewAdapter( // creating a list for our tech stack on below line and passing tech stack item to it. private val techStackList: List<TechStackItem>, ) : BaseExpandableListAdapter() { // on below line we have to return the size of group in our case is tech stack for programming languages override fun getGroupCount(): Int { return techStackList.size } // below method is use to return size of child list in our case is language list override fun getChildrenCount(groupPosition: Int): Int { val lngList = techStackList.get(groupPosition).programmingLanguages return lngList.size } // on below line we are returning the group from our tech stack list. override fun getGroup(groupPosition: Int): Any { return techStackList.get(groupPosition) } // below method is use to return the item for our child list override fun getChild(groupPosition: Int, childPosition: Int): Any { // on below line we are getting our programming language list from tech stack list val programmingLanguageList = techStackList.get(groupPosition).programmingLanguages // on below line e are getting item from our programming language list which we are taking from tech stack list return programmingLanguageList.get(childPosition) } // below method is use to get group position override fun getGroupId(groupPosition: Int): Long { return groupPosition.toLong() } // below method is use to get child position. override fun getChildId(groupPosition: Int, childPosition: Int): Long { return childPosition.toLong() } // below method is use to return true for stable ids. override fun hasStableIds(): Boolean { return true } // below method is use to inflate layout file for our group items. override fun getGroupView( groupPosition: Int, isExpanded: Boolean, convertView: View?, parent: ViewGroup? ): View { // on below line we are getting our group from tech stack item val techStackItem: TechStackItem = getGroup(groupPosition) as TechStackItem // on below line we are creating a layout inflater variable to inflate our layout file. val inflater = parent!!.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater // on below line we are inflating our layout file for our tech stack item. val view = inflater.inflate(R.layout.tech_stack_list_item, null) as View // on below line we are creating and initializing variable for our tech stack tv. val techStackTV: TextView = view.findViewById(R.id.idTvTechStack) // on below line we are setting text for our tech stack text view. techStackTV.text = techStackItem.techStack // on below line returning the view. return view } // below method is use to inflate layout file for our child view. override fun getChildView( groupPosition: Int, childPosition: Int, isLastChild: Boolean, convertView: View?, parent: ViewGroup? ): View { // on below line we are getting language from our group val language: String = getChild(groupPosition, childPosition) as String // on below line we are creating a variable for our inflater. val inflater = parent?.context!!.getSystemService(Context.LAYOUT_INFLATER_SERVICE) as LayoutInflater // on below line we are inflating a layout file for programming language list item. val view = inflater.inflate(R.layout.programming_lng_list_item, null) as View // on below line we are creating and initializing our text view for programming language. val programmingLngTV: TextView = view.findViewById(R.id.idTVProgrammingLng) // on below line setting data for our text view. programmingLngTV.text = language // on below line returning the view. return view } // below method is use to specify weather the child item will be selectable or not // in our case we are specifying it as selectable. override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean { return true } }
说明 – 在上面的代码中,首先,我们将适配器类扩展为 BaseExpandableListAdapter,并将我们的数据列表作为参数传递到其中。现在,在这个类中,我们正在重写 BaseExpandableListAdapter 类的所有方法。这些方法如下:
getGroupCount() – 在此方法中,我们必须返回技术栈列表的大小,这是我们的父列表。
getChildrenCount() – 在此方法中,我们必须返回编程语言列表的大小,这是我们的子列表。
getGroup() – 在此方法中,我们必须返回技术栈列表项的组,其中包含技术栈名称和该技术栈中存在的编程语言。
getChild() – 在此方法中,我们必须从每个技术栈的编程语言列表中返回编程语言项目。
getGroupId() – 在此方法中,我们只需返回组位置。
getChildId() – 在此方法中,我们只需返回子项位置。
hasStableIds() – 在此方法中,我们只需返回 true,因为我们必须为列表视图项目显示稳定的 ID。
getGroupView() – 在此方法中,我们正在为父列表视图(在我们的例子中是技术栈)膨胀布局文件,因此我们将膨胀 tech_stack_list_item 布局。
getChildView() – 在此方法中,我们正在为子列表视图(在我们的例子中是编程语言)膨胀布局文件,因此我们将膨胀 programming_lng_list_item 布局。
isChildSelectable() – 在此方法中,我们返回 true,因为我们必须为可展开列表视图设置点击侦听器。
步骤 7:使用 MainActivity.kt
导航到 MainActivity.kt。如果此文件不可见,则要打开此文件,请在左侧面板中导航到 app>java>您的应用程序包名称>MainActivity.kt 以打开此文件。打开此文件后,向其中添加以下代码。代码中添加了注释以便详细了解。
package com.example.gptapp import android.os.Bundle import android.widget.ExpandableListView import android.widget.ExpandableListView.OnChildClickListener import android.widget.ExpandableListView.OnGroupClickListener import android.widget.Toast import androidx.appcompat.app.AppCompatActivity class MainActivity : AppCompatActivity() { // creating variables on below line for array list, adapter and expandable list view. private val techStackList: ArrayList<TechStackItem> = ArrayList() lateinit var customListViewAdapter: CustomListViewAdapter lateinit var expandableLV: ExpandableListView override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // initializing all variables with their ids on below line. expandableLV = findViewById(R.id.idExpandableListView) // on below line initializing our adapter and setting this adapter to expandable list view. customListViewAdapter = CustomListViewAdapter(techStackList) expandableLV.setAdapter(customListViewAdapter) // on below line creating an array list for first tech tack and passing it to our tech stack list with tech stack name val lng1: ArrayList<String> = ArrayList() lng1.add("Java") lng1.add("Kotlin") techStackList.add(TechStackItem("Android Development", lng1)) // on below line creating an array list for second tech tack and passing it to our tech stack list with tech stack name val lng2: ArrayList<String> = ArrayList() lng2.add("Objective c") lng2.add("Swift") techStackList.add(TechStackItem("IOS Development", lng2)) // on below line creating an array list for third tech tack and passing it to our tech stack list with tech stack name val lng3: ArrayList<String> = ArrayList() lng3.add("HTML") lng3.add("CSS") techStackList.add(TechStackItem("Web Development", lng3)) // on below line notifying adapter that data has changed. customListViewAdapter.notifyDataSetChanged() // on below line adding child click listener for expandable list view. expandableLV.setOnChildClickListener(OnChildClickListener { parent, v, groupPosition, childPosition, id -> // get the group header // on below line we are getting tech stack item from our tech stack list val techStackItem: TechStackItem = techStackList.get(groupPosition) // on below line we are getting our programming language item from tech stack item. val programmingLanguageItem: String = techStackItem.programmingLanguages.get(childPosition) // on below line we are displaying toast message Toast.makeText( baseContext, techStackItem.techStack + "/" + programmingLanguageItem, Toast.LENGTH_LONG ).show() false }) // on below line adding click listener for expandable list view. expandableLV.setOnGroupClickListener(OnGroupClickListener { parent, v, groupPosition, id -> // get the group header // on below line we are getting our tech stack item val techStackItem: TechStackItem = techStackList.get(groupPosition) // displaying toast message on below line. Toast.makeText(baseContext, techStackItem.techStack, Toast.LENGTH_LONG).show() false }) } }
说明 > 在上面的代码中,首先,我们为技术栈列表创建变量以创建一个新的数组列表,然后我们为适配器创建一个新变量,之后我们为可展开列表视图创建一个变量。创建变量后,我们在 onCreate 方法中初始化所有变量。我们将列表传递给适配器,并将该适配器设置为可展开列表视图。
初始化变量后,我们将数据传递给它。之后,我们通知适配器列表中的数据已更改。
将数据设置为可展开列表视图后,我们为可展开列表视图添加子项点击侦听器和组点击侦听器。在每个方法中,我们都显示一个吐司消息以显示点击。
添加上述代码后,我们只需点击顶部的绿色图标即可在移动设备上运行我们的应用程序。
注意 - 确保已连接到您的真实设备或模拟器。
结论
在本教程中,我们学习了什么是基础可展开列表适配器,以及如何在 Android 应用程序中使用它来显示 Android 应用程序中的可展开列表视图。