MarkerView

2023-11-02

前言:

过了一个愉快的五一后,我们又开始上班了,完成了本分的工作,抽点时间来和说说MarkerView咯。给我的印象,MarkerView的扩展性很强。它可以自定义自己想要的U样式.

MarkerView源码

/**
 * View that can be displayed when selecting values in the chart. Extend this class to provide custom layouts for your
 * markers.
 *
 * @author Philipp Jahoda
 */
public class MarkerView extends RelativeLayout implements IMarker {

    private MPPointF mOffset = new MPPointF();
    private MPPointF mOffset2 = new MPPointF();
    private WeakReference<Chart> mWeakChart;

    /**
     * Constructor. Sets up the MarkerView with a custom layout resource.
     *
     * @param context
     * @param layoutResource the layout resource to use for the MarkerView
     */
    public MarkerView(Context context, int layoutResource) {
        super(context);
        setupLayoutResource(layoutResource);
    }

    /**
     * Sets the layout resource for a custom MarkerView.
     *
     * @param layoutResource
     */
    private void setupLayoutResource(int layoutResource) {

        View inflated = LayoutInflater.from(getContext()).inflate(layoutResource, this);

        inflated.setLayoutParams(new LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT));
        inflated.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));

        // measure(getWidth(), getHeight());
        inflated.layout(0, 0, inflated.getMeasuredWidth(), inflated.getMeasuredHeight());
    }

    public void setOffset(MPPointF offset) {
        mOffset = offset;

        if (mOffset == null) {
            mOffset = new MPPointF();
        }
    }

    public void setOffset(float offsetX, float offsetY) {
        mOffset.x = offsetX;
        mOffset.y = offsetY;
    }

    @Override
    public MPPointF getOffset() {
        return mOffset;
    }

    public void setChartView(Chart chart) {
        mWeakChart = new WeakReference<>(chart);
    }

    public Chart getChartView() {
        return mWeakChart == null ? null : mWeakChart.get();
    }

    @Override
    public MPPointF getOffsetForDrawingAtPoint(float posX, float posY) {

        MPPointF offset = getOffset();
        mOffset2.x = offset.x;
        mOffset2.y = offset.y;

        Chart chart = getChartView();

        float width = getWidth();
        float height = getHeight();

        if (posX + mOffset2.x < 0) {
            mOffset2.x = - posX;
        } else if (chart != null && posX + width + mOffset2.x > chart.getWidth()) {
            mOffset2.x = chart.getWidth() - posX - width;
        }

        if (posY + mOffset2.y < 0) {
            mOffset2.y = - posY;
        } else if (chart != null && posY + height + mOffset2.y > chart.getHeight()) {
            mOffset2.y = chart.getHeight() - posY - height;
        }

        return mOffset2;
    }

    @Override
    public void refreshContent(Entry e, Highlight highlight) {

        measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
        layout(0, 0, getMeasuredWidth(), getMeasuredHeight());

    }

    @Override
    public void draw(Canvas canvas, float posX, float posY) {

        MPPointF offset = getOffsetForDrawingAtPoint(posX, posY);

        int saveId = canvas.save();
        // translate to the correct position and draw
        canvas.translate(posX + offset.x, posY + offset.y);
        draw(canvas);
        canvas.restoreToCount(saveId);
    }
}

MarkerView继承了RelativeLayout,所以说它相当于一个View容器,你只管往里面放View就好了。至于啥样子,就不管了,由你来掌控。它还实现了IMarker接口,IMarker接口中的方法有如下几个:

    MPPointF getOffset();

    MPPointF getOffsetForDrawingAtPoint(float posX, float posY);

    void refreshContent(Entry e, Highlight highlight);

    void draw(Canvas canvas, float posX, float posY);

draw方法,就是去画你自定义的MarkerView的内容,posX,posY,就是画在指定的点。
refreshContent方法,顾名思义,就是刷新MarkerView的内容。传了两个参数,一个是Entry,一个是Highlight,可以知道,这个与Highlight有密切的关系。也就是说,只有在选择了一个Entry高亮显示了,才会画出这个刷新画出MarkerView。
getOffsetForDrawingAtPoint方法,与画的点的位置有关系,一个偏移量
getOffset方法,就是偏移量咯。

实际使用

在MarkerView中还有一个方法被我们忽视了,setupLayoutResource(int layoutResource)。这个方法就是加载你自定义的xml文件。我们来看下demo中自定义的MarkerView。

public class MyMarkerView extends MarkerView {

    private TextView tvContent;

    public MyMarkerView(Context context, int layoutResource) {
        super(context, layoutResource);

        tvContent = (TextView) findViewById(R.id.tvContent);
    }

