首页 > 其他分享 >安卓开发级联显示菜单-省市区显示举例

安卓开发级联显示菜单-省市区显示举例

时间:2023-06-21 10:01:48浏览次数:41  
标签:级联 val 安卓 fun Organization var import 省市区 view

问题背景

安卓日常开发过程,经常会有需要级联显示的场景,比如省市区显示等,或者各种组织结构级联显示,本文将介绍安卓开发过程实现级联显示的一种方案。 实现效果如下: 1687311831086.gif

问题分析

思路分析: 考虑将要是的省、市、区设计成一种字典迭代结构,数据结构如下:

/**
 * 组织实体类
 */
class Organization(var name: String, var subList: MutableList<Organization>?)

这种数据结构,当前页面即可显示当前组织的子列表内容,比较方便。 话不多少,直接上代码: (1)数据结构实体类

/**
 * 组织实体类
 */
class Organization(var name: String, var subList: MutableList<Organization>?)

(2)页面显示activity,代码如下:

package com.baorant.kotlinorganization

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.recyclerview.widget.LinearLayoutManager
import com.baorant.kotlinorganization.databinding.ActivityMainBinding

class MainActivity : AppCompatActivity() {
    private lateinit var activityMainBinding: ActivityMainBinding
    private lateinit var topListAdapter : TopAdapter
    private val topList = mutableListOf<Organization>()

    private val organizationList = mutableListOf<Organization>()
    private lateinit var subOrgListAdapter : OrganizationAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        activityMainBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(activityMainBinding.root)

        initView()

        initData()
    }

    private fun initData() {
        // 模拟省市区级联数据
        val organization111 = Organization("南关区", null);
        val organization112 = Organization("朝阳区", null);
        val organization113 = Organization("绿园区", null);
        val organization110List = ArrayList<Organization>()
        organization110List.add(organization111)
        organization110List.add(organization112)
        organization110List.add(organization113)

        val organization121 = Organization("丰满区", null);
        val organization122 = Organization("龙潭区", null);
        val organization123 = Organization("蛟河区", null);
        val organization120List = ArrayList<Organization>()
        organization120List.add(organization121)
        organization120List.add(organization122)
        organization120List.add(organization123)

        val organization11 = Organization("长春市", organization110List)
        var organization12 = Organization("吉林市", organization120List)

        val organization11List = ArrayList<Organization>()
        organization11List.add(organization11)
        organization11List.add(organization12)

        val organization1 = Organization("吉林省", organization11List);
        organizationList.add(organization1)
        subOrgListAdapter.notifyDataSetChanged()

    }

    private fun initView() {
        // 显示层级的横向列表
        val layoutManager = LinearLayoutManager(this)
        layoutManager.orientation = LinearLayoutManager.HORIZONTAL
        activityMainBinding.recyclerView.layoutManager = layoutManager
        topListAdapter = TopAdapter(topList)
        topListAdapter.setOnItemClickListener(object: OnItemClickListener{
            override fun onItemClick(view: View, position: Int) {
                val organization = topList[position]
                organizationList.clear()
                organization.subList?.let { organizationList.addAll(it) }
                subOrgListAdapter.notifyDataSetChanged()

                val temList = mutableListOf<Organization>()
                for (index in topList.indices) {
                    if (index <= position) {
                        temList.add(topList[index])
                    }
                }
                topList.clear()
                topList.addAll(temList)
                topListAdapter.notifyDataSetChanged()
            }
        })
        activityMainBinding.recyclerView.adapter = topListAdapter

        // 展示当前层级子项的纵向列表
        val subLayoutManager = LinearLayoutManager(this)
        activityMainBinding.subOrgList.layoutManager = subLayoutManager

        subOrgListAdapter = OrganizationAdapter(organizationList)
        subOrgListAdapter.setOnItemClickListener(object : OnItemClickListener {
            override fun onItemClick(view: View, position: Int) {
                val organization = organizationList[position]
                if (organization.subList == null) {
                    return
                }
                organizationList.clear()
                organization.subList?.let { organizationList.addAll(it) }
                subOrgListAdapter.notifyDataSetChanged()

                topList.add(organization)
                topListAdapter.notifyDataSetChanged()
            }
        })
        activityMainBinding.subOrgList.adapter = subOrgListAdapter
    }
}

