膨胀自定义视图时出错

时间:2013-08-19 11:22:26

标签: android

我有一个饼图自定义视图,我在画布中绘制饼图。

我从片段内的活动发送饼图值。

但是我在饼图中出现错误。我尝试过各种各样的措施,但却找不到合适的解决方案

我的活动是......

public class PieChart extends View {
    float valuesForDrawing[];
    float valuesForDisplay[];
    // private float[] values,valuesForDisplay = new float[] {};
    ArrayList<ViewWasTouchedListener> listeners = new ArrayList<ViewWasTouchedListener>();

    public void setWasTouchedListener(ViewWasTouchedListener listener) {
        listeners.add(listener);
    }

    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private float[] value_degree;
    private float[] value_degree_for_display;
    private float[] angle_list;
    private int[] COLORS = { Color.BLUE, Color.GREEN, Color.MAGENTA,
            Color.CYAN, Color.RED };
    RectF rectf = new RectF(36, 48, 325, 330);
    int temp = 0;

    public PieChart(Context context, float[] values) {

        super(context);

        valuesForDrawing = calculateData(values);
        value_degree = new float[valuesForDrawing.length];
        for (int i = 0; i < values.length; i++) {
            value_degree[i] = values[i];

        }

        valuesForDisplay = calculateDataForDisplay(values);
        value_degree_for_display = new float[valuesForDisplay.length];
        for (int i = 0; i < values.length; i++) {
            value_degree_for_display[i] = values[i];

        }

    }

    public PieChart(Context context, AttributeSet attrs, float[] values) {
        super(context, attrs);
        valuesForDrawing = calculateData(values);
        value_degree = new float[valuesForDrawing.length];
        for (int i = 0; i < values.length; i++) {
            value_degree[i] = values[i];

        }

        valuesForDisplay = calculateDataForDisplay(values);
        value_degree_for_display = new float[valuesForDisplay.length];
        for (int i = 0; i < values.length; i++) {
            value_degree_for_display[i] = values[i];

        }

    }

    public PieChart(Context context, AttributeSet attrs, int defStyle,
            float[] values) {

        super(context, attrs, defStyle);
        valuesForDrawing = calculateData(values);
        value_degree = new float[valuesForDrawing.length];
        for (int i = 0; i < values.length; i++) {
            value_degree[i] = values[i];

        }

        valuesForDisplay = calculateDataForDisplay(values);
        value_degree_for_display = new float[valuesForDisplay.length];
        for (int i = 0; i < values.length; i++) {
            value_degree_for_display[i] = values[i];

        }
    }

    /*
     * public void setChartData(float[] datapoints) { this.values =
     * datapoints.clone(); this.valuesForDisplay = datapoints.clone();
     * invalidate(); }
     */

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        super.onDraw(canvas);

        for (int i = 0; i < value_degree.length; i++) {// values2.length; i++) {
            if (i == 0) {
                paint.setColor(COLORS[i]);
                canvas.drawArc(rectf, 0, value_degree[i], true, paint);
            } else {
                temp += (int) value_degree[i - 1];
                paint.setColor(COLORS[i]);
                canvas.drawArc(rectf, temp, value_degree[i], true, paint);
            }
        }

