android RecyclerView实现柱状图

信用卡欺诈检测项目实战 苦逼奋斗秋招ing???????????????????? 分享,互相进步 文章目录项目背景关键点读取数据数据预处理平衡样本模型训练模型评估总结: 项目背景 数据背景:数据集包含由欧洲人于2013年9月使用信用卡进行交易的数据。此数据集显示两天内发生的交易,其中284807笔交易中有492笔被盗刷。数据集非常不平衡,正例(被盗刷)占所有交易的0.172%。,这是因为由于保密问题,我们无法提供有关数据的原始功能和更多背景信息。特征V1,V2,… V28是使用PCA获得的主要组件,没有用PCA转换的唯一特征 阅读详情

android RecyclerView实现柱状图

先上效果图:
在这里插入图片描述

思路

  • 可以把每一个柱形图看作RecyclerView的单个item
  • 横向的RecyclerView,而且每个item宽度是固定的
  • item的高度,需要确定整个数据最大高度,然后按照比例来确定

实现

知识补充

不想看的可以直接跳过

setStackFromEnd

先讲关于RecyclerView的几个属性:layoutManager.setStackFromEnd(boolean) 和 layoutManager.setReverseLayout(boolean);

 public void setStackFromEnd(boolean stackFromEnd) {
        assertNotInLayoutOrScroll(null);
        if (mStackFromEnd == stackFromEnd) {
            return;
        }
        mStackFromEnd = stackFromEnd;
        requestLayout();
    }

setStackFromEnd()是设置数据填充是否从底部开始的,mStackFromEnd默认为flase。

setReverseLayout
public void setReverseLayout(boolean reverseLayout) {
        assertNotInLayoutOrScroll(null);
        if (reverseLayout == mReverseLayout) {
            return;
        }
        mReverseLayout = reverseLayout;
        requestLayout();
    }

setReverseLayout用于反转项目遍历和布局顺序。当设置为true时,会将第一项放置在ui的末尾类似,如此类推。mReverseLayout默认为false

组合使用
setStackFromEnd(false) && setReverseLayout(false)

这两种就是默认情况,代码如下

recyclerView = (RecyclerView) findViewById(R.id.rv_bill);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                this, LinearLayoutManager.HORIZONTAL, false);
        linearLayoutManager.setStackFromEnd(false);
        List<BillBean> billBeanArrayList = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            billBeanArrayList.add(new BillBean(i + ""));
        }
        BillListAdapter listAdapter = new BillListAdapter(this, billBeanArrayList);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(listAdapter);

效果如下:正常的显示
在这里插入图片描述

setStackFromEnd(true) && setReverseLayout(false)
recyclerView = (RecyclerView) findViewById(R.id.rv_bill);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                this, LinearLayoutManager.HORIZONTAL, false);
        linearLayoutManager.setStackFromEnd(true);
        List<BillBean> billBeanArrayList = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            billBeanArrayList.add(new BillBean(i + ""));
        }
        BillListAdapter listAdapter = new BillListAdapter(this, billBeanArrayList);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(listAdapter);

效果:列表的排序顺序还是正常的,但是数据先从末端排列开始,所以会自动展示在末尾。
在这里插入图片描述

setStackFromEnd(false) && setReverseLayout(true)
 recyclerView = (RecyclerView) findViewById(R.id.rv_bill);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                this, LinearLayoutManager.HORIZONTAL, true);
        linearLayoutManager.setStackFromEnd(false);
        List<BillBean> billBeanArrayList = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            billBeanArrayList.add(new BillBean(i + ""));
        }
        BillListAdapter listAdapter = new BillListAdapter(this, billBeanArrayList);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(listAdapter);

效果:倒过来排序,显示的是最开始的
在这里插入图片描述

setStackFromEnd(true) && setReverseLayout(true)

        recyclerView = (RecyclerView) findViewById(R.id.rv_bill);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                this, LinearLayoutManager.HORIZONTAL, true);
        linearLayoutManager.setStackFromEnd(true);
        List<BillBean> billBeanArrayList = new ArrayList<>();
        for (int i = 0; i < 12; i++) {
            billBeanArrayList.add(new BillBean(i + ""));
        }
        BillListAdapter listAdapter = new BillListAdapter(this, billBeanArrayList);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(listAdapter);

效果如下:顺序倒排,但是显示栈底的

在这里插入图片描述

实现部分

recyclerView部分

