2016-06-22 19 views
2

私は、最終的にクリック可能な数多くの点を含む円を作成しようとしています。私がこれまで行ってきた何Androidでクリック可能なドットで円を作成する

はこのように108 imageviewsを作成することです:

<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を持っている必要があることを考慮し、これを行うための良い方法は何でしょう。

ありがとうございました

+0

はい、これは間違った方法です。 [this](https://github.com/LukeDeighton/WheelView)のようなものを使用してください。 – SripadRaj

+0

Thanks @SripadRaj。私はそれを試しましたが、それはマシュマロで問題があるかもしれないようです。少なくとも私は大きな円以外の何かを得ることができません。 – JPJens

+0

@ JPJensあなたが考慮する必要があるものはほとんどありません。 **全体**サークルは常に表示されますか?それともその一部ですか?サークル内のすべての画像は同じですか? –

答えて

2

私は小さな変更で、それは「ドット」としてdrawablesの3つの異なる種類を表示することができ、周りに敷設同様のクラスを持っていました。あなたがしなければならないのは、touchの管理を書くことだけです。

描画108個のドット(3つの異なる種類):

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" 
      } 
     } 
    } 
} 
+0

それは完璧で、ちょうど私が必要とするものです。私はタッチイベントによって円の上に円を描く(または円形の色を置き換える)方法を理解するためにまだ苦労しています。ドットの1つを変更するには、すべてのドットを再描画する必要がありますか? – JPJens

+0

このコードには、ドットの「状態」の配列( 'dotsStates')があります。だから、特定のドットを表す値を変更するだけです。そしてあなたは 'invalidate()'を呼び出します。これにより、 'View'がそれ自身を再描画するようになり、' state'に基づいて正しいdrawableが選択されます。 –

+1

invalidate(); !私はそれを理解するために苦労していた。ありがとうございました – JPJens

2

あなたのアプローチは超重量です。の座標を確認し、直接ビューのCanvas

  • onTouchEventリスナーを実装する上でサークルを描くために

    • オーバーライドonDraw方法:私の代わりにその中にあなたがこれらのことを行う、独自のViewクラスを作るお勧めしますあなたが作成したサークルの位置/半径に触れて、タップされたサークルを見つけてください。
    • onCircleTapped(View v, int circleId)のようなカスタムイベントをトリガーして、ビュー/アクティビティ/フラグメントがイベントを適切に処理できるようにします。
  • +1

    あなたは正しいです。しかし、彼はあなたが何を意味するかを理解するために、より詳細を必要とするかもしれないと思います。おかげさまで – Cenxui

    1

    あなたはtire view

    • このライブラリを試すことができますbarlibrary
    • は、私は、これはあなたを助けることを願っていますChartTireView

      を作成してインポートします。

    +0

    しかし、これに関する文書がほとんどないか、またはほとんどドキュメントがないので、作業が非常に難しいかもしれません。 – JPJens

    +0

    または、クラスの拡張ビューを作成してonDraw(canvas)メソッドをオーバーライドするには、canvas.canvas.drawCircle()を使用します。それ。 – Cenxui