/res/layout/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:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.androidview.MainActivity" > <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="android-coding.blogspot.com" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="CornerPathEffect radius" /> <SeekBar android:id="@+id/radius" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="500" android:progress="30" /> <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:text="DashPathEffect phase" /> <SeekBar android:id="@+id/phase" android:layout_width="match_parent" android:layout_height="wrap_content" android:max="100" android:progress="30" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <ToggleButton android:id="@+id/combineffect" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textOff="SumPathEffect" android:textOn="ComposePathEffect" /> <RadioGroup android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <RadioButton android:id="@+id/styleFill" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="FILL" android:checked="true" /> <RadioButton android:id="@+id/styleStroke" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="STROKE" /> <RadioButton android:id="@+id/styleFillAndStroke" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="FILL_AND_STROKE" /> </RadioGroup> </LinearLayout> <com.example.androidview.MyView android:id="@+id/myview" android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
MyView.java
package com.example.androidview; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ComposePathEffect; import android.graphics.CornerPathEffect; import android.graphics.DashPathEffect; import android.graphics.Paint; import android.graphics.Path; import android.graphics.SumPathEffect; import android.graphics.Path.Direction; import android.graphics.PathEffect; import android.util.AttributeSet; import android.view.View; public class MyView extends View { Paint paintBorder, paintCircle; Path pathBorder, pathCircle; Path pathShape; float cornerRadius; float dashPhase; float[] intervals = {50.0f, 50.0f}; //true: ComposePathEffect //false: SumPathEffect boolean combinPathEffect; Paint.Style style = Paint.Style.FILL; public MyView(Context context) { super(context); init(); } public MyView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MyView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); init(); } private void init() { paintBorder = new Paint(); paintBorder.setColor(Color.BLUE); paintBorder.setStrokeWidth(5); paintCircle = new Paint(); paintCircle.setColor(Color.RED); paintCircle.setStrokeWidth(5); pathBorder = new Path(); pathCircle = new Path(); pathShape = new Path(); pathShape.moveTo(0, 0); pathShape.lineTo(10, 20); pathShape.lineTo(20, 0); pathShape.close(); cornerRadius = 30.0f; dashPhase = 30.0f; } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); canvas.drawColor(Color.GRAY); pathBorder.reset(); pathBorder.moveTo(50, 50); pathBorder.lineTo(50, getHeight()-50); pathBorder.lineTo(getWidth()-50, getHeight()-50); pathBorder.lineTo(getWidth()-50, 50); pathBorder.close(); float radius; pathCircle.reset(); if(getWidth()>getHeight()){ radius = getHeight()/4; }else{ radius = getWidth()/4; } pathCircle.addCircle(getWidth()/2, getHeight()/2, radius, Direction.CCW); CornerPathEffect cornerPathEffect = new CornerPathEffect(cornerRadius); DashPathEffect dashPathEffect = new DashPathEffect(intervals, dashPhase); PathEffect pathEffect; if(combinPathEffect){ pathEffect = new ComposePathEffect(dashPathEffect, cornerPathEffect); }else{ pathEffect = new SumPathEffect(dashPathEffect, cornerPathEffect); } paintBorder.setStyle(style); paintCircle.setStyle(style); paintBorder.setPathEffect(pathEffect); paintCircle.setPathEffect(pathEffect); canvas.drawPath(pathBorder, paintBorder); canvas.drawPath(pathCircle, paintCircle); } public void setCornerRadius(float r){ cornerRadius = r; invalidate(); } public void setDashPhase(float p){ dashPhase = p; invalidate(); } public void setCombinPathEffect(boolean e){ combinPathEffect = e; invalidate(); } public void setStyle(Paint.Style s){ style = s; invalidate(); } }
MainActivity.java
package com.example.androidview; import android.app.Activity; import android.graphics.Paint; import android.os.Bundle; import android.widget.CompoundButton; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.RadioButton; import android.widget.SeekBar; import android.widget.SeekBar.OnSeekBarChangeListener; import android.widget.ToggleButton; public class MainActivity extends Activity { private MyView myView; private SeekBar seekBarRadius, seekBarPhase; ToggleButton buttonEffect; RadioButton radioFill, radioStroke, radioFillAndStroke; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); myView = (MyView)findViewById(R.id.myview); seekBarRadius = (SeekBar)findViewById(R.id.radius); seekBarRadius.setOnSeekBarChangeListener(seekBarRadiusChangeListener); seekBarPhase = (SeekBar)findViewById(R.id.phase); seekBarPhase.setOnSeekBarChangeListener(seekBarPhaseChangeListener); buttonEffect = (ToggleButton)findViewById(R.id.combineffect); buttonEffect.setOnCheckedChangeListener(buttonEffectCheckedChangeListener); radioFill = (RadioButton)findViewById(R.id.styleFill); radioStroke = (RadioButton)findViewById(R.id.styleStroke); radioFillAndStroke = (RadioButton)findViewById(R.id.styleFillAndStroke); radioFill.setOnCheckedChangeListener(radioOnCheckedChangeListener); radioStroke.setOnCheckedChangeListener(radioOnCheckedChangeListener); radioFillAndStroke.setOnCheckedChangeListener(radioOnCheckedChangeListener); } OnSeekBarChangeListener seekBarRadiusChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setCornerRadius(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnSeekBarChangeListener seekBarPhaseChangeListener = new OnSeekBarChangeListener(){ @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { myView.setDashPhase(progress); } @Override public void onStartTrackingTouch(SeekBar seekBar) {} @Override public void onStopTrackingTouch(SeekBar seekBar) {} }; OnCheckedChangeListener buttonEffectCheckedChangeListener = new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { myView.setCombinPathEffect(isChecked); }}; OnCheckedChangeListener radioOnCheckedChangeListener = new OnCheckedChangeListener(){ @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if(radioFill.isChecked()){ myView.setStyle(Paint.Style.FILL); }else if(radioStroke.isChecked()){ myView.setStyle(Paint.Style.STROKE); }else{ myView.setStyle(Paint.Style.FILL_AND_STROKE); } } }; }
- More examples of drawing path on custom View.
No comments:
Post a Comment