这里账单展示样式肯定是最近月份的要优先展示,所以要反向设置mLayoutManager.setReverseLayout(true);

 recyclerView = (RecyclerView) findViewById(R.id.rv_bill);
        LinearLayoutManager linearLayoutManager = new LinearLayoutManager(
                this, LinearLayoutManager.HORIZONTAL, true);
        BillListAdapter listAdapter = new BillListAdapter(this, billBeanArrayList);
        recyclerView.setLayoutManager(linearLayoutManager);
        recyclerView.setAdapter(listAdapter);
item实现部分

在这里插入图片描述
看图可以分为上面4块,可以直接用LinearLayout套住,或者自定义实现上面4块。这里采用自定义:
业务分析:先要考虑红色块的高度问题,金额最大和最低会可能相差很大的,这里最好获取列表最大值作为基准,每个金额去除以最大金额,获得自身高度的百分比。
业务显示数据类:根据要显示的内容,需要定义一个实体类来控制显示的内容。这里模拟为月账单业务,需要月份、最大金额(可自己先算好)、月金额、月份颜色、月金额颜色、柱状块颜色、线颜色(颜色也可以通过自定义属性设置)。

  package com.hujin.wan;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

public class BarItemView extends View {

    private Context mContext;
    private Paint linePaint;
    private int barColir;
    private int lineColor;
    private int moneyColor;
    private int timeColor;
    private Paint barPaint;
    private Paint moneyPaint;
    private Paint timePaint;
    private int width;
    private int heigt;
    private int lineHeigt;
    private int lineWidth;
    private int barHeight;
    private int maxBarHeight;
    private float animValue;
    private int animBarHeight;
    private int pos;

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


