Nik
Nik

Reputation: 21

Androidplot - creating chart without XML

I need to create some PieCharts on my Activity, and quantity of charts varies. I try to create PieChart dynamically from code, and it's doesn't work. My Layout correct - Button added successfully. Can you help me? Some code: Layout:

<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:context="example.bros.nik.tabs1.MealsActivity"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/l_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:orientation="vertical" >
</LinearLayout>
</ScrollView>

Java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_meals);
    LinearLayout l_layout = (LinearLayout) findViewById(R.id.l_layout);
    meals_params = ResultsActivity.get_meals_params();        

    LinearLayout.LayoutParams lp_view = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT,
            LinearLayout.LayoutParams.WRAP_CONTENT, 1.0f);

    PieChart pie = new PieChart(this, "Chart#1");

    Segment s1 = new Segment("Углеводы", meals_params[0].get_carbohydrates_percent());
    Segment s2 = new Segment("Жиры", meals_params[0].get_fats_percent());
    Segment s3 = new Segment("Белки", meals_params[0].get_proteins_percent());

    EmbossMaskFilter emf = new EmbossMaskFilter(new float[]{1, 1, 1}, 0.4f, 10, 8.2f);

    SegmentFormatter sf1 = new SegmentFormatter();
    sf1.configure(getApplicationContext(), R.xml.pie_segment_formatter1);
    sf1.getFillPaint().setMaskFilter(emf);

    SegmentFormatter sf2 = new SegmentFormatter();
    sf2.configure(getApplicationContext(), R.xml.pie_segment_formatter2);
    sf2.getFillPaint().setMaskFilter(emf);

    SegmentFormatter sf3 = new SegmentFormatter();
    sf3.configure(getApplicationContext(), R.xml.pie_segment_formatter3);
    sf3.getFillPaint().setMaskFilter(emf);

    pie.addSeries(s1, sf1);
    pie.addSeries(s2, sf2);
    pie.addSeries(s3, sf3);


    pie.getRenderer(PieRenderer.class).setDonutSize(0.1f,PieRenderer.DonutMode.PERCENT);
    pie.redraw();
    pie.getBorderPaint().setColor(Color.TRANSPARENT);
    pie.getBackgroundPaint().setColor(Color.TRANSPARENT);

    l_layout.addView(pie, lp_view);

I try this:

pie.setLayoutParams(lp_view);
l_layout.addView(pie);

and it's doesn't help me.

And if I add Button to Layout:

pie.setLayoutParams(lp_view);
l_layout.addView(pie);

Button but = new Button(this);
but.setText("bla");
l_layout.addView(but, lp_view);

then I see this Button (look at screenshot). Added button

EDIT: In Android docs written, that in constructor

ViewGroup.LayoutParams (int width, int height)

attributes may be the absolute sizes of view, or may be constants - WRAP_CONTENT (int value -2), MATCH_PARENT (int value -1). Probably, PieChart doesn't recognize these constants, and get it as absolute size with negative values. I found solution:

private int[] getDisplayParams() {
    int[] display_params = new int[2];
    Display display = getWindowManager().getDefaultDisplay();
    if (Build.VERSION.SDK_INT >= 13) {
        Point size = new Point();
        display.getSize(size);
        display_params[0] = size.x;
        display_params[1] = size.y;
    }
    else {
        display_params[0] = display.getWidth();
        display_params[1] = display.getHeight();
    }
    return display_params;
}

and use size of screen for determining size of chart:

int[] display_params = getDisplayParams();
Double pie_size = display_params[0]*0.8;
int pie_size_int = pie_size.intValue();
ViewGroup.LayoutParams lp_view = new LinearLayout.LayoutParams(pie_size_int, pie_size_int);

Upvotes: 1

Views: 469

Answers (2)

Nik
Nik

Reputation: 21

Problem resolved by Nick. You can also try:

plot.setMinimumHeight(100);
plot.setMinimumWidth(100);

Upvotes: 1

Nick
Nick

Reputation: 8317

Looks like you are not providing LayoutParams for pie. Try doing this before adding pie to l_layout:

pie.setLayoutParams(new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.FILL_PARENT,
    LinearLayout.LayoutParams.FILL_PARENT));

EDIT: I went back and noticed that the layout is enclosed in a ScrollView but the Scrollview is set to wrap content and the content is set to match parent so it seems like it might be a chicken and egg problem as described here. I believe buttons, etc. have default non-zero values for these whereas plots do not, which might explain why the button works.

As a sanity check, what happens if you specify an absolute size for your plot like this:

LinearLayout.LayoutParams lp_view = new LinearLayout.LayoutParams(100, 100);

You can also try:

plot.setMinimumHeight(100);
plot.setMinimumWidth(100);

Upvotes: 1

Related Questions