    // callbacks everytime the MarkerView is redrawn, can be used to update the
    // content (user-interface)
    @Override
    public void refreshContent(Entry e, Highlight highlight) {

        if (e instanceof CandleEntry) {

            CandleEntry ce = (CandleEntry) e;

            tvContent.setText("" + Utils.formatNumber(ce.getHigh(), 0, true));
        } else {

            tvContent.setText("" + Utils.formatNumber(e.getY(), 0, true));
        }

        super.refreshContent(e, highlight);
    }

    @Override
    public MPPointF getOffset() {
        return new MPPointF(-(getWidth() / 2), -getHeight());
    }
}

重写了refreshContent方法 , getOffset()方法。如何使用的呢?

 MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
        mv.setChartView(mChart); // For bounds control
        mChart.setMarker(mv); // Set the marker to the chart

先new 一个MyMarkerView,然后设置到Chart中去。在绘制的时候就可以绘制你自定义的xml了。在Chart中有一个drawMarkers方法:

protected void drawMarkers(Canvas canvas) {

        // if there is no marker view or drawing marker is disabled
        if (mMarker == null || !isDrawMarkersEnabled() || !valuesToHighlight())
            return;

        for (int i = 0; i < mIndicesToHighlight.length; i++) {

            Highlight highlight = mIndicesToHighlight[i];

            IDataSet set = mData.getDataSetByIndex(highlight.getDataSetIndex());

            Entry e = mData.getEntryForHighlight(mIndicesToHighlight[i]);
            int entryIndex = set.getEntryIndex(e);

            // make sure entry not null
            if (e == null || entryIndex > set.getEntryCount() * mAnimator.getPhaseX())
                continue;

            float[] pos = getMarkerPosition(highlight);

            // check bounds
            if (!mViewPortHandler.isInBounds(pos[0], pos[1]))
                continue;

            // callbacks to update the content
            mMarker.refreshContent(e, highlight);

            // draw the marker
            mMarker.draw(canvas, pos[0], pos[1]);
        }
    }