    public BarItemView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }


    public BarItemView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;

        TypedArray typedArray = mContext.obtainStyledAttributes(attrs, R.styleable.BarItemView);
        try {
            barColir = typedArray.getColor(R.styleable.BarItemView_barColor, Color.RED);
            lineColor = typedArray.getColor(R.styleable.BarItemView_lineColor, Color.GRAY);
            moneyColor = typedArray.getColor(R.styleable.BarItemView_moneyColor, Color.GRAY);
            timeColor = typedArray.getColor(R.styleable.BarItemView_textColor, Color.GRAY);
        } finally {
            typedArray.recycle();
        }
        init();
    }
    private BillBean billBean;
    private boolean hasAnimation;

    public void setValue(BillBean bean){
        this.billBean = bean;
    }

    public synchronized void updateValue(int position, BillBean bean, boolean hasAnimation) {
        this.pos = position;
        this.billBean = bean;
        this.hasAnimation=true;
        if(hasAnimation) {
            doAnimation();
        }
        postInvalidate();
    }

    ValueAnimator animator;
    private void doAnimation() {
        if (animator != null && animator.isRunning()) {
            animator.cancel();
        }
        animator = ValueAnimator.ofFloat(0, 1);
        animator.setDuration(1000);

        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                animValue = (float) animation.getAnimatedValue();
                invalidate();
            }
        });
        animator.start();
    }

    private void init() {
        initLinePaint();
        initBarPaint();
        initTimePaint();
        initMoneyPaint();
    }

    private void initMoneyPaint() {
        moneyPaint = new Paint();
        moneyPaint.setAntiAlias(true);
        moneyPaint.setColor(moneyColor);
        moneyPaint.setStyle(Paint.Style.FILL);
        moneyPaint.setStrokeWidth(2);

    }

    private void initTimePaint() {
        timePaint = new Paint();
        timePaint.setAntiAlias(true);
        timePaint.setColor(timeColor);
        timePaint.setStyle(Paint.Style.FILL);
        timePaint.setStrokeWidth(2);

    }

    private void initBarPaint() {
        barPaint = new Paint();
        barPaint.setAntiAlias(true);
        barPaint.setColor(barColir);
        barPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    }

    private void initLinePaint() {
        linePaint = new Paint();
        linePaint.setAntiAlias(true);
        linePaint.setColor(lineColor);
        linePaint.setStyle(Paint.Style.STROKE);
        linePaint.setStrokeWidth(2);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //宽度固定的,不需要测量了,高度由外表recyleview控制
        heigt = getMeasuredHeight();
        Log.e("距离1", "" + DisplayUtils.dip2px(60));
        width = lineWidth = (int) DisplayUtils.dip2px(60);
        //高度从上到下 ,下面越大
        lineHeigt = heigt - DisplayUtils.dip2px(32);
        //  宽度在外面限制了
        //计算 bar的最大高度 == 总高 - (月份整体高度+金额文字高度+线的高度+margin距离 * 2)
        Paint paint = new Paint();
        Rect rect = new Rect();
        paint.setTextSize(36);
        paint.getTextBounds("测试", 0, 1, rect);
        int textHeight = rect.height();
        Log.e("距离3", "" + textHeight);
        //bar最大高度 等于最大高度依次减去其他
        maxBarHeight = heigt - DisplayUtils.dip2px(32 + textHeight + 6 * 2 + 1);
        setMeasuredDimension(lineWidth, heigt);
    }


    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //真正的宽高
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if(hasAnimation) {
            animBarHeight = (int) (maxBarHeight * animValue);
        }else {
            animBarHeight = maxBarHeight;
        }
        drawLine(canvas);
        drawTime(canvas);
        drawBar(canvas);
        drawMoney(canvas);

    }

    private int marginForMoney = DisplayUtils.dip2px(6);

    private void drawMoney(Canvas canvas) {
        canvas.save();
        //动态的
        int height = lineHeigt - barHeight;

        Rect rect = new Rect();
        String money = String.valueOf(billBean.countAmt);
        timePaint.setTextSize(36);
        timePaint.getTextBounds(money, 0, money.length(), rect);

        //获得字符串的宽度
        float strNameFix = timePaint.measureText(money) / 2;
        canvas.drawText(money, width / 2 - rect.width() / 2, height - marginForMoney, timePaint);
    }

    private int barWidth = (int) DisplayUtils.dip2px(30);


    private void drawBar(Canvas canvas) {
        canvas.save();
        int barStartWidth = width / 2 - barWidth / 2;
        int barEndWidth = width / 2 + barWidth / 2;
        //倒角
        float arcRect = 15.0f;
        //高度
      //  Log.e("animBarHeight ==",pos+"  "+animBarHeight+""+"  value=="+animValue);
        barHeight = (int) (animBarHeight * billBean.percent);
        //这里要判断

        RectF oval1 = new RectF(barStartWidth,lineHeigt - barHeight + arcRect,barEndWidth,lineHeigt);
        RectF oval2 = new RectF(barStartWidth+arcRect,lineHeigt - barHeight,barEndWidth-arcRect,lineHeigt);
        RectF oval3 = new RectF(barStartWidth,lineHeigt -barHeight ,barStartWidth+2*arcRect,lineHeigt - barHeight+2*arcRect);
        RectF oval4 = new RectF(barEndWidth - 2*arcRect,lineHeigt -barHeight,barEndWidth,lineHeigt - barHeight+2*arcRect);
        canvas.drawRect(oval1, barPaint);
        canvas.drawRect(oval2, barPaint);
        canvas.drawArc(oval3,180,90,true,barPaint);
        canvas.drawArc(oval4,270,90,true,barPaint);
    }

    /**
     * 绘制 月份
     *
     * @param canvas
     */
    private void drawTime(Canvas canvas) {
        canvas.save();
        Rect rect = new Rect();
        String month = billBean.months;
        timePaint.setTextSize(34);
        timePaint.getTextBounds(month, 0, month.length(), rect);
        //获得字符串的宽度
        float strNameFix = timePaint.measureText(month) / 2;
        canvas.drawText(month, width / 2 - rect.width() / 2, getHeight() - DisplayUtils.dip2px(16) + rect.height() / 2, timePaint);

    }

    private void drawLine(Canvas canvas) {
        Path path = new Path();
        path.moveTo(0, lineHeigt);
        path.lineTo(lineWidth, lineHeigt);
        canvas.drawPath(path, linePaint);
    }

}

实体类(颜色再自定义属性里面)

public double countAmt;

    public String months;

    public boolean isAnim;

    public float percent;

    public BillBean(double countAmt, String months, boolean isAnim,double maxCount) {
        this.countAmt = countAmt;
        this.months = months;
        this.isAnim = isAnim;
        this.percent = (float) (countAmt/maxCount);
    }

item布局

<com.hujin.wan.BarItemView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/biv_item"
    app:lineColor="@color/colorAccent"
    android:layout_width="60dp"
    android:layout_height="match_parent"
    android:background="@color/colorPrimary" />

假数据部分

 List<BillBean> billBeanArrayList = new ArrayList<>();
        for (int i = 1; i < 13; i++) {
            billBeanArrayList.add(new BillBean(100*i,i+"月",true,12*100));
        }

最终效果

在这里插入图片描述

