I have chart, based on this lesson, so it has some data and this chart initializing by
ChartView chartView = findViewById(R.id.chart);
chartView.setChartData(getRandomData());
And I want made it scrollable throw ViewPager. So I've created ChartPageAdapter.class. But when I'm creating viewPager in my MainActivity, getting some error that length and index of my ChartView equals to zero. That's right, because I didn't initialized this by setting some data. So' how to set my custom ChartView to ChartPageAdapter?
MainScreenActivity.class
public class MainScreenActivity extends BaseActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ViewPager viewPager = findViewById(R.id.viewpager);
viewPager.setAdapter(new ChartPageAdapter(this));
ChartView chartView = findViewById(R.id.chart);
chartView.setChartData(getRandomData());
}
public static float[] getRandomData() {
return new float[] { 10, 12, 7, 14, 15, 19, 13, 2, 10, 13, 13, 10, 15, 14 };
}
ChartView.class
public class ChartView extends View {
private static final int MIN_LINES = 4;
private static final int MAX_LINES = 7;
private static final int[] DISTANCES = { 1, 2, 5 };
private float[] datapoints = new float[] {};
private Paint paint = new Paint();
public ChartView(Context context) {
super(context);
}
public ChartView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void setChartData(float[] datapoints) {
this.datapoints = datapoints.clone();
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
drawBackground(canvas);
drawLineChart(canvas);
}
private void drawBackground(Canvas canvas) {
float maxValue = getMax(datapoints);
int range = getLineDistance(maxValue);
paint.setStyle(Paint.Style.STROKE);
paint.setColor(Color.GRAY);
for (int y = 0; y < maxValue; y += range) {
final float yPos = getYPos(y);
canvas.drawLine(0, yPos, getWidth(), yPos, paint);
}
}
private int getLineDistance(float maxValue) {
int distance;
int distanceIndex = 0;
int distanceMultiplier = 1;
int numberOfLines = MIN_LINES;
do {
distance = DISTANCES[distanceIndex] * distanceMultiplier;
numberOfLines = (int) Math.ceil(maxValue / distance);
distanceIndex++;
if (distanceIndex == DISTANCES.length) {
distanceIndex = 0;
distanceMultiplier *= 10;
}
} while (numberOfLines < MIN_LINES || numberOfLines > MAX_LINES);
return distance;
}
private void drawLineChart(Canvas canvas) {
Path path = new Path();
path.moveTo(getXPos(0), getYPos(datapoints[0]));
for (int i = 1; i < datapoints.length; i++) {
path.lineTo(getXPos(i), getYPos(datapoints[i]));
}
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
paint.setColor(0xFF33B5E5);
paint.setAntiAlias(true);
paint.setShadowLayer(4, 2, 2, 0x80000000);
canvas.drawPath(path, paint);
paint.setShadowLayer(0, 0, 0, 0);
}
private float getMax(float[] array) {
float max = array[0];
for (int i = 1; i < array.length; i++) {
if (array[i] > max) {
max = array[i];
}
}
return max;
}
private float getYPos(float value) {
float height = getHeight() - getPaddingTop() - getPaddingBottom();
float maxValue = getMax(datapoints);
// scale it to the view size
value = (value / maxValue) * height;
// invert it so that higher values have lower y
value = height - value;
// offset it to adjust for padding
value += getPaddingTop();
return value;
}
private float getXPos(float value) {
float width = getWidth() - getPaddingLeft() - getPaddingRight();
float maxValue = datapoints.length - 1;
// scale it to the view size
value = (value / maxValue) * width;
// offset it to adjust for padding
value += getPaddingLeft();
return value;
}
}
ChartPageAdapter.class
public class ChartPageAdapter extends PagerAdapter {
private Context context;
public ChartPageAdapter(Context context) {
this.context = context;
}
@Override
public Object instantiateItem(ViewGroup container, int position) {
LayoutInflater inflater = LayoutInflater.from(context);
ViewGroup layout = (ViewGroup) inflater.inflate(R.layout.chart_layout, container, false);
container.addView(layout);
return layout;
}
@Override
public int getCount() {
return 1;
}
@Override
public boolean isViewFromObject(@NonNull View view, @NonNull Object object) {
return view == object;
}
@Override
public void destroyItem(ViewGroup collection, int position, Object view) {
collection.removeView((View) view);
}
}