当前位置: 首页 > 知识库问答 >
问题:

如何设置自定义值

公羊灿
2023-03-14

我正在使用MPAndroidChart显示一个相对简单的条形图。

有2件事我需要设置,我不知道如何自定义:

>

  • 我需要为每个条添加文本,而不是简单的值,每个条本身也有样式。

    在每个条的顶部,我需要放置各种类型的可绘制材料来覆盖它的宽度(例如一个条中高度为2dp的蓝色,或另一个条上高度相同的黄色渐变)。

    下面是我需要做的一个演示:

    >

    我知道我也可以通过使用setDrawIcons添加图标,但这似乎不适用于应该使用整个条形宽度的绘图。

    正如我写的,我想知道以上是否可能,以及如何做到:

    >

    如何设置不同的drawable以“坐”在每个酒吧的顶部?

    如果#2不可能(即使可能),是否可以将可绘制设置为条形本身?例如,一些条是纯灰色,而一些条是渐变黄色,可绘制?

  • 共有1个答案

    能翔宇
    2023-03-14

    您需要自定义条形图渲染器来实现这一点。我提供了一个粗略的样品。希望有帮助。

    用于设置条形图的代码

        public class MainActivity extends AppCompatActivity {
    
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            // custom colors that you want on top of the bars
            ArrayList<Integer> myColors = new ArrayList<>();
            myColors.add(Color.BLACK);
            myColors.add(Color.YELLOW);
            myColors.add(Color.BLUE);
            myColors.add(Color.DKGRAY);
            myColors.add(Color.GREEN);
            myColors.add(Color.GRAY);
    
            String[] myText = {"A Round", "B Round", "C Round", "D Round", "E Round", "F Round"};
    
    
            BarChart mChart = (BarChart) findViewById(R.id.barChart);
            mChart.setDrawBarShadow(false);
            mChart.getDescription().setEnabled(false);
            mChart.setDrawGridBackground(false);
    
            XAxis xaxis = mChart.getXAxis();
            xaxis.setDrawGridLines(false);
            xaxis.setPosition(XAxis.XAxisPosition.BOTTOM);
    
            xaxis.setDrawLabels(true);
            xaxis.setDrawAxisLine(false);
    
            YAxis yAxisLeft = mChart.getAxisLeft();
            yAxisLeft.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);
            yAxisLeft.setDrawGridLines(false);
            yAxisLeft.setDrawAxisLine(false);
            yAxisLeft.setEnabled(false);
    
            mChart.getAxisRight().setEnabled(false);
            // set your custom renderer
            mChart.setRenderer(new BarChartCustomRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), myColors));
            mChart.setDrawValueAboveBar(true);
    
            Legend legend = mChart.getLegend();
            legend.setEnabled(false);
    
            ArrayList<BarEntry> valueSet1 = new ArrayList<BarEntry>();
    
            for (int i = 0; i < 6; ++i) {
                BarEntry entry = new BarEntry(i, (i + 1) * 10);
                valueSet1.add(entry);
            }
    
    
            List<IBarDataSet> dataSets = new ArrayList<>();
            BarDataSet barDataSet = new BarDataSet(valueSet1, " ");
            barDataSet.setValueFormatter(new MyFormatter(myText));
            barDataSet.setColor(Color.CYAN);
            dataSets.add(barDataSet);
    
            BarData data = new BarData(dataSets);
            mChart.setData(data);
        }
    
    
        public class MyFormatter implements IValueFormatter {
    
            String[] text;
    
            public MyFormatter(String[] text) {
                this.text = text;
            }
    
            @Override
            public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
                return String.valueOf((int)value)+"M" + ", " + text[(int) entry.getX()];
            }
        }
    
    
    }
    

    自定义渲染器

        public class BarChartCustomRenderer extends BarChartRenderer {
    
        private Paint myPaint;
        private ArrayList<Integer> myColors;
    
        public BarChartCustomRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, ArrayList<Integer> myColors) {
            super(chart, animator, viewPortHandler);
            this.myPaint = new Paint();
            this.myColors = myColors;
        }
    
        @Override
        public void drawValues(Canvas c) {
            super.drawValues(c);
            // you can modify the original method
            // so that everything is drawn on the canvas inside a single loop
            // also you can add logic here to meet your requirements
            int colorIndex = 0;
            for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {
                BarBuffer buffer = mBarBuffers[i];
                float left, right, top, bottom;
                for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {
                    myPaint.setColor(myColors.get(colorIndex++));
                    left = buffer.buffer[j];
                    right = buffer.buffer[j + 2];
                    top = buffer.buffer[j + 1];
                    bottom = buffer.buffer[j + 3];
    //                myPaint.setShader(new LinearGradient(left,top,right,bottom, Color.CYAN, myColors.get(colorIndex++), Shader.TileMode.MIRROR ));
                    c.drawRect(left, top, right, top+5f, myPaint);
                }
            }
        }
    
        @Override
        public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) {
            String text = formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler);
            String[] splitText;
            if(text.contains(",")){
                splitText = text.split(",");
                Paint paintStyleOne = new Paint(mValuePaint);
                Paint paintStyleTwo = new Paint(mValuePaint);
                paintStyleOne.setColor(Color.BLACK);
                paintStyleTwo.setColor(Color.BLUE);
                c.drawText(splitText[0], x, y-20f, paintStyleOne);
                c.drawText(splitText[1], x, y, paintStyleTwo);
            }
            //else{
    //            super.drawValue(c, formatter, value, entry, dataSetIndex, x, y, color);
            //}
        }
    }
    

    结果

    您还可以通过稍微修改自定义渲染器为整个栏做渐变效果:

    myPaint.setShader(new LinearGradient(left,top,right,bottom, Color.CYAN, myColors.get(colorIndex++), Shader.TileMode.MIRROR ));
    c.drawRect(left, top, right, bottom, myPaint);
    

    类似地,可以使用自定义渲染器绘制文本并设置其样式。选中此选项可了解有关自定义渲染器的更多信息。

    更新使用绘图而不是颜色

    //get bitmap from a drawable
    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.myDrawable);
    

    之后,您可以创建位图列表并传递到渲染器而不是颜色列表。

    如果要仅在条形图的顶部绘制,可以使用以下选项:

    c.drawBitmap(bitmap.get(index++), null, new RectF(left, top, right, top+5f), null);
    

    或者,如果要覆盖整个条,可以使用如下位图:

    c.drawBitmap(bitmap.get(index++), null, new RectF(left, top, right, bottom), null);
    
     类似资料:
    • 问题内容: 我正在使用Spring 3.1,并且想使用新的缓存功能。然后,我尝试: 但是我没有找到配置自定义KeyGenerator的方法。任何想法? 问题答案: 好的,我只是找到一种方法来做… 如您所见,我使用AnnotationDrivenCacheBeanDefinitionParser,将配置放入xml中,并且可以::完成! 编辑: 对于Spring> 3.2,可以使用实现CachingC

    • 我正在研究一个项目,其中上下文和会话由ThreadLocal使用ThreadPoolExecutor安全地管理(信息从线程传递到ThreadPoolExecutor内部的另一个线程)。 我们有: ThreadPoolExecutor:它实现beforeExecute和afterExecute方法行为,以确保信息从线程传递到另一个线程,并在afterExecutre方法中清除线程上下文。 Threa

    • 我通过Java Admin API使用Google的Firebase存储在Spring Boot应用程序中存储文件。出于安全考虑,我为每个客户组织创建了一个单独的存储桶。由于我经常使用我的测试环境,所以我经常删除和创建这些存储桶。我在找人帮忙把这些水桶更快地装进火力点。 null null

    • 我正在用cakephp开发一个用户库,用于我的应用程序中的翻译操作。我想创造。po文件在Lib目录中,这就是为什么我在Lib目录中创建Locale文件夹,并在相应的语言目录中创建po文件。但问题是CakePHP在默认情况下是在其默认区域设置位置搜索po文件的。现在我的语言环境目录在Lib文件夹中。 我怎么能让cakephp搜索po文件在我自己的区域设置目录这是在Lib文件夹? 这是我的翻译课程代码

    • 问题内容: 我最近开始在Node.js中工作,在app.js文件中有以下一行: 现在,如何设置自己的自定义favicon.ico? 问题答案: 在Express 4中 安装收藏夹中间件,然后执行以下操作: 或者更好,使用模块: (请注意,此解决方案也可以在Express 3应用中使用) 在Express 3中 根据API,接受一个location参数: 大多数时候,您可能希望这样做(如vsync建

    • 介绍: 现在基于css font-face的字体图标越来越流行。 这种图标具有矢量图的特点,可以不失真的自由缩放,还可以通过css来设置图标的颜色,还有就是网络上资源特别丰富。X5系统自带了数百个字体图标, 用户还可以通过配置使用自己下载的字体图标, 下边就介绍一下具体的使用方法。 首先以fortawesome 网站为例(网址:http://fortawesome.github.io/Font-A