自定义View——横向柱状图 前言 最近在项目中需要实现一个简单的横向柱状图(如下图),需要实现在左边名字之后显示对应进度,同时进度之后需要跟上当前进度的内容。由于太菜找不到好的实现方法,于是决定使用自定义View实现。 实现 ps:这里我采取了一个偷懒的办法,只实现单个数据的柱状图,然后结合RecyclerView展示多个数据,同时还支持滑动,方便了不少。 单个柱状图比较简单,从左到右依次绘制标题、灰色条、进度条... 阅读详情

相关推荐

Android记账APP开发实战:从SQLite数据库到MPAndroidChart图表集成

在移动应用开发中,数据持久化与可视化是核心基础能力。SQLite作为Android内置的轻量级关系型数据库,通过SQLiteOpenHelper和原生API,开发者可以高效实现数据的增删改查(CRUD)操作,这是理解数据层架构的关键。掌握这些原理后,便能构建具备完整业务逻辑的应用,例如个人记账工具。这类应用不仅涉及数据库设计、DAO模式封装,还延伸到UI交互与数据统计。通过集成MPAndroidChart等开源库,可将查询结果转化为直观的饼图,实现消费数据的可视化分析,从而为个人财务管理等实用场景提供清晰洞

weixin_29284201的博客 311

RecycleView的layoutManager.setStackFromEnd(true)

layoutManager =new LinearLayoutManager(getActivity(), LinearLayoutManager.VERTICAL, false); 1 RecycleView中item从上到下依次添加,并且第一个添加的item始终在最上面,新添加的item需要滑下去才能看到。 2.使用 layoutManager =new LinearLayoutMan...

xiaodongvtion的专栏 4873

MPAndroidChart可滑动柱状图:数据窗口、手势与性能优化实战

数据可视化是移动应用展示信息的重要手段,柱状图常用于趋势对比。在Android平台实现可滑动柱状图,需理解图表滑动的本质是可视窗口在数据空间中移动。合理设置可视范围与手势开关,结合高效的数据装配与动态更新策略,才能保证流畅交互。以MPAndroidChart为例,解析Viewport机制、手势冲突、大数据量抽稀等关键技术,并分享常见踩坑与性能自检方法,帮助开发者快速构建稳健的滑动柱状图。

weixin_32520095的博客 238

Android之RecycleView类似聊天显示最底部数据

实现类似聊天列表,初始加载显示最底部数据,数据刷新重新显示最底部数据。 一、使用setStackFromEnd从底部开始加载数据。 LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mActivity); linearLayoutManager.setStackFromEnd(true); rv_view.se...

Zachary的基地 2961

安卓记账App开发实战:从SQLite到MPAndroidChart的期末大作业全解析

在移动应用开发中,SQLite作为轻量级关系型数据库,是Android本地数据持久化的核心方案,通过SQL语句即可高效完成增删改查与聚合统计。RecyclerView则是列表展示的利器,强制ViewHolder复用机制配合局部刷新,让大数据量场景下仍保持流畅体验。当需要直观呈现消费结构时,MPAndroidChart提供开箱即用的饼图与柱状图,帮助开发者快速实现数据可视化。这些技术共同构成了一个完整记账应用的基础:从数据库表设计、页面流转到统计图表渲染,再到最终APK签名打包。本文以安卓期末大作业为场景,完

weixin_34005090的博客 234

学生课程设计用的Android健康数据管理App源码(带图表分析与SQLite本地存储)

这个Android健康记录App源码专为高校计算机类课程设计打造,支持体重、血压、心率、步数、睡眠时长等多维度健康数据录入和长期跟踪。所有数据保存在本地SQLite数据库中,通过Room持久化库封装,结构清晰易维护。历史记录用RecyclerView列表展示,趋势分析借助MPAndroidChart生成折线图与柱状图,直观反映身体变化。支持一键导出CSV文件,方便后续Excel处理或教学检查。项目基于Android Studio标准工程构建,适配Android 5.0+,已通过真机和模拟器测试;gradle

rain6的博客 264

android多个柱状图和折线图,RecyclerView 实现柱状图和折线图

先上要实现的效果图Paste_Image.png整体布局android:orientation="vertical" android:layout_width="match_parent"android:background="@color/comm_white"android:layout_height="match_parent">android:layout_marginTop="24...

weixin_31557179的博客 649

安卓单词本App开发实战:SQLite存储与RecyclerView列表实现

