仿网易严选物流界面

2023-10-09 22:59
文章标签 界面 物流 网易 严选

本文主要是介绍仿网易严选物流界面,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

    • 最终效果
    • 环境
    • 原理分析
    • 效果实现
      • attr属性
      • LogisticsLayout 实现
      • 初步效果
      • 最终实现

最终效果

最终效果

环境

AndroidStudio 3.1.2
compileSdkVersion 27

原理分析

1 从效果图可以看出,每条物流信息基本都是重复的布局(左侧稍有区别),因此我们只需要自定义物流条目即可,无需把整个效果作为自定义View.

2 最容易想到的方式就是直接利用 RecyclerView 实现.我们只要控制 Item 改变左侧样式即可.

3 本文利用自定义 View 继承 RelativeLayout 实现,暂时叫做 LogisticsLayout
Item

4 上图是一个自定义 LogisticsLayout , 因为继承自 RelativeLayout 所以右边的两行展示可以直接写在布局的 xml 中,然后距离左侧留出一定的距离,这样 LogisticsLayoutonLayout() 阶段会自动完成子孩子的绘制,我们只需要在 onDraw() 阶段绘制左侧圆点和虚线即可.这里需要注意的是 Item 之间是没有 divier 的,上图下方的空白是 Item 自身的 padding 或者 margin 属性. 这两个属性占据的高度是 Item 的高度的一部分.

5 绘制左侧效果时,区分三种情况,首部,普通,尾部.

首部普通尾部
颜色红色颜色灰色颜色灰色
虚线从圆点到bottom虚线占据整个高度虚线从top至圆点

6 条目中的电话高亮以及点击后自动拨号,我们直接使用 TextViewandroid:autoLink="phone"属性

效果实现

attr属性

定义一个可在xml使用的属性,用于限定左侧宽度. 这样做是为了方便维护.当然你也可以直接写死在 View 中.

在 values 文件夹下创建 attrs.xml 并写入下面代码

<?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="LogisticsLayout"><attr name="left_margin" format="dimension" /></declare-styleable>
</resources>

这里只定义一个 left_margin 即可

LogisticsLayout 实现


public class LogisticsLayout extends RelativeLayout {Paint linePaint;Paint circlePaint;// 左侧绘制范围的宽度,此值作为基准,float totalWidth;float totalHeight;float radius;float centerX;float marginTop;float dottedLen;public LogisticsLayout(Context context) {this(context, null);}public LogisticsLayout(Context context, AttributeSet attrs) {this(context, attrs, 0);}public LogisticsLayout(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.LogisticsLayout);try {totalWidth = array.getDimension(R.styleable.LogisticsLayout_left_margin, 60);centerX = totalWidth * 0.5f;radius = totalWidth * 0.1f;marginTop = totalWidth * 0.3f;dottedLen = totalWidth / 15;} finally {array.recycle();}init();}private void init() {linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);linePaint.setStyle(Paint.Style.FILL);linePaint.setStrokeWidth(3);linePaint.setColor(Color.GRAY);circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);circlePaint.setStyle(Paint.Style.FILL);circlePaint.setColor(Color.GRAY);// 清除标记,因为 ViewGroup 作为容器,默认不会触发 onDraw() 方法setWillNotDraw(false);//关闭硬件加速 这里非常重要, 不然虚线等没有效果setLayerType(View.LAYER_TYPE_SOFTWARE, null);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);totalHeight = getHeight();System.out.println(totalWidth + " " + totalHeight + "hp");// 画虚线drawLine(canvas);// 画圆点drawCircle(canvas);}private void drawLine(Canvas canvas) {linePaint.setPathEffect(new DashPathEffect(new float[]{dottedLen, dottedLen}, 2));canvas.drawLine(centerX, 0, centerX, totalHeight, linePaint);}private void drawCircle(Canvas canvas) {canvas.drawCircle(centerX, marginTop, radius, circlePaint);}
}
注意几点
初始化时定义关键参数,其中以左侧宽度为基准,根据比例定义出 centerX, radius 等.这样做有助于不同屏幕的适配
画虚线和圆点,这部分比较简单,只需要第一步定义好位置参数,作图代码只需三行.
init() 方法中最后两行需要注意. 其中为了实现 ViewGroup 的 onDraw() 方法调用也可以采用在 xml 中设置背景的方式.
关闭硬件加速是为了实现某些特殊效果,例如虚线,阴影等