(3)activity对应布局layout文件,代码如下:

<?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"
    tools:context=".MainActivity">

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

        <LinearLayout
            android:id="@+id/ll_top_recycler"
            android:layout_width="match_parent"
            android:layout_height="42dp"
            android:background="@color/white"
            android:gravity="center_horizontal">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/recyclerView"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:scrollbars="none" />
        </LinearLayout>

        <ScrollView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/ll_top_recycler"
            android:scrollbars="none">

            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">
                <!--subOrg-->
                <TextView
                    android:layout_marginTop="10dp"
                    android:layout_height="wrap_content"
                    android:layout_width="wrap_content"
                    android:text="下级内容列表" />

                <androidx.recyclerview.widget.RecyclerView
                    android:id="@+id/subOrgList"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content" />
            </LinearLayout>
        </ScrollView>
    </RelativeLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

(4)纵向子列表对应adapter,代码如下:

package com.baorant.kotlinorganization

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

/**
 * 纵向子列表对应adapter
 */
class OrganizationAdapter(var organizationList:List<Organization>) : RecyclerView.Adapter<OrganizationAdapter.ViewHolder>() {
    private lateinit var onItemClickListener: OnItemClickListener

    //在内部类里面获取到item里面的组件
    inner class ViewHolder(view:View):RecyclerView.ViewHolder(view){
        var newName:TextView=view.findViewById(R.id.name)
    }

    //重写的第一个方法,用来给制定加载那个类型的Recycler布局
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.list_item,parent,false)
        val viewHolder = ViewHolder(view)
        //单机事件
        viewHolder.itemView.setOnClickListener {
            val position = viewHolder.adapterPosition
            onItemClickListener.onItemClick(viewHolder.itemView, position)
        }

        return viewHolder
    }

    fun setOnItemClickListener(listener: OnItemClickListener) {
        this.onItemClickListener = listener
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val organization = organizationList[position]

        holder.newName.text = organization.name
    }

    override fun getItemCount(): Int {
        return organizationList.size
    }
}

(5)上方横向列表对应adapter,代码如下:

package com.baorant.kotlinorganization

import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView

/**
 * 上方横向列表对应adapter
 */
class TopAdapter(var organizationList:List<Organization>) : RecyclerView.Adapter<TopAdapter.ViewHolder>() {
    private lateinit var onItemClickListener: OnItemClickListener

    //在内部类里面获取到item里面的组件
    inner class ViewHolder(view:View):RecyclerView.ViewHolder(view){
        var newName:TextView=view.findViewById(R.id.name)
    }

    //重写的第一个方法,用来给制定加载那个类型的Recycler布局
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        Log.d("baorant", "onCreateViewHolder begin")
        val view = LayoutInflater.from(parent.context).inflate(R.layout.top_list_item,parent,false)
        val viewHolder = ViewHolder(view)
        // 点击事件
        viewHolder.itemView.setOnClickListener {
            val position = viewHolder.adapterPosition
            onItemClickListener.onItemClick(viewHolder.itemView, position)
        }

        return viewHolder
    }

    fun setOnItemClickListener(listener: OnItemClickListener) {
        this.onItemClickListener = listener
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Log.d("baorant", "onBindViewHolder begin")
        val organization = organizationList[position]

        holder.newName.text = organization.name
    }

    override fun getItemCount(): Int {
        Log.d("baorant", "getItemCount begin")
        return organizationList.size
    }
}

(6)自定义接口,代码如下:

/**
 * 自定义接口,适配recyclerview点击事件adapter
 */
interface OnItemClickListener {
    fun onItemClick(view: View, position: Int)
}

问题总结

本文介绍了安卓开发过程实现级联显示的一种方案,有兴趣的同学可以进一步深入研究。

标签:级联,val,安卓,fun,Organization,var,import,省市区,view
From: https://blog.51cto.com/baorant24/6527483

