2017-01-19 3 views
0

と、特定の円の外側のゾーン:クリア私が円を充填することによって進捗状況を示すが、今、私は</strong>外にこの白い円を私の見解<strong>のゾーンを消去する方法を探していますカスタムビューを持つキャンバス

ここで

enter image description here

、私のコード:

public class CircleGauge extends View { 
    private int value = 75; 
    private Paint backgroundPaint, gaugePaint, textPaint, circlePaint; 

    ... constructors 

    private void init() { 
     DisplayMetrics metrics = getResources().getDisplayMetrics(); 

     backgroundPaint = new Paint(); 
     backgroundPaint.setColor(ResourcesCompat.getColor(getResources(), R.color.favorite_position_gauge_background, null)); 
     backgroundPaint.setStyle(Paint.Style.FILL); 
     backgroundPaint.setAntiAlias(true); 

     gaugePaint = new Paint(); 
     gaugePaint.setColor(ResourcesCompat.getColor(getResources(), R.color.favorite_position_gauge, null)); 
     gaugePaint.setAntiAlias(true); 

     circlePaint = new Paint(); 
     circlePaint.setColor(Color.WHITE); 
     circlePaint.setStyle(Paint.Style.STROKE); 
     circlePaint.setStrokeWidth(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 2, metrics)); 
     circlePaint.setAntiAlias(true); 

     textPaint = new Paint(); 
     textPaint.setTextAlign(Paint.Align.CENTER); 
     textPaint.setColor(Color.WHITE); 
     textPaint.setFakeBoldText(true); 
     textPaint.setTextSize(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 23, metrics)); 
     textPaint.setAntiAlias(true); 
    } 

    @Override 
    protected void onDraw(Canvas canvas) { 
     canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), backgroundPaint); 
     canvas.drawRect(0, ((float) (100 - value)/100F) * canvas.getHeight(), canvas.getWidth(), canvas.getHeight(), gaugePaint); 
     canvas.drawText(getContext().getString(R.string.percent_value, value), getWidth()/2, getHeight() * .6F, textPaint); 
     canvas.drawCircle(getWidth()/2, getHeight()/2, (getHeight()/2) - circlePaint.getStrokeWidth()/2, circlePaint); 
    } 

    public void setValue(int value) { 
     this.value = value; 
     invalidate(); 
    } 
} 

私はかなり確信して私はPorterDuffでこれを行うことができますが、私は方法がわかりません。

答えて

1

Android drawable resourcesは、すでにあなたがViewとオーバーライドonDrawをサブクラス化するために頼ることなくこれを行うために必要なすべてを与えます。

まず、drawableリソースから始めましょう。私たちは、ある色の円が別の色の円を覆っていることを望みます。このためには、でXMLで指定されているLayerDrawableを使用します。

Drawableは、レベルの値を持ちます。 DrawablesetLevelに電話をかけてレベル(0-10000)を調整できます。レベルを使用して、明るい円の外観を制御したいと考えています。そのためにはClipDrawableを使用します。これはXMLで定義されており、<clip>です。

サークル自体については、ShapeDrawable<shape>)を使用できます。ここでは、我々はすべて一緒にそれを置くとき、それは次のようになります。

<?xml version="1.0" encoding="utf-8"?> 
<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 

    <item android:id="@+id/field" android:gravity="fill"> 
     <shape android:shape="oval"> 
      <stroke android:width="2dp" android:color="@android:color/white"/> 
      <solid android:color="#FF78606D"/> 
     </shape> 
    </item> 

    <item android:id="@+id/progress" android:gravity="fill"> 
     <clip android:gravity="bottom" android:clipOrientation="vertical"> 
      <shape android:shape="oval" > 
       <stroke android:width="2dp" android:color="@android:color/white"/> 
       <solid android:color="#FFAB9BA6"/> 
      </shape> 
     </clip> 
    </item> 

</layer-list> 

今はちょうど `のTextViewを使用し、背景として、この描画可能に置くことができます。あなたの色に基づいて

<TextView 
     android:id="@+id/text" 
     android:layout_height="64dp" 
     android:layout_width="64dp" 
     android:layout_gravity="center" 
     android:background="@drawable/circle_progress" 
     android:gravity="center" 
     android:textAppearance="?android:textAppearanceLarge" 
     android:text="0%"/> 

私が暗いテーマであるTheme.AppCompatを使用。ここで

はそれをすべて一緒にどのように動作するかを示し、拙速なデモです:

public class MainActivity extends AppCompatActivity { 

    private TextView mTextView; 

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

     mTextView = (TextView) findViewById(R.id.text); 
     setLevel(0); 
     new AsyncTask<Void, Integer, Void>() { 
      @Override 
      protected Void doInBackground(Void... params) { 

       try { 
        for (int i = 0; i <= 100; i++) { 
         publishProgress(i); 
         Thread.sleep(100); 
        } 
       } catch (InterruptedException e) { 
        // just leave 
       } 

       return null; 
      }; 

      @Override 
      protected void onProgressUpdate(Integer... values) { 
       setLevel(values[0]); 
      } 
     }.execute(); 

    } 

    private void setLevel(int level) { 

     mTextView.setText(Integer.toString(level) + "%"); 
     LayerDrawable layerDrawable = (LayerDrawable) mTextView.getBackground(); 
     Drawable progress = layerDrawable.findDrawableByLayerId(R.id.progress); 
     progress.setLevel(level * 100); // drawable levels go 0-10000 
    } 

} 
+0

は、それが動作し、それはエレガントです、ありがとうございます。私はsetLevel()メソッドを知らなかった –

関連する問題