初步效果

LogisticsLayout 为布局跟节点,配合 RecyclerView 展示初步效果
Item布局:

<?xml version="1.0" encoding="utf-8"?>
<com.example.hepan.logistics.LogisticsLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/apk/res-auto"android:layout_width="match_parent"android:layout_height="wrap_content"tools:left_margin="50dp"><TextView
        android:id="@+id/tvTime"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginLeft="50dp"android:autoLink="phone"android:text="时间" /><TextView
        android:id="@+id/tvDesc"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/tvTime"android:layout_marginBottom="20dp"android:layout_marginLeft="50dp"android:autoLink="phone"android:text="描述" />
</com.example.hepan.logistics.LogisticsLayout>

结合 RecyclerView 效果
这里写图片描述

最终实现

上面的效果距离目标还有一定的距离.我们需要给 LogisticsLayout 添加判定类型类型的方法,以便在绘图时有所区别
1 在末尾添加 state 属性,并需改 drawLine drawCircle 方法

private void drawLine(Canvas canvas) {linePaint.setPathEffect(new DashPathEffect(new float[]{dottedLen, dottedLen}, 2));if (state == State.STATE_HEADER) {canvas.drawLine(centerX, marginTop, centerX, totalHeight, linePaint);} else if (state == State.STATE_FOOTER) {canvas.drawLine(centerX, 0, centerX, marginTop, linePaint);} else {canvas.drawLine(centerX, 0, centerX, totalHeight, linePaint);}}private void drawCircle(Canvas canvas) {if (state == State.STATE_HEADER) {circlePaint.setColor(Color.RED);canvas.drawCircle(centerX, marginTop, radius, circlePaint);} else {canvas.drawCircle(centerX, marginTop, radius, circlePaint);}}@Stateprivate int state = State.STATE_NORMAL;@Retention(RetentionPolicy.SOURCE)@IntDef({State.STATE_HEADER, State.STATE_NORMAL, State.STATE_FOOTER})public @interface State {int STATE_HEADER = 0;int STATE_NORMAL = 1;int STATE_FOOTER = 2;}public int getState() {return state;}public void setState(int state) {this.state = state;}

2 在适配器中设置属性

