列表吸顶分组之按首字母分组国家选区号

列表粘性分组之按首字母分组国家选区号

Android原生版本

直接先看UI图,效果如下

在这里插入图片描述
本来看起来也不难,我就想着上面常用区号那块不动,下面的列表滑动就行,但IOS说他滑动的时候上面也滑上去了,好吧,这也行;但最终效果做出来后,IOS滑动后会有按照国家名称首字母进行粘性分组,好吧,为了提升自己,我也决定做得跟IOS一样,不说废话了,直接上代码
引入流布局控件

//流布局
api 'com.google.android:flexbox:1.0.0'

布局

<?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:id="@+id/rl_content"
    android:layout_width="match_parent"
    android:layout_height="@dimen/dp_area_code_pop_height"
    app:defaultColor="@color/white"
    app:topLeftRadius="@dimen/dp_10"
    app:topRightRadius="@dimen/dp_10"
    tools:background="@color/white">

    <TextView
        android:id="@+id/tv_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_gravity="center"
        android:paddingVertical="@dimen/dp_20"
        android:text="@string/sel_international_code"
        android:textColor="@color/col_3a3b3d"
        android:textSize="@dimen/sp_18" />

    <com.yunqu.quyun_res.widget.StatusLayout
        android:id="@+id/status"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_title"
        app:status="LOADING"
        app:toolsStatus="NORMAL">

        <ProgressBar
            style="?android:attr/progressBarStyleSmall"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center"
            app:layout_status="LOADING" />

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            app:layout_status="NORMAL">

            <androidx.recyclerview.widget.RecyclerView
                android:id="@+id/rv_general"
                android:background="@color/white"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:paddingHorizontal="@dimen/dp_20"
                android:paddingVertical="@dimen/dp_10"
                tools:itemCount="4"
                tools:listitem="@layout/item_general_code" />

        </FrameLayout>

    </com.yunqu.quyun_res.widget.StatusLayout>

    <View
        android:id="@+id/v_divider"
        android:layout_width="match_parent"
        android:layout_height="@dimen/dp_0_5"
        android:layout_above="@id/tv_cancel"
        android:background="@color/col_e0e7ee" />

    <Button
        android:id="@+id/tv_cancel"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:background="@color/white"
        android:gravity="center"
        android:paddingVertical="@dimen/dp_17"
        android:text="@string/cancel"
        android:textColor="@color/col_3a3b3d"
        android:textSize="@dimen/sp_16"
        app:textPressedColor="@color/col_acb2b8" />

    <com.yunqu.quyun_res.widget.TenXuLetterBar
        android:id="@+id/txlb"
        android:layout_width="@dimen/dp_15"
        android:layout_height="wrap_content"
        android:layout_below="@id/tv_title"
        android:layout_alignBottom="@id/v_divider"
        android:layout_alignParentEnd="true"
        android:layout_marginTop="@dimen/dp_70"
        android:layout_marginEnd="@dimen/dp_20"
        android:layout_marginBottom="@dimen/dp_10"
        android:minHeight="@dimen/dp_area_code_mh"
        app:txlb_item_background_def="@drawable/bg_letter_def"
        app:txlb_item_background_sel="@drawable/bg_letter_sel"
        app:txlb_item_text_color_def="@color/col_9b9b9b"
        app:txlb_item_text_color_sel="@color/white" />

    <TextView
        android:id="@+id/tv_letter"
        android:layout_width="@dimen/dp_55"
        android:layout_height="@dimen/dp_55"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:background="@drawable/bg_circle_80000000"
        android:gravity="center"
        android:textColor="@color/white"
        android:textSize="18sp"
        android:visibility="gone"
        tools:visibility="visible" />

</RelativeLayout>

item_common_code.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingBottom="@dimen/dp_10"
    tools:ignore="MissingDefaultResource">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_commons"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:nestedScrollingEnabled="false"
        tools:itemCount="2"
        tools:listitem="@layout/item_common_code" />

</FrameLayout>

item_common_code_tip.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    tools:ignore="MissingDefaultResource">

    <TextView
        android:id="@+id/tv_common_tip"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/common_code"
        android:textColor="@color/col_9b9b9b"
        android:textSize="@dimen/sp_14" />

</FrameLayout>

item_general_code.xml

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

    <TextView
        android:id="@+id/tv_code"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingVertical="@dimen/dp_12"
        android:includeFontPadding="false"
        android:textColor="@color/col_111212"
        android:textSize="@dimen/sp_14"
        tools:text="中国大陆+86" />

</LinearLayout>

item_general_code_group.xml

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

    <LinearLayout
        android:id="@+id/ll_letter"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        tools:ignore="UselessParent">

        <TextView
            android:id="@+id/tv_letter"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textColor="@color/col_111212"
            android:textSize="@dimen/sp_14"
            android:textStyle="bold"
            tools:text="A" />

        <View
            android:layout_width="match_parent"
            android:layout_height="@dimen/dp_0_5"
            android:layout_marginTop="@dimen/dp_10"
            android:background="@color/col_e0e7ee" />

    </LinearLayout>

