Android中的自定义视图显示为黑匣子

时间:2015-03-01 10:53:00

标签: java android android-custom-view

我正在尝试创建一个类似饼图的视图,但我对Android很新,所以它并不总是按照我的计划进行。现在,如果我在活动中得到的不是黑盒子,我会很高兴:)你能帮忙吗?

这是我的代码:

activity_main.xml中

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_vertical_margin"
    tools:context=".MainActivity"
    android:orientation="vertical">

    <TextView
        android:text="@string/hello_world"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <com.example.wouter.countdownwidget.PieHolder
        android:id="@+id/pieHolder"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
    </com.example.wouter.countdownwidget.PieHolder>

</LinearLayout>

MainActivity.java

public class MainActivity extends Activity {

    private static final String LOG_TAG = "MainActivity";

    @Override protected void onCreate (Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PieHolder pieHolder = (PieHolder) findViewById(R.id.pieHolder);
        pieHolder.addInterval(new Interval(1, Color.RED));
    }
}

PieHolder.java

public class PieHolder extends ViewGroup {

    private static final String LOG_TAG = "PieHolder";

    private RectF pieBounds = new RectF();
    private PieView pieView;

    public PieHolder (Context context) {
        super(context);
        init();
    }

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

    private void init () {
        setBackgroundColor(Color.WHITE);
        pieView = new PieView(this);
        addView(pieView);
    }

    void addInterval (Interval interval) {
        pieView.addInterval(interval);
    }

    @DebugLog @Override protected void onSizeChanged (int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);

        float xpad = (float) (getPaddingLeft() + getPaddingRight());
        float ypad = (float) (getPaddingTop() + getPaddingBottom());
        float ww = (float) w - xpad;
        float hh = (float) h - ypad;
        float diameter = Math.min(ww, hh);

        pieBounds = new RectF(0, 0, diameter, diameter);
        pieBounds.offsetTo(getPaddingLeft(), getPaddingTop());

        pieView.layout((int) pieBounds.left,
                              (int) pieBounds.top,
                              (int) pieBounds.right,
                              (int) pieBounds.bottom);
    }

    @DebugLog @Override protected void dispatchDraw (Canvas canvas) {
        super.dispatchDraw(canvas);
        if (pieView != null) pieView.draw(canvas);
    }

    @Override protected void onLayout (boolean changed, int l, int t, int r, int b) {

    }
}

PieView.java

public class PieView extends SurfaceView{

    private static final String LOG_TAG = "PieView";

    private PieHolder pieHolder;
    //private SurfaceHolder holder;
    //private PieViewThread pieViewThread;

    private RectF rectF;
    private Paint paint;
    private List<Interval> intervals;

    @DebugLog public PieView (PieHolder pieHolder) {
        super(pieHolder.getContext());

        this.pieHolder = pieHolder;
        intervals = new ArrayList<>();
        rectF = new RectF(0, 0, pieHolder.getWidth(), pieHolder.getHeight());

        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setStyle(Paint.Style.FILL);
        paint.setColor(Color.GREEN);
    }

    public void addInterval (Interval interval) {
        intervals.add(interval);
    }

    @DebugLog @Override protected void onDraw (Canvas canvas) {
        super.onDraw(canvas);

        if (rectF == null) {
            rectF = new RectF(0, 0, pieHolder.getWidth(), pieHolder.getHeight());
            Log.i(LOG_TAG, "Reinstantiating rectF");
        }

        canvas.drawColor(Color.RED);
        canvas.drawArc(rectF, 0, 180, true, paint);
    }
}

2 个答案:

答案 0 :(得分:0)

我找到了解决方案!!!

Android希望在另一个帖子中绘制SurfaceView,因此我需要在setWillNotDraw(false)的构造函数中调用PieView。此外,正如谢提到的,创建一个自定义ViewGroup有点无意义,所以我也摆脱了它。

这是我感兴趣的PieView课程:

class PieView extends SurfaceView{

    private Interval[] intervals;
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    private RectF rectf;
    private int size;

    public PieView (Context context, Interval[] intervals) {
        super(context);
        this.intervals = intervals;
    setWillNotDraw(false);
    }

    @Override protected void onMeasure (int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        size = Math.min(getMeasuredWidth(), getMeasuredHeight());
        setMeasuredDimension(size, size);
        if (rectf == null || rectf.width() != size ) { rectf = new RectF(0, 0, size, size); }
    }

    @Override protected void onDraw (Canvas canvas) {
        super.onDraw(canvas);
    canvas.drawColor(getResources().getColor(android.R.color.background_light));
        paint.setColor(intervals[0].color);
        canvas.drawArc(rectf, -90, 360, true, paint);
        paint.setColor(intervals[1].color);
        canvas.drawArc(rectf, -90, intervals[1].duration, true, paint);
    }
}

PS:这绝不是我的最终目标,但现在我至少可以在屏幕上绘制一些东西

答案 1 :(得分:-1)

您自定义了一个视图组,但没有任何内容。如果您只想制作视图,最好从View而不是ViewGroup扩展。

你可以在这里参考google android site的doc:http://developer.android.com/training/custom-views/create-view.html