在移动应用开发中,数据持久化与列表展示是构建高效APP的基础能力。SQLite作为轻量级关系型数据库,被广泛用于本地数据管理;RecyclerView作为Android官方推荐的列表控件,以灵活的布局管理和高效的视图复用机制,成为现代应用界面开发的核心组件。本文以期末课程设计常见的单词本应用为例,讲解如何基于Android平台实现单词的增删改查、搜索过滤及界面优化,涵盖数据库建表、DAO封装、适配器编写等关键工程实践,并探讨从SQLite迁移到Room的进阶思路。通过完整项目演示,帮助开发者掌握数据层与UI

weixin_34378767的博客 350

android自定义柱状图表,Android自定义柱状图控件

搜索github会发现已经有很多相对成熟的图表框架,但与我们拿到的ui效果图总会有一些差别,然后就会陷入是把别人源码下载下来修改之后作为已用,或是重新定义一个新控件的两难境地。初拿到效果图感觉还是比较复杂难以实现,但是仔细观察发现其实这就是一个列表,一个横向列表,一个可以用RecyclerView实现的列表。效果图.gif如果借助recyclerview的话,那么重点就在每个条目也就是柱状图每个柱...

weixin_39616565的博客 452

recyclerview实现柱状图折线图

1、通过实现recyclerview的ItemDecoration类实现折线图柱状图绘制 2、代码没有做优化及封装,希望给大家能扩展下思路 3、没有使用任何第三方的图表库 4、有什么问题欢迎留言讨论

Potplayer + LAVFilters + madVR 配置教程

文章目录Potplayer + LAVFilters + madVR 配置教程工具安装篇设置调教1.potplayer播放器设置加载LAVFilters和madVR1.选择“源滤镜/分离器”选项,选择“滤镜/解码器管理”2.“添加外部滤镜”3.浏览到刚才LAVFilters解压的文件夹,分别添加图示项。4.添加后回到管理界面设置,点击左边的”LAV AudioDecoder”,将右边”音频解码器”...

re 16万+

android 分组柱状图_Android自定义柱状图控件

搜索github会发现已经有很多相对成熟的图表框架,但与我们拿到的ui效果图总会有一些差别,然后就会陷入是把别人源码下载下来修改之后作为已用,或是重新定义一个新控件的两难境地。初拿到效果图感觉还是比较复杂难以实现,但是仔细观察发现其实这就是一个列表,一个横向列表,一个可以用RecyclerView实现的列表。效果图.gif如果借助recyclerview的话,那么重点就在每个条目也就是柱状图每个柱...

weixin_42558758的博客 411

《深入 UFS Explorer:自定义 RAID 配置指南》

UFS Explorer支持以虚拟模式组装任何受支持的RAID配置,以便后续访问其内容或恢复丢失数据。启动RAID构建器;向RAID构建器主内容区域的列表中添加RAID组件;为不可用组件插入占位符(需当前RAID级别支持且软件兼容);调整组件的准确顺序;在“虚拟RAID配置”区域设置RAID参数;以虚拟模式组装阵列各部分。程序主窗口“存储设备导航面板”中打开的任何存储设备(包括驱动器、逻辑卷、磁盘镜像、虚拟磁盘及其他复杂存储设备)均可作为RAID组件。

melonbo的专栏 1403

【自定义View】实现柱状图方法(一)

通过自定义View实现柱状图的方法有很多种,因为最近在公司做需求用到了这部分知识,所以在这里用文章记录一下最简单的方法之一,我选择是去定义每个柱状条的View,然后通过RecyclerView的网格布局实现需求。主要属性有:初始颜色画笔,染色画笔,圆柱高,圆柱宽(宽度一般为柱体的原的直径),最大容量,真实容量等// 初始颜色 private Paint paint;// 定义颜色 private float height;

薪火_的博客 664

AI智能体升级实战:从规则匹配到Function Call,准确率提升86%的技术选型之路

AI智能体升级实战:从规则匹配到Function Call的技术演进 文章记录了AI邮件助手从传统规则匹配升级到Function Call的技术迭代过程。通过案例分析,揭示了规则匹配的三大核心问题:覆盖不全(用户表达千变万化)、组合困难(多条件容易漏掉)、维护噩梦(每个需求都要新增规则)。测试数据显示,规则匹配在复杂查询中的准确率仅51%,严重影响用户体验。 技术团队对比了三种升级方案:1) 继续优化规则匹配(天花板明显);2) 微调专用NLP模型(成本高);3) 采用Function Call(灵活高效)

yweng18的博客 1079

【万字长文】学习Armv8架构虚拟化一篇就够了

