菜鸟一位,之前还在纠结项目不能导入n多个 github上下载或者自己建立的库文件,当修改完mpchart源码之后,发现不能导入,半天的时光耗费,发现了一个好的方法,将修改完源码的库打成jar包,导入到自己项目中。
可能大牛们都已经知道了,但是对于新手来讲确实眼前一亮。
具体jar包位置在库目录 比如 Xutils\build\intermediates\bundles\release\class.jar
记得先build一下生成class.jar 然后自己把文件copy出来改个名字当作jar包导入。
言归正传,产品给了一个新的UI,效果图如下
这在普通的mpchart来说确实很难实现,只能去研究源码了,这里非常感谢http://blog.csdn.net/baidu_34934230/article/details/52386592此文的作者。助我找到了源码需要修改的地方,发现mpchart也是分层去绘制,参考此文的介绍找到 2个类 IBarDataSet类和它的实现类BarDataSet,发现IBarDataSet类中定义了几个接口即:
public interface IBarDataSet extends IBarLineScatterCandleBubbleDataSet<BarEntry> { /** * Returns the space between bars as the actual value (0 - 1.0f) * * @return */ float getBarSpace(); /** * Returns true if this DataSet is stacked (stacksize > 1) or not. * * @return */ boolean isStacked(); /** * Returns the maximum number of bars that can be stacked upon another in * this DataSet. This should return 1 for non stacked bars, and > 1 for stacked bars. * * @return */ int getStackSize(); /** * Returns the color used for drawing the bar-shadows. The bar shadows is a * surface behind the bar that indicates the maximum value. * * @return */ int getBarShadowColor(); /** * Returns the alpha value (transparency) that is used for drawing the * highlight indicator. * * @return */ int getHighLightAlpha(); /** * Returns the labels used for the different value-stacks in the legend. * This is only relevant for stacked bar entries. * * @return */ String[] getStackLabels(); Drawable getBarBitmapBackGround(); }最后面的getBarBitmapBackGround是我后来自己添加的方法,这里命名不太规范,应该改为getBitmapBackGround();
然后找到IBardataSet的实现类,去实现他的方法,这里有2个实现类,另外一个我就不贴代码了,因为我们只用到了BarDataSet类,
package com.github.mikephil.charting.data; import android.graphics.Color; import android.graphics.drawable.Drawable; import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; import java.util.ArrayList; import java.util.List; public class BarDataSet extends BarLineScatterCandleBubbleDataSet<BarEntry> implements IBarDataSet { /** * bar background */ private Drawable mBitmapBarBakcground;public void setmBitmapBarBakcground(Drawable mBitmapBarBakcground) { this.mBitmapBarBakcground = mBitmapBarBakcground; }@Override public Drawable getBarBitmapBackGround() { return mBitmapBarBakcground; }/** * the color used for drawing the bar shadows */
private int mBarShadowColor = Color.rgb(215, 215, 215);
@Override
public DataSet<BarEntry> copy() {
List<BarEntry> yVals = new ArrayList<BarEntry>();
for (int i = 0; i < mYVals.size(); i++) {
yVals.add(((BarEntry) mYVals.get(i)).copy());
}
BarDataSet copied = new BarDataSet(yVals, getLabel());
copied.mColors = mColors;
copied.mStackSize = mStackSize;
copied.mBarSpace = mBarSpace;
copied.mBarShadowColor = mBarShadowColor;
copied.mStackLabels = mStackLabels;
copied.mHighLightColor = mHighLightColor;
copied.mHighLightAlpha = mHighLightAlpha;
copied.mBitmapBarBakcground=mBitmapBarBakcground;
return copied;
}
/** * Sets the color used for drawing the bar-shadows. The bar shadows is a * surface behind the bar that indicates the maximum value. Don't for get to * use getResources().getColor(...) to set this. Or Color.rgb(...).
*
* @param color
*/ public void setBarShadowColor(int color) {
mBarShadowColor = color;
}
@Override public int getBarShadowColor() {
return mBarShadowColor;
}
}这里我只粘贴了几段有代表性的代码, mBitmapBarBakcground
是我 自定义的一个属性当然改为mBitmapBackground更好一点,这里就靠大家自己去修改了,
做到这里,已然将我们自己自定义的属性搭配好,下面就开始去找绘图的源码了。借助http://blog.csdn.net/baidu_34934230/article/details/52386592
作者的分析我们找到了绘图的源码。即:
public class BarChartRenderer extends DataRenderer { protected BarDataProvider mChart; /** * the rect object that is used for drawing the bars */ protected RectF mBarRect = new RectF(); protected BarBuffer[] mBarBuffers; protected Paint mShadowPaint; private Drawable mBitmapBarBakcground;//...................................... @Override public void drawData(Canvas c) { BarData barData = mChart.getBarData(); for (int i = 0; i < barData.getDataSetCount(); i++) { IBarDataSet set = barData.getDataSetByIndex(i); if (set.isVisible() && set.getEntryCount() > 0) { drawDataSet(c, set, i); } } } protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) { Transformer trans = mChart.getTransformer(dataSet.getAxisDependency()); mShadowPaint.setColor(dataSet.getBarShadowColor()); mBitmapBarBakcground = dataSet.getBarBitmapBackGround();//................ float phaseX = mAnimator.getPhaseX(); float phaseY = mAnimator.getPhaseY(); // initialize the buffer BarBuffer buffer = mBarBuffers[index]; buffer.setPhases(phaseX, phaseY); buffer.setBarSpace(dataSet.getBarSpace()); buffer.setDataSet(index); buffer.setInverted(mChart.isInverted(dataSet.getAxisDependency())); buffer.feed(dataSet); trans.pointValuesToPixel(buffer.buffer); // draw the bar shadow before the values if (mChart.isDrawBarShadowEnabled()) { for (int j = 0; j < buffer.size(); j += 4) { if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) continue; if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) break; Rect r=new Rect((int)(buffer.buffer[j]),
(int)mViewPortHandler.contentTop(), (int)buffer.buffer[j + 2],
(int)mViewPortHandler.contentBottom()); c.drawRect(r,mShadowPaint); // if (mBitmapBarBakcground != null) { // Log.i("chatUtil","0back!=null"); // Bitmap bitmap=((BitmapDrawable)mBitmapBarBakcground).getBitmap(); // c.drawBitmap(bitmap, r, r, mRenderPaint); // } else { // Log.i("chatUtil","0back==null"); // c.drawRect(r, mRenderPaint); // } } } // if multiple colors if (dataSet.getColors().size() > 1) { for (int j = 0; j < buffer.size(); j += 4) { if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) continue; if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) break; // Set the color for the currently drawn value. If the index // is // out of bounds, reuse colors. if(mBitmapBarBakcground==null){//.................................... mRenderPaint.setColor(dataSet.getColor(j / 4)); }else { mRenderPaint.setFilterBitmap(true); mRenderPaint.setDither(true); } // c.drawRect(buffer.buffer[j], buffer.buffer[j + 1], buffer.buffer[j + 2], // buffer.buffer[j + 3], mRenderPaint); Rect r=new Rect((int)buffer.buffer[j], (int)buffer.buffer[j + 1],(int)buffer.buffer[j + 2],(int)buffer.buffer[j + 3]);
if (mBitmapBarBakcground != null) {//....................................... Log.i("chartUtil","1back!=null");
Bitmap bitmap=((BitmapDrawable)mBitmapBarBakcground) .getBitmap();
c.drawBitmap(bitmap, r, r, mRenderPaint);
} else {
Log.i("chartUtil","1back==null");
c.drawRect(r, mRenderPaint);
}
}
} else {
if(mBitmapBarBakcground==null){//.......................................... mRenderPaint.setColor(dataSet.getColor());
}else {
mRenderPaint.setFilterBitmap(true);
mRenderPaint.setDither(true);
}
for (int j = 0; j < buffer.size(); j += 4) {
if (!mViewPortHandler.isInBoundsLeft(buffer.buffer[j + 2])) continue;
if (!mViewPortHandler.isInBoundsRight(buffer.buffer[j])) break;
// c.drawRect(buffer.buffer[j], buffer.buffer[j + 1],
// buffer.buffer[j + 2],
// buffer.buffer[j + 3], mRenderPaint);
Rect r = new Rect((int) buffer.buffer[j], (int) buffer.buffer[j + 1], (int) buffer.buffer[j + 2],(int) buffer.buffer[j + 3]);
if (mBitmapBarBakcground != null) {//...................................
Log.i("chartUtil","2back!=null");
mBitmapBarBakcground.setBounds(r);
mBitmapBarBakcground.draw(c);
} else {
Log.i("chatrUtil","2back==null");
c.drawRect(r, mRenderPaint);
}
}
}
}
}找到drawdata方法 然后看到一个循环,我想到的是每条柱子的绘制,然后找到drawDataSet方法,跟进去,简单修改了源码,
由于没想配置太多,只简单的做了一个设置方法,后期读者可以添加各种drawBackGroundBitmap(boolean canable)类似的,就
由读者自行去使用了,到此位置,简单实现了UI要求。介于此有一些疑点
为什么将方法加到IbarDataSet里面是因为 mp3.0后BarChart的Bardata初始化方法有了调整
barDataSet.setBarSpacePercent(space);//柱状图之间宽度 barDataSet.setmBitmapBarBakcground(context.getDrawable(R.drawable.barbg));//具体使用 barDataSet.setHighLightAlpha(00);ArrayList<IBarDataSet> barSets = new ArrayList<IBarDataSet>();
barSets.add(barDataSet);
BarData barData = new BarData(xTittles, barSets);
这里使用的是IbardataSet,当然可以将方法只添加到BardataSet里面。看个人需求了。
本人菜鸟一枚,如果有问题欢迎一起讨论