最主要的就是最后两行代码,先刷新UI,再去画。以上就是对MarkerView的介绍了。下次再会!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MarkerView 的相关文章

  • 如何为 Android 创建我们自己的 PDF 查看器?

    我想构建一个可在我的 Android 应用程序中使用的 PDF 阅读器 查看器 但我无法使用 Google 文档来阅读我的内容 我无法使用我的设备中已安装的任何 PDF 阅读器 它应该位于我的应用程序内 并且不会通过互联网公开我的安全内容
  • 在 Android 上生成 FileDescriptor 而不先打开文件

    在Android中 是否可以直接从字节数组生成FileDescriptor 而不必先打开文件 在 Android 2 2 中 我动态生成 MIDI 文件 然后使用 MediaPlayer 进行播放 我在下面包含了成功执行此操作的 Main
  • 在 Android 模拟器上运行完整的 Android 手机 ROM

    正如标题所说 是否可以在 Android 模拟器中运行完整的 Android 设备 ROM 是的 你可以 但让它 100 工作可能很困难 大多数 ROM 都包含其运行硬件的特定驱动程序 我并不是 100 全力以赴 但可以尝试以下步骤 创建
  • Android:java.lang.OutOfMemoryError:

    我在 Android 上开发了一个使用大量图像的应用程序 可绘制文件夹中有很多图像 比如说超过 100 张 我正在开发图像动画应用程序 我使用 imageview 来显示 GIF 图像 我使用了将 gif 图像分割成多个 PNG 格式图像的
  • Android Toast 消息不起作用

    我正在通过 Andengine 为 Android 开发游戏 我有 MainActivity 类和 GameScene 类 我在 GameActivity 中使用 Toast 消息 它正在发挥作用 Toast makeText this H
  • 单击另一个项目/小部件时展开/打开微调器?

    当用户单击另一个按钮时 我试图展开微调器 例如 我有一个带有值的微调器和一个 确定 按钮 当用户单击 确定 按钮而不从微调器中选择任何值时 微调器会自行扩展 是否可以在无需用户与微调器交互的情况下获得扩展微调器的事件 只需致电Spinner
  • animation.start() 或animation.startNow() 不会立即开始动画

    我有一个奇怪的问题 有时应该淡出我的控件 ImageButton 的动画不会立即启动 我使用淡出动画来隐藏它 然后在 myListener 的末尾 onAnimationEnd 中 我将新资源作为按钮上的图像 我的应用程序代码中的某处 An
  • Android 软键盘 - 禁用某些键

    我正在寻找一种使用内置软键盘并禁用某些键的方法 例如 如果用户不应该使用字母 f 因为在列表中该字母不存在 则该键应显示为灰色 想象一下 用户可以在文本框中键入文本以从列表中进行选择 该列表包含 ABC BCCD 床 如果用户输入 A 然后
  • Android:将图像裁剪为特定尺寸

    我的目的是让用户从图库中选择一张图像 然后进行裁剪活动 但是 我需要将定义裁剪蒙版的矩形锁定到某个尺寸 然后用户只需重新定位它即可显示图像的一部分 关于如何做到这一点有什么想法吗 Thanks T Intent intent new Int
  • 使用全局变量从内部函数获取空字符串

    请帮助我解决一些小问题 我确信你能做到 D 我试图在 firestore 文档 user cases information 上设置一个字段 其中包含一个字段 case number 首先我声明这个全局变量 private String c
  • 如果未安装应用程序,深层链接将重定向到 Play 商店

    我在我的应用程序中使用深度链接的概念 我真正想要的是 当我共享我的应用程序中的链接时 它工作正常 它会转到我想在我的应用程序中打开的活动 但问题是当用户没有这个时应用程序此链接通过手机浏览器打开 显示错误 未找到 但如果未安装应用程序 我想
  • 返回到上一个活动的最后状态

    我有两个活动 A 和 B 当应用程序启动时 活动 A 会被加载 我会从数据库将数据加载到其中 我可以毫无问题地转到活动 B 但是当我返回活动 A 时 会查看旧数据一段时间 然后重新加载活动 知道如何解决这个问题吗 在从数据库加载数据之前清除
  • Ionic 框架 - Config.xml

    我需要修改 config xml 文件 因此在针对 Android 进行编译时我会获取以下权限
  • Firebase 身份验证中是否需要 SMS Retriever API 才能进行 otp 自动填充?

    我在用Firebase auth api验证用户电话号码 目前 就我而言 我有一个屏幕 用户在其中输入电话号码 并在第二个屏幕上输入密码 根据文档firebase大多数时候自动检索 OTP 并启动验证过程 所以我的问题是它已经实现了SMS
  • 具有隐式授权的 OAuth 应用程序中的客户端模拟

    来自 OAuth 草案 隐式section https datatracker ietf org doc html draft ietf oauth v2 31 section 1 3 2 在隐式授权流程期间发出访问令牌时 授权服务器不对客
  • 如何在android中将文本放在单选按钮的左侧

    我想将单选按钮的文本放在左侧而不是右侧 我找到了这个解决方案
  • PhoneGap Build Android 不显示闪屏

    这是我的 config xml 中与启动屏幕相关的代码
  • 连接到具有相同 SSID 的最强接入点(信号最强的接入点)

    我正在编写一个程序来始终连接到最强的接入点 我的意思是信号最强的接入点 首先 我扫描所有可用的 WiFi 网络 然后限制它们仅查看具有相同 SSID 的网络 这样我就可以看到一个网络的所有AP 当我连接到该网络时 它没有连接到最强的信号 但
  • 使用部分字符串匹配进行 Firebase 查询[重复]

    这个问题在这里已经有答案了 假设我有一个简单的 firebase 实时数据库结构 其中关键是username其值为userid 现在我想搜索userid by username 如果用户名匹配 这很容易 但如何获得部分匹配的答案 更清楚地说
  • 如何使用socket.io发送图像文件(二进制数据)?

    我无法从以下位置发送数据Android Client to NodeJS Server I use Socket IO 客户端 https github com socketio socket io client java我的客户端中的ja