override fun onBindViewHolder(holder: ViewHolder, position: Int) {when (position) {0 -> {//设置属性holder.itemView.root.state = LogisticsLayout.State.STATE_HEADER//字体颜色holder.itemView.tvTime.setTextColor(Color.RED)holder.itemView.tvDesc.setTextColor(Color.RED)}data.size - 1 -> holder.itemView.root.state = LogisticsLayout.State.STATE_FOOTERelse -> holder.itemView.root.state = LogisticsLayout.State.STATE_NORMAL}holder.itemView.tvDesc.text = data[position].split("\n")[0]holder.itemView.tvTime.text = data[position].split("\n")[1]}
修改后效果 这里写图片描述 注意几点
我这里用的 kotlin, when() 其实就是switch() 语句, .() 就是 set**()
onBindViewHolder 周期中 View 还未真正绘制,此处设置属性时不用内部调用 postInvalidate(); 等方法
用字符串模拟了条目的物流信息,其中用\n隔开
电话的颜色显示是以 colors.xml 文件中 <color name="colorAccent">****</color> 为默认值的.也就是app的强调色,如果想改变的话可以自定义 TextView 样式设置对应属性值.

备注

感谢何天鹏组长,本文思路是参考其代码完成的

项目地址 希望能有所帮助

这篇关于仿网易严选物流界面的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/176154

相关文章

京东物流查询|开发者调用API接口实现

快递聚合查询的优势 1、高效整合多种快递信息。2、实时动态更新。3、自动化管理流程。 聚合国内外1500家快递公司的物流信息查询服务,使用API接口查询京东物流的便捷步骤,首先选择专业的数据平台的快递API接口:物流快递查询API接口-单号查询API - 探数数据 以下示例是参考的示例代码: import requestsurl = "http://api.tanshuapi.com/a

一款支持同一个屏幕界面同时播放多个视频的视频播放软件

GridPlayer 是一款基于 VLC 的免费开源跨平台多视频同步播放工具,支持在一块屏幕上同时播放多个视频。其主要功能包括: 多视频播放:用户可以在一个窗口中同时播放任意数量的视频,数量仅受硬件性能限制。支持多种格式和流媒体:GridPlayer 支持所有由 VLC 支持的视频格式以及流媒体 URL(如 m3u8 链接)。自定义网格布局:用户可以配置播放器的网格布局,以适应不同的观看需求。硬

centOS7.0设置默认进入字符界面

刚装的,带有x window桌面,每次都是进的桌面,想改成自动进命令行的。记得以前是修改 /etc/inittab 但是这个版本inittab里的内容不一样了没有id:x:initdefault这一行而且我手动加上也不管用,这个centos 7下 /etc/inittab 的内容 Targets systemd uses targets which serve a simil

AI 与大模型:物流行业的变革力量

一、物流行业的现状与挑战 物流行业在现代经济中扮演着至关重要的角色,但目前也面临着诸多挑战。 在效率方面,交通拥堵是一个突出问题。许多城市道路容量不足,无法满足日益增长的货物运输需求,导致运输时间延长。例如,在一些大城市,货物运输常常因交通拥堵而延迟,影响了整个供应链的效率。此外,信息不对称也严重影响了物流效率。供应商和购买方之间缺乏实时信息共享平台,双方无法准确了解货物的到达时间、配送状

Appium--界面元素选择

在操作界面元素前,我们需要进行手机与电脑的连接,这里介绍一个adb无线连接的方法: Adb无线连接功能 无线连接步骤(确保手机和电脑处于同一局域网) 1先以USB有线连接方式连接到计算机 2激活手机adb的无线服务: 命令行输入adb tcpip 5555(5555是端口号) 3计算机以无线方式连接到手机: 命令行输入adb connect 配置信息 desired_caps:这些键值对告诉ap

大厂算法例题解之网易2018秋招笔试真题 (未完)

1、字符串碎片 【题目描述】一个由小写字母组成的字符串可以看成一些同一字母的最大碎片组成的。例如,“aaabbaaac” 是由下面碎片组成的:‘aaa’,‘bb’,‘c’。牛牛现在给定一个字符串,请你帮助计算这个字符串的所有碎片的 平均长度是多少。 输入描述: 输入包括一个字符串 s,字符串 s 的长度 length(1 ≤ length ≤ 50),s 只含小写字母(‘a’-‘z’) 输出描述

【YOLO 系列】基于YOLOV8的智能花卉分类检测系统【python源码+Pyqt5界面+数据集+训练代码】

前言: 花朵作为自然界中的重要组成部分,不仅在生态学上具有重要意义,也在园艺、农业以及艺术领域中占有一席之地。随着图像识别技术的发展,自动化的花朵分类对于植物研究、生物多样性保护以及园艺爱好者来说变得越发重要。为了提高花朵分类的效率和准确性,我们启动了基于YOLO V8的花朵分类智能识别系统项目。该项目利用深度学习技术,通过分析花朵图像,自动识别并分类不同种类的花朵,为用户提供一个高效的花朵识别

【虚拟机/服务器】非图形化界面下修改Shell中颜色的设置

1、首先 cd ~ && ll 可以看到如下图所示 2、输入 sudo vim .bashrc 进入 .bashrc 并通过 /PS1 迅速从上往下定位第一个PS1 3、输入 i 进入插入模式后修改 else 下面的配置如下 说明:\e[1;32;40m] 其中1表示高亮显示,32表示字体颜色是绿色,40表示背景色为黑色 4、输入 esc 退出编辑模式到命令模式,再输入

【视频教程】手把手AppWizard轻松制作一个emWin滑动主界面控制框架,任意跳转控制(2024-09-06)

现在的新版AppWizard已经比较好用,用户可以轻松的创建各种项目常规界面。 比如早期创建一个支持滑动的主界面框架,并且可以跳转各种子界面,仅仅界面布局和各种图片格式转换都要花不少时间,而现在使用AppWizard,可以说轻轻松松,毫不费力。 用户唯一要做的就是根据自己的芯片性能做一定的速度优化。 视频: https://www.bilibili.com/video/BV17Rp3eLE

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录(失败记录)

ubuntu 20.04 一直卡在登录界面,即使密码正确也无法登录 这次是装实体机,一次失败的尝试。。。 名称型号CPUIntel Xeon E5-2673 V3GPURTX 3060 mobile 安装的时候不要选install third-party software for graphics and Wi-fi hardware and additional media