相关文章

  • 基于安卓的智能语音识别系统
    本文通过对市场上的大多数用户量比较大的手机APP是使用的调查,并对调查结果做出需求分析后,确定了基于安卓客户端的语音识别和语音合成的功能设计方案。实现了在手机端可以调用手机的客户端麦克风进行语音的录入和识别,同时也实现了文本信息朗读和合成的技术。本设计的框架为Android......
  • pixel 3xl 编译安卓与内核并烧入全流程(含安卓源码部分编译)
    pixel3xl编译安卓与内核并烧入全流程(含安卓源码部分编译)目录pixel3xl编译安卓与内核并烧入全流程(含安卓源码部分编译)环境搭建安卓源码下载一、准备下载环境1、安装Python3.92、安装git3、安装curl4、配置环境变量安装repo二、下载源代码1、创建目录2、初始化仓库3、同步安......
  • 树莓派、PS4、Switch、STM32、安卓、iOS
    系统架构树莓派:基于ARMCortex-A系列处理器(如Cortex-A53)的Linux操作系统。PS4:基于x86-64架构的FreeBSD操作系统。Switch:基于ARMv8-A架构的NvidiaCustom操作系统,也被称为“HorizonOS”。STM32:无操作系统或基于实时操作系统(RTOS)的固件(裸机)编程。安卓:基于Linux内核的软件堆栈......
  • 前端Vue自定义简单实用中国省市区三级联动选择器
    前端Vue自定义简单实用中国省市区三级联动选择器,请访问uni-app插件市场地址:https://ext.dcloud.net.cn/plugin?id=13118效果图如下:使用方法<!--themeColor:主题颜色ref:设置唯一refpickerValueDefault:默认选择@onCancel:取消事件@onConfirm:确认事件--><cc-city-......
  • Compose能拯救安卓开发吗?Jetpack Compose入门到精通(附资料)含实战、附Demo
    JetpackCompose简述JetpackCompose是用于构建原生AndroidUI的现代工具包。JetpackCompose使用更少的代码,强大的工具和直观的KotlinAPI,简化并加速了Android上的UI开发。这是AndroidDevelopers官网对它的描述。由于Compose基于Kotlin构建,因此可以与Java编程语言完全互操作,并......
  • 关于flutter框架安卓应用抓包问题,以及解决方法
    参考文档https://bbs.kanxue.com/thread-261941.htm一.从安装的app所在文件夹目录中提出libflutter.socd/data/app/包名/lib/xxx/..../...libflutter.so二.将其拖入ida中进行分析字符串窗口搜索ssl_server按x进入F5看了一下和上面博客说的相似不理解上面说的也......
  • 布局性能优化:安卓开发者不可错过的性能优化技巧
    今天总结一下布局的性能优化,这是一个系列,上一篇是#内存泄漏大集结:安卓开发者不可错过的性能优化技巧也可以看性能优化专栏里的记录,都是非常好的开发经验。当我们开发Android应用时,布局性能优化是一个必不可少的过程。一个高效的布局能够提高用户体验,使应用更加流畅、响应更加迅速......
  • unity将安卓streamingAssetsPath文件复制到persistentDataPath
    privatevoidTestCopy(){stringfrom=Application.streamingAssetsPath+"/Test/test.txt";stringto=Application.persistentDataPath+"/Test/";CopyFile(from,to);}publicstaticvoidCopyFile(stringsourcePath,stringdesti......
  • MT8168核心板,MTK8168安卓核心板模块
    MT8168核心板是一款高度集成的高性能应用处理器,适用于平板电脑、电子阅读器以及智能家居或物联网应用等嵌入式设备,具备出色的多媒体体验和极低的功耗。该处理器采用先进的12纳米工艺,将四核ArmCortex-A53MPCoreTMCPU与最高运行频率2GHz的ArmNEON引擎以及最高运行频率800MHz......
  • EasyCVR平台如何推送RTMP流实现上级平台级联?
    EasyCVR可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有GB28181、RTSP/Onvif、RTMP等,以及厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等,能对外分发RTSP、RTMP、FLV、HLS、WebRTC等格式的视频流。有用户反馈,现场的设备是运动相机,不支持国标和其他协议接入......