在Android中创建一个带有可点击点的圆圈

时间:2016-06-22 12:01:23

标签: android android-layout

我正在尝试构建一个包含多个点的圆圈,这些圆点最终将是可点击的(多达108个点以填充圆圈的边框)。

到目前为止我所做的是创建108个这样的图像视图:

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/circle_1"
        android:src="@drawable/dot_complete"
        android:layout_marginLeft="383dp"
        android:layout_marginTop="214dp"
        />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/circle_2"
        android:src="@drawable/dot_complete"
        android:layout_marginLeft="382dp"
        android:layout_marginTop="214dp"
        />
<!-- And so on all the way up to 108 -->

结果如下所示

enter image description here

但是我怀疑这是一个非常糟糕的方法,所以我的问题是更好的方法,考虑到我需要在每个点上都有onclickListener才能显示它的信息。

谢谢

3 个答案:

答案 0 :(得分:3)

我有一个类似的课程,通过一个小的修改它可以显示三种不同类型的drawables作为“点”。您唯一需要做的就是编写touch管理。

绘制108个点(三种不同类型):

public class DotsView extends View {

    private static final int dots = 108;
    private static final int dotRadius = 20;

    private Bitmap testBitmap1;
    private Bitmap testBitmap2;
    private Bitmap testBitmap3;
    private RectF dotRect;
    private Paint paint;
    private int[] dotsStates = new int[dots];

    public DotsView(Context context) {
        super(context);
        setupView(context);
    }

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

    public DotsView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        setupView(context);
    }

    private void setupView(Context context) {
        setWillNotDraw(false);
        paint = new Paint();
        paint.setAntiAlias(true);

        test();
    }

    private void test() {
        //THIS METHOD IS JUST A TEST THAT CHANGES THE DRAWABLES USED FOR SOME DOTS
        for (int i = 2; i < 20; ++i) {
            dotsStates[i] = 1;
        }
        for (int i = 50; i < 55; ++i) {
            dotsStates[i] = 2;
        }
    }

    @Override
    protected void onAttachedToWindow() {
        super.onAttachedToWindow();
        initBitmaps();
        invalidate();
    }

    @Override
    protected void onDetachedFromWindow() {
        super.onDetachedFromWindow();
        destroyBitmaps();
    }

    private void initBitmaps() {
        testBitmap1 = BitmapFactory.decodeResource(getResources(), R.drawable.test_1);
        testBitmap2 = BitmapFactory.decodeResource(getResources(), R.drawable.test_2);
        testBitmap3 = BitmapFactory.decodeResource(getResources(), R.drawable.test_3);
        dotRect = new RectF(0, 0, dotRadius, dotRadius);
    }

    private boolean isBitmapValid(Bitmap bitmap) {
        return bitmap != null && !bitmap.isRecycled();
    }

    private void destroyBitmaps() {
        if (isBitmapValid(testBitmap1)) {
            testBitmap1.recycle();
            testBitmap1 = null;
        }
        if (isBitmapValid(testBitmap2)) {
            testBitmap2.recycle();
            testBitmap2 = null;
        }
        if (isBitmapValid(testBitmap3)) {
            testBitmap3.recycle();
            testBitmap3 = null;
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (isBitmapValid(testBitmap1) && isBitmapValid(testBitmap2) && isBitmapValid(testBitmap3)) {
            // apply padding to canvas:
            final int width = canvas.getWidth();
            final int height = canvas.getHeight();
            final int squareSide = Math.min(width, height);
            canvas.translate(width / 2f, height / 2f); // moving to the center of the View

            final float outerRadius = squareSide / 2f;
            final float innerRadius = outerRadius - dotRadius;

            final float angleFactor = 360f / dots;

            for (int i = 0; i < dots; ++i) {
                canvas.save(); // creating a "checkpoint"
                canvas.rotate(angleFactor * i);
                canvas.translate(innerRadius, 0); //moving to the edge of the big circle
                canvas.drawBitmap(dotsStates[i] == 0 ?
                                testBitmap1 :
                                dotsStates[i] == 1 ?
                                        testBitmap2 : testBitmap3,
                        null, dotRect, paint);
                canvas.restore(); //restoring a "checkpoint"
            }
        }
    }
}

答案 1 :(得分:2)

你的方法超级重量级。我建议您制作一个自定义的View类,在其中执行以下操作:

  • 重写onDraw方法,将您的圈子直接绘制到视图Canvas
  • 实施一个onTouchEvent听众,根据您创建的圆圈的位置/半径检查触摸的坐标 - 从而找到被点击的圆圈(如果有的话)
  • 触发自定义事件,例如onCircleTapped(View v, int circleId),以便包含的视图/活动/片段可以正确处理事件。

答案 2 :(得分:1)

您可以尝试使用此库tire view

  • 导入barlibrary
  • 创建ChartTireView

    我希望这会对你有帮助。