随机推荐

  • streamstring

    这是从http www cnblogs com yaozhongxiao archive 2009 05 23 1487903 html拿来的 希望作者不要介意 1 sstream 在C 有两种字符串流 一种在sstream中定义 另一种在
  • FPN详解

    论文题目 Feature Pyramid Networks for Object Detection 论文链接 论文链接 论文代码 Caffe版本代码链接 一 FPN初探 1 图像金字塔 图1 图像金字塔 图2 高斯金字塔效果 如上图所示
  • 【恒指早盘分析】9.18恒指今日复盘及后市思路

    9月18日消息 美股周二小幅收高 市场正在等待美联储货币政策会议结果 沙特称原油生产设施遭袭造成的产能损失已恢复50 预计月底将完全恢复 今日开盘 港股恒指高开0 18 午后转跌 截至收盘 恒生指数 26754 12 36 12 0 13
  • 服务器巡检都做什么工作,巡检的手段是什么?

    服务器巡检都做什么工作 服务器巡检主要分为 1 对于基础资源的巡检 比如说磁盘 cpu 内存的利用率有没有达到公司设定的阈值范围之上 如果达到了就需要及时扩容或者杀进程 2 核心业务的巡检 跟钱打交道的程序 对核心业务的相关指标监控的图形
  • 解决root@localhost's password:localhost:permission denied,please try again

    背景 在装完hadoop及jdk之后 在执行start all sh的时候出现 root localhost s password localhost permission denied please try again 可是 我记得当时设
  • 计算机视觉与深度学习-经典网络解析-ZFNet-[北邮鲁鹏]

    这里写目录标题 ZFNet 主要改进 减小第一层卷积核 将第二 第三个卷积层的卷积步长都设置为2 增加了第三 第四个卷积层的卷积核个数 ZFNet ZFNet是一种基于AlexNet的模型 由Matthew D Zeiler和Rob Fer
  • smplayer中使用srt字幕乱码问题

    选择菜单 选项 gt 首选项 gt 字幕 选择默认字幕编码cp936 简体中文 和正确的中文字体 本文转自JustRun博客园博客 原文链接 http www cnblogs com JustRun1983 archive 2012 10
  • 用户画像技术干货

    1 用户画像是什么 在互联网步入大数据时代后 用户行为给企业的产品和服务带来了一系列的改变和重塑 其中最大的变化在于 用户的一切行为在企业面前是可 追溯 分析 的 企业内保存了大量的原始数据和各种业务数据 这是企业经营活动的真实记录 如何更
  • 在传统公司干IT是一种什么体验(五)

    与不懂技术的人交流 最痛苦的不是你说的她听不懂 而是她自以为懂帝 强行把概念降低到她能所理解的层面 然后丰富的经验来指导你 表哥语录 表哥以前最喜欢当老师 例尤其是公司新来的同事 都愿意找表哥请教技术问题 自动去了新公司之后 表哥天天面对不
  • 内网穿透神器-frp的概念,搭建和使用,方便访问内网服务

    FRP概念 FRP是什么 借助官网的描述 frp 是一个专注于内网穿透的高性能的反向代理应用 支持 TCP UDP HTTP HTTPS 等多种协议 且支持 P2P 通信 可以将内网服务以安全 便捷的方式通过具有公网 IP 节点的中转暴露到
  • sql注入;基于时间盲注;sqli-labs/less-9;

    1 搭建好环境 连好数据库 这里看我这篇文章 可以找到网盘文件 sql注入之报错注入 这里用到的是sqli labs Less 1 也就是第一关 利用报错信息注入 小乘杭的博客 CSDN博客 2 无真假 报错回显 通过时间延迟判断 3 通过
  • Hadoop Kerberos安全机制

    Hadoop Kerberos安全机制 1 背景 在Hadoop1 0 0或者CDH3 版本之前 hadoop并不存在安全认证一说 默认集群内所有的节点都是可靠的 值得信赖的 用户与HDFS或者M R进行交互时并不需要进行验证 导致存在恶意
  • Pyramid pooling module(PPM)

    参考代码 https blog csdn net wd18508423052 article details 93882113 上采样问题可以参考 https blog csdn net zouxiaolv article details
  • Unity无法打开项目的解决方法

    Unity无法打开项目的解决方法 这两天硬盘突然大量文件损坏导致一些项目无法打开 如Unity的项目在hub窗口打开项目后就会卡死报错 求助他人以后基本问题得到了解决 故记录一下 遇到项目无法打开的情况后 尝试正常建立新项目 发现工程能正常
  • C语言-蓝桥杯-算法提高 01背包

    问题描述 给定N个物品 每个物品有一个重量W和一个价值V 你有一个能装M重量的背包 问怎么装使得所装价值最大 每个物品只有一个 输入格式 输入的第一行包含两个整数n m 分别表示物品的个数和背包能装重量 以后N行每行两个数Wi和Vi 表示物
  • 稳压二极管的串联与并联

    稳压二极管又叫齐纳二极管 是一种用于稳定电压的二极管 注 其承受电流非常小 需要根据场合使用 常见类型 其组合方式有串联与并联 串联 串联有以上四种方式 图1 10V和8V稳压管均击穿 VCC为两者稳压值的和 VCC 10 8 18V 图2
  • 整理java集合

    1 map 实现类 HashMap 无序 键值可为null 非同步 Hashtable 无序 键值非null 作键的对象必须实现 hashCode 方法和 equals 同步 性能低 LinkedHashMap 有序记录插入顺序 如果在映射
  • 【超详细Python秒杀代码】京东淘宝抢购通用

    由于之前手动抢购枪神7超竞连续失败两次后怒学脚本抢购 今天给大家分享一期超简单 直观 好用的Python脚本 此代码目前仅适用于可以加入购物车的商品 直接上代码 import datetime import time from seleni
  • 为什么机油使用后变红_汽车机油用完后放出油红色怎么回事

    展开全部 汽车e68a84e8a2ad62616964757a686964616f31333433623861机油用完后放出油红色的原因为 因为汽车添加的机油油品出现问题了 劣质机油往往都没有很好的润滑冷却作用 不仅无法清除发动机内部的积碳
  • MarkerView

    前言 过了一个愉快的五一后 我们又开始上班了 完成了本分的工作 抽点时间来和说说MarkerView咯 给我的印象 MarkerView的扩展性很强 它可以自定义自己想要的U样式 MarkerView源码 View that can be