Kotlin 中嵌套的 ExpandableListView 的问题
Issues with Nested ExpandableListView in Kotlin
我正在开发一个应用程序,允许人们使用 Google 方向 API 来计划和跟踪 public 交通旅程。我试图显示使用三层嵌套的 ExpandableListView 所采取的步骤,但我遇到了这两个问题:
1.父列表的子视图显示相同的项目(groupPosition 始终为 0)。
2。子列表的子视图根本没有显示。
这是我的代码(很抱歉格式太长了):
家长列表主视图(journey_detail_list_view)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/journey_title_text_view"
android:textSize="40dp"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/journey_expandable_list_view"
android:layout_below="@id/journey_title_text_view"
/>
</LinearLayout>
父列表组视图(leg_detail_group_view)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/leg_list_title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="20dp"
android:text="TextView" />
</com.google.android.material.card.MaterialCardView>
父列表子view/child列表主视图(steps_nested_list_view)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/steps_nested_expandable_list_view" />
</LinearLayout>
子列表组视图(steps_nested_group_view)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/steps_nested_group_title_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:padding="20dp"/>
</com.google.android.material.card.MaterialCardView>
子列表子视图 (step_detail_view)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<View
android:id="@+id/step_line_colour_view"
android:layout_width="10dp"
android:layout_height="match_parent" />
<TextView
android:id="@+id/step_item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/step_line_colour_view"
android:text="TextView" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
JourneyDetailFragment
class JourneyDetailFragment(var journey: Journey, var act: MainActivity): Fragment() {
private lateinit var listView: ExpandableListView
private lateinit var titleTV: TextView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//Establish list
val v = inflater.inflate(R.layout.journey_detail_list_view, container, false)
listView = v.findViewById(R.id.journey_expandable_list_view)
titleTV = v.findViewById(R.id.journey_title_text_view)
val adapter = JourneyLegExpandableListAdapter(act, journey.legs)
listView.setAdapter(adapter)
titleTV.text = journey.summary
return v
}
}
父可扩展列表适配器 (JourneyLegExpandableListAdapter)
class JourneyLegExpandableListAdapter(var con: Context, var parentList: ArrayList<Leg>): BaseExpandableListAdapter() {
override fun getGroupCount(): Int {
return parentList.size
}
override fun getChildrenCount(groupPosition: Int): Int {
return parentList.get(groupPosition).steps.size
}
override fun getGroup(groupPosition: Int): Any {
return parentList.get(groupPosition)
}
override fun getChild(groupPosition: Int, childPosition: Int): Any {
return parentList.get(groupPosition).steps.get(childPosition)
}
override fun getGroupId(groupPosition: Int): Long {
return groupPosition.toLong()
}
override fun getChildId(groupPosition: Int, childPosition: Int): Long {
return childPosition.toLong()
}
override fun hasStableIds(): Boolean {
return false
}
override fun getGroupView(
groupPosition: Int,
isExpanded: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
//Create group view
val v: View
if(convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.leg_detail_group_view, parent, false)
}
else
{
v = convertView
}
val tv: TextView = v.findViewById(R.id.leg_list_title_tv)
val sb: StringBuilder = StringBuilder()
val leg = parentList.get(groupPosition)
if (leg.steps.first().startStop == null)
{
sb.append(leg.startAddress)
}
else
{
sb.append(leg.steps.first().startStop!!.name)
}
sb.append(" -> ")
if (leg.steps.last().endStop == null)
{
sb.append(leg.endAddress)
}
else
{
sb.append(leg.steps.last().endStop!!.name)
}
tv.text = sb.toString()
return v
}
override fun getChildView(
groupPosition: Int,
childPosition: Int,
isLastChild: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
val v: View
//Create child view
if (convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.steps_nested_list_view, parent, false)
}
else
{
v = convertView
}
val childList: ExpandableListView = v.findViewById(R.id.steps_nested_expandable_list_view)
val adapter = StepsExpandableListAdapter(con, parentList.get(groupPosition).steps)
childList.setAdapter(adapter)
return v
}
override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
return !parentList.get(groupPosition).steps.get(childPosition).subSteps.isNullOrEmpty()
}
}
子可扩展列表适配器 (StepsExpandableListAdapter)
class StepsExpandableListAdapter(var con: Context, var parentList: ArrayList<Step>): BaseExpandableListAdapter() {
override fun getGroupCount(): Int {
return parentList.size
}
override fun getChildrenCount(groupPosition: Int): Int {
return parentList.get(groupPosition).subSteps!!.size
}
override fun getGroup(groupPosition: Int): Any {
return parentList.get(groupPosition)
}
override fun getChild(groupPosition: Int, childPosition: Int): Any {
return parentList.get(groupPosition).subSteps!!.get(childPosition)
}
override fun getGroupId(groupPosition: Int): Long {
return groupPosition.toLong()
}
override fun getChildId(groupPosition: Int, childPosition: Int): Long {
return childPosition.toLong()
}
override fun hasStableIds(): Boolean {
return false
}
override fun getGroupView(
groupPosition: Int,
isExpanded: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
//Create group view
val v: View;
if(convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.steps_nested_group_view, parent, false)
}
else
{
v = convertView
}
val tv = v.findViewById<TextView>(R.id.steps_nested_group_title_tv)
tv.text = parentList.get(groupPosition).instructions
return v;
}
override fun getChildView(
groupPosition: Int,
childPosition: Int,
isLastChild: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
val v: View
if(convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.step_detail_view, parent, false)
}
else
{
v = convertView
}
val subStep = parentList.get(groupPosition).subSteps!!.get(childPosition)
val stepLineView = v.findViewById<View>(R.id.step_line_colour_view)
val stepTextView = v.findViewById<TextView>(R.id.step_item_tv)
stepLineView.setBackgroundColor(Color.parseColor(subStep.line!!.lineColour))
if(subStep.endStop == null)
{
stepTextView.text = subStep.instructions
}
else
{
stepTextView.text = subStep.endStop!!.name
}
return v;
}
override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
return false
}
}
旅程对象
class Journey(legs: ArrayList<Leg>, sum: String, f: Fare?, p: Polyline, c: String) {
var legs: ArrayList<Leg> = legs;
var summary: String = sum;
var fare: Fare? = f;
var polyline: Polyline = p
var copyright: String = c
}
腿对象
class Leg(di: Distance, at: Date, dt: Date, st: ArrayList<Step>, du: Duration, sl: LatLng, el: LatLng, sa: String, ea: String) {
var distance: Distance = di;
var arrivalTime: Date = at;
var departureTime: Date = dt;
var steps: ArrayList<Step> = st;
var duration: Duration = du;
var startLoc: LatLng = sl;
var endLoc: LatLng = el;
var startAddress: String = sa;
var endAddress: String = ea;
}
步骤对象
class Step (i: String?, di: Distance?, du: Duration?, st: LatLng?, en: LatLng?, su: ArrayList<Step>?, m: String?, es: Stop?, ss: Stop?, ar: Date?, de: Date?, hd: Double?, he: String?, ns: Int?, li: Line?, p: Polyline?){
var instructions: String? = i;
var distance: Distance? = di;
var duration: Duration? = du;
var startLocation: LatLng? = st;
var endLocation: LatLng? = en;
var subSteps: ArrayList<Step>? = su;
var maneuver: String? = m;
var endStop: Stop? = es;
var startStop: Stop? = ss;
var arrivalTime: Date? = ar;
var departureTime: Date? = de;
var headway: Double? = hd;
var headsign: String? = he;
var numStops: Int? = ns;
var line: Line? = li;
var polyline: Polyline? = p
}
我是不是漏掉了什么?
我创建了一个自定义列表视图用作子列表视图:
父列表子view/child列表主视图(steps_nested_list_view):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<NestedExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/steps_nested_expandable_list_view" />
</LinearLayout>
自定义代码 class:
class NestedExpandableListView(var con: Context, attributeSet: AttributeSet): ExpandableListView(con, attributeSet)
{
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val int = Int.MAX_VALUE.shr(2)
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(int, MeasureSpec.AT_MOST))
}
}
我正在开发一个应用程序,允许人们使用 Google 方向 API 来计划和跟踪 public 交通旅程。我试图显示使用三层嵌套的 ExpandableListView 所采取的步骤,但我遇到了这两个问题:
1.父列表的子视图显示相同的项目(groupPosition 始终为 0)。
2。子列表的子视图根本没有显示。
这是我的代码(很抱歉格式太长了):
家长列表主视图(journey_detail_list_view)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/journey_title_text_view"
android:textSize="40dp"/>
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/journey_expandable_list_view"
android:layout_below="@id/journey_title_text_view"
/>
</LinearLayout>
父列表组视图(leg_detail_group_view)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/leg_list_title_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:padding="20dp"
android:text="TextView" />
</com.google.android.material.card.MaterialCardView>
父列表子view/child列表主视图(steps_nested_list_view)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/steps_nested_expandable_list_view" />
</LinearLayout>
子列表组视图(steps_nested_group_view)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/steps_nested_group_title_tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView"
android:padding="20dp"/>
</com.google.android.material.card.MaterialCardView>
子列表子视图 (step_detail_view)
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="20dp">
<View
android:id="@+id/step_line_colour_view"
android:layout_width="10dp"
android:layout_height="match_parent" />
<TextView
android:id="@+id/step_item_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@id/step_line_colour_view"
android:text="TextView" />
</RelativeLayout>
</com.google.android.material.card.MaterialCardView>
JourneyDetailFragment
class JourneyDetailFragment(var journey: Journey, var act: MainActivity): Fragment() {
private lateinit var listView: ExpandableListView
private lateinit var titleTV: TextView
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
//Establish list
val v = inflater.inflate(R.layout.journey_detail_list_view, container, false)
listView = v.findViewById(R.id.journey_expandable_list_view)
titleTV = v.findViewById(R.id.journey_title_text_view)
val adapter = JourneyLegExpandableListAdapter(act, journey.legs)
listView.setAdapter(adapter)
titleTV.text = journey.summary
return v
}
}
父可扩展列表适配器 (JourneyLegExpandableListAdapter)
class JourneyLegExpandableListAdapter(var con: Context, var parentList: ArrayList<Leg>): BaseExpandableListAdapter() {
override fun getGroupCount(): Int {
return parentList.size
}
override fun getChildrenCount(groupPosition: Int): Int {
return parentList.get(groupPosition).steps.size
}
override fun getGroup(groupPosition: Int): Any {
return parentList.get(groupPosition)
}
override fun getChild(groupPosition: Int, childPosition: Int): Any {
return parentList.get(groupPosition).steps.get(childPosition)
}
override fun getGroupId(groupPosition: Int): Long {
return groupPosition.toLong()
}
override fun getChildId(groupPosition: Int, childPosition: Int): Long {
return childPosition.toLong()
}
override fun hasStableIds(): Boolean {
return false
}
override fun getGroupView(
groupPosition: Int,
isExpanded: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
//Create group view
val v: View
if(convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.leg_detail_group_view, parent, false)
}
else
{
v = convertView
}
val tv: TextView = v.findViewById(R.id.leg_list_title_tv)
val sb: StringBuilder = StringBuilder()
val leg = parentList.get(groupPosition)
if (leg.steps.first().startStop == null)
{
sb.append(leg.startAddress)
}
else
{
sb.append(leg.steps.first().startStop!!.name)
}
sb.append(" -> ")
if (leg.steps.last().endStop == null)
{
sb.append(leg.endAddress)
}
else
{
sb.append(leg.steps.last().endStop!!.name)
}
tv.text = sb.toString()
return v
}
override fun getChildView(
groupPosition: Int,
childPosition: Int,
isLastChild: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
val v: View
//Create child view
if (convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.steps_nested_list_view, parent, false)
}
else
{
v = convertView
}
val childList: ExpandableListView = v.findViewById(R.id.steps_nested_expandable_list_view)
val adapter = StepsExpandableListAdapter(con, parentList.get(groupPosition).steps)
childList.setAdapter(adapter)
return v
}
override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
return !parentList.get(groupPosition).steps.get(childPosition).subSteps.isNullOrEmpty()
}
}
子可扩展列表适配器 (StepsExpandableListAdapter)
class StepsExpandableListAdapter(var con: Context, var parentList: ArrayList<Step>): BaseExpandableListAdapter() {
override fun getGroupCount(): Int {
return parentList.size
}
override fun getChildrenCount(groupPosition: Int): Int {
return parentList.get(groupPosition).subSteps!!.size
}
override fun getGroup(groupPosition: Int): Any {
return parentList.get(groupPosition)
}
override fun getChild(groupPosition: Int, childPosition: Int): Any {
return parentList.get(groupPosition).subSteps!!.get(childPosition)
}
override fun getGroupId(groupPosition: Int): Long {
return groupPosition.toLong()
}
override fun getChildId(groupPosition: Int, childPosition: Int): Long {
return childPosition.toLong()
}
override fun hasStableIds(): Boolean {
return false
}
override fun getGroupView(
groupPosition: Int,
isExpanded: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
//Create group view
val v: View;
if(convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.steps_nested_group_view, parent, false)
}
else
{
v = convertView
}
val tv = v.findViewById<TextView>(R.id.steps_nested_group_title_tv)
tv.text = parentList.get(groupPosition).instructions
return v;
}
override fun getChildView(
groupPosition: Int,
childPosition: Int,
isLastChild: Boolean,
convertView: View?,
parent: ViewGroup?
): View {
val v: View
if(convertView == null)
{
v = LayoutInflater.from(con).inflate(R.layout.step_detail_view, parent, false)
}
else
{
v = convertView
}
val subStep = parentList.get(groupPosition).subSteps!!.get(childPosition)
val stepLineView = v.findViewById<View>(R.id.step_line_colour_view)
val stepTextView = v.findViewById<TextView>(R.id.step_item_tv)
stepLineView.setBackgroundColor(Color.parseColor(subStep.line!!.lineColour))
if(subStep.endStop == null)
{
stepTextView.text = subStep.instructions
}
else
{
stepTextView.text = subStep.endStop!!.name
}
return v;
}
override fun isChildSelectable(groupPosition: Int, childPosition: Int): Boolean {
return false
}
}
旅程对象
class Journey(legs: ArrayList<Leg>, sum: String, f: Fare?, p: Polyline, c: String) {
var legs: ArrayList<Leg> = legs;
var summary: String = sum;
var fare: Fare? = f;
var polyline: Polyline = p
var copyright: String = c
}
腿对象
class Leg(di: Distance, at: Date, dt: Date, st: ArrayList<Step>, du: Duration, sl: LatLng, el: LatLng, sa: String, ea: String) {
var distance: Distance = di;
var arrivalTime: Date = at;
var departureTime: Date = dt;
var steps: ArrayList<Step> = st;
var duration: Duration = du;
var startLoc: LatLng = sl;
var endLoc: LatLng = el;
var startAddress: String = sa;
var endAddress: String = ea;
}
步骤对象
class Step (i: String?, di: Distance?, du: Duration?, st: LatLng?, en: LatLng?, su: ArrayList<Step>?, m: String?, es: Stop?, ss: Stop?, ar: Date?, de: Date?, hd: Double?, he: String?, ns: Int?, li: Line?, p: Polyline?){
var instructions: String? = i;
var distance: Distance? = di;
var duration: Duration? = du;
var startLocation: LatLng? = st;
var endLocation: LatLng? = en;
var subSteps: ArrayList<Step>? = su;
var maneuver: String? = m;
var endStop: Stop? = es;
var startStop: Stop? = ss;
var arrivalTime: Date? = ar;
var departureTime: Date? = de;
var headway: Double? = hd;
var headsign: String? = he;
var numStops: Int? = ns;
var line: Line? = li;
var polyline: Polyline? = p
}
我是不是漏掉了什么?
我创建了一个自定义列表视图用作子列表视图:
父列表子view/child列表主视图(steps_nested_list_view):
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<NestedExpandableListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/steps_nested_expandable_list_view" />
</LinearLayout>
自定义代码 class:
class NestedExpandableListView(var con: Context, attributeSet: AttributeSet): ExpandableListView(con, attributeSet)
{
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
val int = Int.MAX_VALUE.shr(2)
super.onMeasure(widthMeasureSpec, MeasureSpec.makeMeasureSpec(int, MeasureSpec.AT_MOST))
}
}