</LinearLayout>

其中com.yunqu.quyun_res.widget.StatusLayout控件是自定义的一个FrameLayout状态控件,这里就不放出来了,其实主要就是控制加载数据过程中的切换,根据逻辑用GONE和VISIBLE也是一样的

com.yunqu.quyun_res.widget.TenXuLetterBar控件代码如下

public class TenXuLetterBar extends View {
   
    private static final String TAG = "TenXuLetterBar";

    //    private final List<String> mLetters = new ArrayList<>();
    private final String[] mLettersHadWell = new String[]{
   "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"
            , "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "#"};
    private final String[] mLetters = new String[]{
   "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"
            , "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};

    private final Paint mPaint;

    private Drawable mItemBackgroundDef;
    private Drawable mItemBackgroundSel;
    private final int mItemTextColorDef;
    private final int mItemTextColorSel;
    private final boolean mNeedWell;
    //    private int mLetterWidth;

    private int mLetterIndex = -1;

    private OnLetterChangeListner onLetterChangeListener;//选中字母后的回调

    public TenXuLetterBar(Context context) {
   
        this(context, null);
    }

    public TenXuLetterBar(Context context, AttributeSet attrs) {
   
        this(context, attrs, 0);
    }

    public TenXuLetterBar(Context context, AttributeSet attrs, int defStyleAttr) {
   
        super(context, attrs, defStyleAttr);
        TypedArray typedArray =
                context.obtainStyledAttributes(attrs, R.styleable.TenXuLetterBar);

        mItemBackgroundDef = typedArray.getDrawable(

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/435048.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mysql从旧表 取出部分列并保存到新表几种方式介绍

在MySQL中&#xff0c;从旧表取出部分列并保存到新表有多种方式&#xff0c;主要包括以下几种&#xff1a; 1. 使用INSERT INTO ... SELECT语句&#xff1a; 这是最常用的方法。通过SELECT语句从旧表中选择需要的数据&#xff0c;然后使用INSERT INTO语句将数据…

cesium-切分地图

在cesium中只看想看到的部分地图&#xff0c;其他的隐藏。 做法如下 import {ArrowRight} from element-plus/icons-vue import {onMounted, ref, watch} from "vue"; import * as Cesium from "cesium"; import InitCesium from "../js/InitCesiumH…

快速了解Redis

Redis是什么&#xff1f; Redis是一个数据库&#xff0c;是一个跨平台的非关系型数据库&#xff0c;Redis完全开源&#xff0c;遵守BSD协议。它通过键值对(Key-Value)的形式存储数据。 它与mysql数据库有什么区别&#xff1f; redis通过键值对(Key-Value)的形式存储数据&…

【AI视野·今日Robot 机器人论文速览 第八十三期】Wed, 6 Mar 2024

AI视野今日CS.Robotics 机器人学论文速览 Wed, 6 Mar 2024 Totally 30 papers &#x1f449;上期速览✈更多精彩请移步主页 Interesting: &#x1f4da;SpaceHopper,外星探索多功能三足机器人 (from Robotic Systems Lab, ETH Zurich) Daily Robotics Papers A Safety-Criti…

《探索虚拟与现实的边界:VR与AR谁更能引领未来?》

引言 在当今数字时代&#xff0c;虚拟现实&#xff08;VR&#xff09;和增强现实&#xff08;AR&#xff09;技术正以惊人的速度发展&#xff0c;并逐渐渗透到我们的日常生活中。它们正在重新定义人与技术、人与环境之间的关系&#xff0c;同时也为各行各业带来了全新的可能性。…

LeetCode刷题---填充每个节点的下一个右侧节点指针 II

题解:LeetCode题解 解题思想&#xff1a; 通过创建辅助指针来解决该问题 当当前节点cur不为空的时候&#xff0c;创建辅助节点dummy&#xff0c;使其一直作为每一层的第一个节点的前一个节点。 创建辅助指针pre&#xff0c;pre初始指向dummy&#xff0c;之后通过pre来填充当前层…

JVM-整体结构原理深度解析

JVM定义 JVM是Java Virtual Machine&#xff08;Java虚拟机&#xff09;的缩写&#xff0c;JVM是一种用于计算设备的规范&#xff0c;它是一个虚构出来的计算机&#xff0c;是通过在实际的计算机上仿真模拟各种计算机功能来实现的。 引入Java语言虚拟机后&#xff0c;Java语言在…

Tensorflow2.0笔记 - 常见激活函数sigmoid,tanh和relu

本笔记主要记录常见的三个激活函数sigmoid&#xff0c;tanh和relu&#xff0c;关于激活函数详细的描述&#xff0c;可以参考这里&#xff1a; 详解激活函数&#xff08;Sigmoid/Tanh/ReLU/Leaky ReLu等&#xff09; - 知乎 import tensorflow as tf import numpy as nptf.__ve…

spring boot3token拦截器链的设计与实现

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 写在前面 流程分析 需要清楚的 实现步骤 1.定义拦截器 2.创建拦截器链配置类 3.配置拦截器链顺序 4.配置拦截…

StarRocks实战——松果出行实时数仓实践

目录 一、背景 二、松果出行实时OLAP的演进 2.1 实时数仓1.0的架构 2.2 实时数仓2.0的架构 2.3 实时数仓3.0的架构 三、StarRocks 的引入 四、StarRocks在松果出行的应用 4.1 在订单业务中的应用 4.2 在车辆方向的应用 4.3 StarRocks “极速统一” 落地 4.4 StarRoc…

设计模式-结构型模式-享元模式

享元模式&#xff08;Flyweight&#xff09;&#xff0c;运用共享技术有效地支持大量细粒度的对象。[DP] 解决对象的开销问题&#xff0c;像围棋&#xff0c;一盘棋理论上有361个空位可以放棋子&#xff0c;那如果用常规的面向对象方式编程&#xff0c;每盘棋都可能有两三百个…

记录第一次使用QT

今晚和舍友准备搞一个QT网盘的项目&#xff0c;我之前也没有用过QT。在舍友的指导下&#xff0c;我安装了QT creator&#xff0c;然后完成了第一次的QT的编译运行&#xff0c;记录一下这激动的感觉&#xff08;2024-03-07)。 使用qmake进行的编译。qDebug进行输出调试hello qt…

FedDefender: Client-Side Attack-Tolerant Federated Learning

与现有的大部分方法不同&#xff0c;FedDefender是在客户端层面的防御机制。 方法叠的有点多 大部分方法都在④这一步防御&#xff0c;通过设计鲁邦的聚合策略等&#xff0c;但是本文通过修改本地训练策略&#xff0c;来更新模型&#xff0c;文章主要基于两个观点&#xff1a; …

机器学习的边界与实际应用

目录 前言1 机器学习的广泛适用性1.1. 利用输入输出映射1.2. 大量的可用数据 2 机器学习能做的事情举例2.1 自动驾驶2.2 用户请求处理2.3 有大量数据的医学影像诊断 3 机器学习不能做的事情举例3.1 市场分析报告3.2 感同身受的邮件回复3.3 手势意图判断3.4 少量数据的医学影像诊…

真Unity-Editor二次开发-ScriptableObject 可自定义UI界面

关于ScriptablObject自定义 作为官方指定的&#xff0c;曾经我也吐槽过ScriptableObject很鸡肋&#xff0c;个人曾经也是强烈反对在项目中使用&#xff0c;但直到我今天看到下面这个代码&#xff0c;菜发现其实只是自己太菜鸡而已 --------------不想多写什么 -------------…

无人机生态环境监测、图像处理与GIS数据分析

构建“天空地”一体化监测体系是新形势下生态、环境、水文、农业、林业、气象等资源环境领域的重大需求&#xff0c;无人机生态环境监测在一体化监测体系中扮演着极其重要的角色。通过无人机航空遥感技术可以实现对地表空间要素的立体观测&#xff0c;获取丰富多样的地理空间数…

Java面试篇【JVM】常见面试题(2024最新)

JVM 1. Java内存区域详解 线程私有&#xff1a;程序计数器&#xff0c;虚拟机栈&#xff0c;本地方法栈 线程共享的&#xff1a;堆&#xff0c;方法区&#xff0c;直接内存 1.1 各个区域详解 程序计数器 每个线程需要一个计数器记录自己执行到哪一行了。线程之间切换需要保存…

LVS集群---二

1.LVS工作模式和相关命令 1.1LVS集群工作模式 - lvs-nat&#xff1a;修改请求报文的目标IP,多目标IP的DNAT- lvs-dr&#xff1a;操纵封装新的MAC地址&#xff08;直接路由&#xff09;- lvs-tun&#xff1a;隧道模式 1.1.1 LVS的NAT模式 lvs-nat&#xff1a;本质是多目标IP的…

flutter 使用webview

背景&#xff1a; 一般都有使用webview加载网页的需求&#xff0c;比如加载隐私协议、用户协议等。 如何做&#xff1a; 当然&#xff0c;我们自己不用封装轮子&#xff0c;在pub.dev上有成熟的轮子&#xff1a;webview_flutter 首先&#xff0c;将依赖导入&#xff0c;在pub…

MooC下载pdf转为ppt后去除水印方法

1、从MooC下载的课件&#xff08;一般为pdf文件&#xff09;可能带有水印&#xff0c;如下图所示&#xff1a; 2、将pdf版课件转为ppt后&#xff0c;同样带有水印&#xff0c;如下图所示&#xff1a; 3、传统从pdf中去除水印方法不通用&#xff0c;未找到有效去除课件pdf方法…