2

So I am using MPAndroidChart LineCharts which means in XML I define it this way:

<com.github.mikephil.charting.charts.LineChart
    android:id="@+id/line_chart"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

However I am trying to use this chart using various default settings and so on, so I made a custom class to try to extend it:

public class MyLineChart extends com.github.mikephil.charting.charts.LineChart {
    private Context mContext;

    public MyLineChart(Context context) {
        super(context);
        mContext = context;
    }
    //...

And so elsewhere in my code when I want to use it, I have:

private MyLineChart mChart;

...

mChart = new MyLineChart(getActivity());
mChart = (MyLineChart) findViewById(R.id.line_chart);

And it all seems to compile fine, but then it throws a runtime error because it says I cannot convert the LineChart to MyLineChart.

  • 1
    You have to use MyLineChart in your xml too – Stefan May 07 '16 at 18:10
  • What you show is not "wrapping", it is "extending". And `LineChart` cannot be cast to `MyLineChart`, because the former is not subclass of the latter. `MyLineChart` could be cast to `LineChart`, but not vice versa. – Alex Salauyou May 07 '16 at 18:11
  • I tried using MyLineChart in the XML (com.mypackagename.appname.MyLineChart) but then I had an inflating error when trying to inflate the activity layout – user6183183 May 07 '16 at 18:13
  • @SashaSalauyou I reworded to use the word extend instead of wrap – user6183183 May 07 '16 at 18:14
  • Can you add that error? Because that's the way you should do it. Btw, why are you creating it twice, the second assignment (findViewById) should be enough. – Stefan May 07 '16 at 18:18
  • Apparently the inflating error had to do with not including all three constructors, doing this worked: http://stackoverflow.com/a/3739853/6183183 – user6183183 May 07 '16 at 18:18
  • Huh, I didn't realize findviewbyid also called constructors – user6183183 May 07 '16 at 18:33

1 Answers1

1

To make it possible using MyLineChart in xml, you need define two more constructors there, like:

public class MyLineChart extends com.github.mikephil.charting.charts.LineChart {
    private Context mContext;

    public MyLineChart(Context context) {
        super(context);
        mContext = context;
    }

    public MyLineChart(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
    }

    public LineChart(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mContext = context;
    }

    // ...
}
Alex Salauyou
  • 14,185
  • 5
  • 45
  • 67
  • Why are these three constructors needed? Are they needed for any class that is to be includable as an XML view? – user6183183 May 07 '16 at 18:24
  • to inject attributes passed as `android:id=...`, `android:layout_width=...` etc. – Alex Salauyou May 07 '16 at 18:25
  • Quick question: Does this also mean I cannot pass in any extra arguments other than the context? Like what if I wanted to pass in some other variables (like a Fragment argument or a Textview argument, for instance). – user6183183 May 07 '16 at 19:46
  • @user6183183 of course you may define as many additional constructors as you need and use them to create a view programmatically. These three are requied to create it from xml layout description. – Alex Salauyou May 07 '16 at 19:48
  • But how? If I am already doing `mChart = findViewById(R.id.line_chart);` then isn't this already effectively calling the constructor? How would I also send in an additional argument? – user6183183 May 07 '16 at 19:54
  • @user6183183 no, constructor is called when layout is processed. By `findViewById()` you just locate a view which already exists. If you need to pass some data to a view, you can define accessors, like `setTextView()` etc, but you'll need to call them programmatically. – Alex Salauyou May 07 '16 at 20:02
  • So I cannot send in additional arguments through constructors? I have to use an extra setter? – user6183183 May 07 '16 at 20:04
  • @user6183183 you may, but you'll need to call it programmatically, not in layout xml description. I believe you should post another question to attract attention of Android specialists. I am not one of them, unfortunately, just used to play some time ago ) – Alex Salauyou May 07 '16 at 20:07
  • In other words instead of setting `mContext = context` I'd also like to be able to set something like `mTextview = textview`, but I cannot pass this in through the constructor, right? I have to do that separately using a setter? – user6183183 May 07 '16 at 20:07