        for (ViewWasTouchedListener listener : listeners) {
            listener.onViewDrawn(value_degree_for_display, COLORS);
        }

    }

    private float[] calculateData(float[] data) {
        // TODO Auto-generated method stub
        float total = 0;
        // float x=0;
        for (int i = 0; i < data.length; i++) {
            total += data[i];
        }
        for (int i = 0; i < data.length; i++) {
            data[i] = 360 * (data[i] / total);
            // x=x+data[i];
        }
        return data;

    }

    private float[] calculateDataForDisplay(float[] data) {
        // TODO Auto-generated method stub
        float total = 0;
        float x = 0;
        for (int i = 0; i < data.length; i++) {
            total += data[i];
        }
        for (int i = 0; i < data.length; i++) {
            data[i] = 360 * (data[i] / total);
            x = x + data[i];
            data[i] = x;
        }
        return data;

    }

    public float[] getValuesForDrawing() {
        return valuesForDrawing;
    }

    public void setValuesForDrawing(float[] valuesForDrawing) {
        this.valuesForDrawing = valuesForDrawing;
    }

    public float[] getValuesForDisplay() {
        return valuesForDisplay;
    }

    public void setValuesForDisplay(float[] valuesForDisplay) {
        this.valuesForDisplay = valuesForDisplay;
    }

    public ArrayList<ViewWasTouchedListener> getListeners() {
        return listeners;
    }

    public void setListeners(ArrayList<ViewWasTouchedListener> listeners) {
        this.listeners = listeners;
    }

    public Paint getPaint() {
        return paint;
    }

    public void setPaint(Paint paint) {
        this.paint = paint;
    }

    public float[] getValue_degree() {
        return value_degree;
    }

    public void setValue_degree(float[] value_degree) {
        this.value_degree = value_degree;
    }

    public float[] getValue_degree_for_display() {
        return value_degree_for_display;
    }

    public void setValue_degree_for_display(float[] value_degree_for_display) {
        this.value_degree_for_display = value_degree_for_display;
    }

    public float[] getAngle_list() {
        return angle_list;
    }

    public void setAngle_list(float[] angle_list) {
        this.angle_list = angle_list;
    }

    public int[] getCOLORS() {
        return COLORS;
    }

    public void setCOLORS(int[] cOLORS) {
        COLORS = cOLORS;
    }

    public RectF getRectf() {
        return rectf;
    }

    public void setRectf(RectF rectf) {
        this.rectf = rectf;
    }

    public int getTemp() {
        return temp;
    }

    public void setTemp(int temp) {
        this.temp = temp;
    }

         }

我从这句话中调用了这个观点..

 PieChart customView = new PieChart(getActivity(), values);

值是        float [] = {2,7,8,9,.. anything};

但我收到错误....

     08-19 16:50:12.389: E/AndroidRuntime(27669): FATAL EXCEPTION: main
08-19 16:50:12.389: E/AndroidRuntime(27669): android.view.InflateException: Binary XML file line #17: Error inflating class com.example.fragmentnewone.PieChart
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.createView(LayoutInflater.java:589)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:680)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:739)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.rInflate(LayoutInflater.java:742)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.inflate(LayoutInflater.java:489)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.inflate(LayoutInflater.java:396)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.inflate(LayoutInflater.java:352)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at com.example.fragmentnewone.PieChartFragment.onCreateView(PieChartFragment.java:50)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.Fragment.performCreateView(Fragment.java:1460)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:911)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1088)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.BackStackRecord.run(BackStackRecord.java:682)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.FragmentManagerImpl.execPendingActions(FragmentManager.java:1444)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.FragmentManagerImpl.executePendingTransactions(FragmentManager.java:461)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.app.FragmentPagerAdapter.finishUpdate(FragmentPagerAdapter.java:141)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.view.ViewPager.populate(ViewPager.java:1011)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.view.ViewPager.populate(ViewPager.java:880)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.support.v4.view.ViewPager$3.run(ViewPager.java:238)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.os.Handler.handleCallback(Handler.java:608)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.os.Handler.dispatchMessage(Handler.java:92)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.os.Looper.loop(Looper.java:156)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.app.ActivityThread.main(ActivityThread.java:5109)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at java.lang.reflect.Method.invokeNative(Native Method)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at java.lang.reflect.Method.invoke(Method.java:511)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:991)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at dalvik.system.NativeStart.main(Native Method)
08-19 16:50:12.389: E/AndroidRuntime(27669): Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]
08-19 16:50:12.389: E/AndroidRuntime(27669):    at java.lang.Class.getConstructorOrMethod(Class.java:460)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at java.lang.Class.getConstructor(Class.java:431)
08-19 16:50:12.389: E/AndroidRuntime(27669):    at android.view.LayoutInflater.createView(LayoutInflater.java:561)
08-19 16:50:12.389: E/AndroidRuntime(27669):    ... 26 more

EDIT  我更改了构造函数并使用setter方法