这里我们将介绍一些基础的Hypervisor和虚拟化的理论知识。如果你已经有一定的基础或是已经熟悉了这些概念,可以跳过这部分内容。我们用Hypervisor这个词来定义一种负责创建,管理以及调度虚拟机(Virtual Machines, VMs)的软件。Stage 2 转换允许Hypervisor控制虚拟机的内存视图。具体来说,其可以控制虚拟机是否可以访问特定的某一块物理内存,以及该内存块出现在虚拟机内存空间的位置。这种能力对于虚拟机的隔离和沙箱功能来说至关重要。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 5313

MPAndroidChart实现折线图,单折线图,多折线图,饼图,蜘蛛网图,柱状图,单柱状图,多柱状图,组合图

复杂图表实现,MPAndroidChart实现折线图,单折线图,多折线图,饼图,蜘蛛网图,柱状图,单柱状图,多柱状图,组合图

恋兔de木子的博客 463

Android Qcom Display学习(十一)

该系列文章总目录链接与各部分简介:本章主要是基于MIPI Payload传输接口的学习,包括Generic和DCS的接口不同。底层都是基于去封装的,下面第一部分调用原生接口,第二部分分析高通是如何进行读写操作的。

Android驱动开发 3181

Android图表与RecyclerView集成:MPAndroidChart性能优化终极指南

MPAndroidChart是一个功能强大的Android图表库,支持折线图、柱状图、饼图等多种图表类型,以及缩放、平移和动画效果。本文将详细介绍如何将MPAndroidChart与RecyclerView高效集成,并分享实用的性能优化技巧,帮助开发者打造流畅的图表展示体验。 ## 为什么选择MPAndroidChart? MPAndroidChart作为GitHub上最受欢迎的Android

gitblog_00925的博客 775

古风仙侠少女三视图提示词,一键生成角色设定

3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。平视正交视角,统一光照,纯白背景,无文字无水印,避免强透视和动态变形。3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。3D中国写实CG风格,CG渲染质感,精细3D建模,PBR物理材质,细腻服装纹理,电影级灯光,丰富表情,高精度场景,次世代引擎画质。少女,古风仙侠少女气质,灵动、温婉、仙气。

欢迎来到鸾姝淡月博客,专为程序员和编程爱好者打造的技术博客。我们分享编程语言趋势、开发工具、编程哲学、职业发展等,助你掌握新技术,优化技能,激发编程热情。 1042

当AI学会写“自传”:OpenClaw 的 SOUL.md 如何把配置文件变成一颗会变形的心

SOUL.md。

步子哥的博客 1309

recyclerview实现柱形图

最近做项目有个图片界面显示树状图,看到效果图就直接去网上找轮子了,比较知名的MPA和hollowChar,结果两个都用了,一个比一个坑(功能挺强大,不适用我的项目),最后还是自己写了一个。先看下实现的效果 很简单,Y轴显示刻度,X轴显示中文(XY轴的值可以自定义),柱子多了可以左右滑动,每个柱子显示当前点的值,需求就是这么简单。 再来说说MPA的缺点,1,当数据少的时候柱子特别宽,2,还有就是

caobin_study的博客 543

DA14531-蓝牙温度传感器-真实案例

传感器低功耗系统功能需求: 1)平时为关机状态,通过GPIO管脚唤醒,霍尔器件触发拉低IO唤醒系统。 2)唤醒后,进入BLE广播状态,等待主机连接,若一分钟无被主机连接,则进入关机状态。 3)连接后(0.1mA),每秒上报一次温度值,同时主机可以读取设备读电池电量。 4)连接断开后,1分钟后,设备进入关机(1uA)。 5)LED灯在连接时点亮,断开灭,低电量时会闪,提示闪烁。

hejinwu1314的博客 856

140款Android开源优秀项目源码

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

quan333的博客 3204

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

android 模仿Keep的训练统计(横向 RecyclerView 实现picker)

1、概述 keep 的运动统计界面,滑动的柱状图很炫酷。想着怎么实现 2、模仿效果 3、实现思路 多操作几遍,感觉keep的效果就是一个横向的picker,及:横向滑动,自动选择中间一项,点击item也可以自动滚动该item(这个只是锦上添花)。 就按横向picker进行思考,google 了一些实现。发现用recycleView其实是很方便做横向 picker的。参考:添加链接描述 3.1、值得提的点 SnapHelper 可以自动滚动一个item,实现吸合效果 其他都是顺其自然的点: Rec

1141

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

上一篇: OPPO崩溃问题解决
下一篇: Glide4.0+使用
HUandroid
博客等级 码龄10年 35粉丝 113原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值