设置了值
public void setValues(float[] values) {
    this.values = values;
}

但我收到错误

 08-20 11:35:02.685: E/ViewGroup(14994): ----- NullPointerException -----
08-20 11:35:02.685: E/ViewGroup(14994): mChildrenCount = 1, count = 1, i = 0, child = android.widget.LinearLayout@40f4e838, mEditChildren = false
08-20 11:35:02.685: E/ViewGroup(14994): idx = 0, child = android.widget.LinearLayout@40f4e838
08-20 11:35:02.685: E/ViewGroup(14994): ----- NullPointerException -----
08-20 11:35:02.685: E/ViewGroup(14994): mChildrenCount = 3, count = 3, i = 1, child = android.widget.FrameLayout@40f4d9b0, mEditChildren = false
08-20 11:35:02.685: E/ViewGroup(14994): idx = 0, child = com.android.internal.widget.ActionBarContainer@40f463c8
08-20 11:35:02.685: E/ViewGroup(14994): idx = 1, child = android.widget.FrameLayout@40f4d9b0
08-20 11:35:02.685: E/ViewGroup(14994): idx = 2, child = com.android.internal.widget.ActionBarContainer@40f4dd58
08-20 11:35:02.685: E/ViewGroup(14994): ----- NullPointerException -----
08-20 11:35:02.685: E/ViewGroup(14994): mChildrenCount = 1, count = 1, i = 0, child = android.widget.LinearLayout@40f45890, mEditChildren = false
08-20 11:35:02.685: E/ViewGroup(14994): idx = 0, child = android.widget.LinearLayout@40f45890

My xml is 
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/black">

    <RelativeLayout
    android:id="@+id/rel"
    android:layout_width="250dp"
    android:layout_height="250dp"
    android:layout_marginTop="50dp"
    android:layout_marginLeft="40dp"
    android:orientation="vertical"
    tools:context=".MainActivity" 
    android:background="#000000">

  <com.example.fragmentnewone.PieChart

      android:id="@+id/graphId"
      android:layout_width="match_parent"
      android:layout_height="match_parent">

    </com.example.fragmentnewone.PieChart>


    <ImageView
        android:src="@drawable/graphic_ring"
        android:id="@+id/imageView_ring"
        android:scaleType="matrix"
        android:layout_height="fill_parent"
        android:layout_width="fill_parent"> 

    </ImageView>

    <TextView
        android:id="@+id/textId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="32dp"
        android:textStyle="bold"
         />

</RelativeLayout>
</RelativeLayout>

4 个答案:

答案 0 :(得分:25)

您需要一个仅包含ContextAttributeSet参数的构造函数。 values参数无效,您必须在充气后以编程方式设置值。

示例:

public PieChart(Context context, AttributeSet attrs){
    super(context, attrs);
}

public void setValues(float[] values){
    // Do stuff calculating
}

答案 1 :(得分:3)

你有:

Caused by: java.lang.NoSuchMethodException: <init> [class android.content.Context, interface android.util.AttributeSet]

没有只有上下文和属性的方法。你需要传递所有必需的参数。

public PieChart(Context context, AttributeSet attrs, float[] values) {
        super(context, attrs,values);
}

希望它能帮助!!

答案 2 :(得分:0)

您可以尝试一下

class CustomView(
context: Context,
attributes: AttributeSet? = null
 ) : View(context, attributes) {

 override fun onDraw(canvas: Canvas?) {
    super.onDraw(canvas)
    canvas?.let {
        setBackgroundColor(Color.RED)
    }
  }
}

答案 3 :(得分:0)

就我而言,我在FrameLayout变形之前访问视图。 我不得不更改为

private val viewsList = listOf<EditText>(v1, v2, v3)

class LoginContractInput : FrameLayout {

    constructor(context: Context) : super(context)
    [...]

    private val backgroundRed by lazy { context.getDrawable(R.drawable.backgroundRed) }
    
    private val viewsList by lazy {
        listOf<EditText>(v1, v2, v3)
    }

    init{
        inflate(...)
    }
}