美文网首页
Android_自定义控件(画板)

Android_自定义控件(画板)

作者: 书虫大王X | 来源:发表于2019-11-26 22:14 被阅读0次

使用到的知识点:
1、Canvas总结
2、path总结
3、paint总结

实例框架:


关系图

sliderView类:

public class drawView extends View {
    Path mpath;
//    操作的数组
    private ArrayList<Grahp> grahps;
//    原始数组
    private ArrayList<Grahp> orginaGrahps;
    private int lineColor = Color.BLACK;
    private int lineWidth = 10;

    public drawView(Context context) {
        this(context,null);
    }
    public drawView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        grahps = new ArrayList<>();
        orginaGrahps = new ArrayList<>();
        setBackgroundColor(Color.WHITE);  
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
//        遍历数组(遍历器)
        Iterator<Grahp> iterator = grahps.iterator();
        while (iterator.hasNext()) {
            Grahp grahp = iterator.next();
            canvas.drawPath(grahp.path,grahp.paint);
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
                mPaint.setColor(lineColor);
                mPaint.setStrokeWidth(lineWidth);
                mPaint.setStyle(Paint.Style.STROKE);
                mpath = new Path();
                mpath.moveTo(event.getX(),event.getY());
                Grahp temp = new Grahp(mpath,mPaint);
                grahps.add(new Grahp(mpath,mPaint));
                orginaGrahps.add(temp);
                break;
            case MotionEvent.ACTION_MOVE:
                mpath.lineTo(event.getX(),event.getY());
                break;
            case MotionEvent.ACTION_UP:
                break;
        }
        invalidate();
        return true;
    }
    private class Grahp{
        Paint paint;
        Path path;
        public Grahp(Path path,Paint paint){
            this.paint = paint;
            this.path = path;

        }
    }
//    还原上一步
    public void retunrnLastStep(){
        if (grahps.size() < orginaGrahps.size()) {
            int index = grahps.size() - 1 + 1;
            grahps.add(orginaGrahps.get(index));
        }
        invalidate();
    }
    public void removeLast(){
        if (grahps.size() > 0) {
            grahps.remove(grahps.size() - 1);
            invalidate();
        }
    }
    public void removeAll(){
        grahps.clear();
        invalidate();
    }
    public void setLineWidth(int lineWidth) {
        this.lineWidth = lineWidth;
    }
    public int getLineWidth() {
        return lineWidth;
    }
    public void setLineColor(int lineColor) {
        this.lineColor = lineColor;
    }
    public int getLineColor() {
        return lineColor;
    }
}

drawView类:

public class slideView extends View {

    private Path mPath;
    private Paint linePaint;
    private Paint circlePaitn;
    private int circleColor = Color.RED;
    private int lineColor = Color.BLACK;
//    线条的粗细
    private int lineSize = 10;
//   小圆点
    private int cY;
    private int cX;
    private int radius;
//    半径所除的数
    private int thymbScale = 4;
//    记录触摸点的坐标
    private float touchPosition = 10;
//    管理进度条的画笔
    private Paint progressPaint;
    private int progressColor = Color.MAGENTA;

    public static int PROGRESS = 0;
    public static int SLIDER = 1;
    private  int style = PROGRESS;
//    进度最大值
    private int max = 100;
    private float progress;
    private onSliderChangedLisenter onSliderChangedLisenter;

    public slideView(Context context) {
        this(context,null);
    }
    public slideView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    private void init() {
        mPath = new Path();
        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        linePaint.setColor(lineColor);
        linePaint.setStrokeWidth(lineSize);
        circlePaitn = new Paint(Paint.ANTI_ALIAS_FLAG);
        circlePaitn.setColor(circleColor);
        progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        progressPaint.setColor(progressColor);
        progressPaint.setStrokeWidth(lineSize);
        setBackgroundColor(Color.WHITE);
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (getWidth() > getHeight()){
//            屏幕是横着的
            canvas.drawLine(0,(getHeight() )/2,getWidth(),(getHeight())/2, linePaint);
            if (touchPosition > 0) {
                canvas.drawLine(0,(getHeight() )/2,touchPosition,(getHeight())/2, progressPaint);
            }
            radius = getHeight()/thymbScale;
            cX = (int)touchPosition;
        }else {
//            竖屏
            canvas.drawLine((getWidth())/2,0,(getWidth())/2,getHeight(), linePaint);
            if (touchPosition > 0) {
                canvas.drawLine((getWidth())/2,0,(getWidth())/2,touchPosition, progressPaint);
            }
            radius = getWidth()/thymbScale;
            cX = (getWidth())/2;
        }
//        画小圆点
        if (style == SLIDER) {
            canvas.drawCircle(cX,cY,radius,circlePaitn);
        }
    }
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
//                进度条的小圆点放大
                thymbScale = 2;
                if (getWidth() > getHeight()) {
//                    横屏
                    touchPosition = event.getX();
                }else {
                    touchPosition = event.getY();
                }
                callBack();
                break;
            case MotionEvent.ACTION_MOVE:
//                获取当前触摸点的坐标
                if (getWidth() > getHeight()) {
//                    横屏
                    touchPosition = event.getX();
                    if (touchPosition < 0) {
                        touchPosition = 0;
                    } else if (touchPosition > getWidth()) {
                        touchPosition = getWidth();
                    }
                }else {
                    touchPosition = event.getY();
                    if (touchPosition < 0) {
                        touchPosition = 0;
                    }else if(touchPosition > getHeight()){
                        touchPosition = getHeight();
                    }
                }
                callBack();
                break;
            case MotionEvent.ACTION_UP:
                thymbScale = 4;
                break;
        }
        if (style == SLIDER) {
            invalidate();
        }
        return true;
    }
    private void callBack(){
        if (onSliderChangedLisenter != null) {
            if (getWidth() > getHeight()) {
                progress = touchPosition/getWidth();
            }else {
                progress = touchPosition/getHeight();
            }
            onSliderChangedLisenter.progerssChanged(progress*max);
        }
    }
    public void setStyle(int style) {
        this.style = style;
    }
    public void setProgress(int progress){
//        计算比例
        this.progress = (float)((progress*1.0) / max);
        setProgress(this.progress);
    }
    public void setProgress(float progress) {
        this.progress = progress;
        if (progress < 1.001) {
            //        将进度值转化为控件的尺寸位置
            if (getWidth() > getHeight()) {
                touchPosition = progress * getWidth();
            }else {
                touchPosition = progress * getHeight();
            }
        }
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        //        将进度值转化为控件的尺寸位置
        if (getWidth() > getHeight()) {
            touchPosition = progress * getWidth();
        }else {
            touchPosition = progress * getHeight();
        }
        invalidate();
    }
    public float getProgress() {
        return progress;
    }
    public void setMax(int max) {
        this.max = max;
    }
    public int getMax() {
        return max;
    }
    public interface onSliderChangedLisenter{
        void progerssChanged(float progress);
    }
    public void setOnSliderChangedLisenter(onSliderChangedLisenter onSliderChangedLisenter){
        this.onSliderChangedLisenter = onSliderChangedLisenter;
    }
}

xml布局文件:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toTopOf="@+id/text2"
        app:layout_constraintTop_toTopOf="parent">

        <!--滑动条-->
        <xn.ky.a1102_zdy_huaban_1.slideView
            android:id="@+id/slider"
            android:layout_width="20dp"
            android:layout_height="match_parent"
            android:layout_marginLeft="10dp"
            android:layout_marginBottom="50dp"
            android:layout_marginTop="50dp"
            app:layout_constraintLeft_toLeftOf="parent"/>

        <!--画板-->
        <xn.ky.a1102_zdy_huaban_1.drawView
            android:id="@+id/dradView"
            android:layout_width="0dp"
            android:layout_height="match_parent"
            app:layout_constraintLeft_toRightOf="@id/slider"
            app:layout_constraintRight_toLeftOf="@+id/color" />
        <LinearLayout
            android:id="@+id/color"
            android:layout_width="50dp"
            android:layout_height="match_parent"
            android:orientation="vertical"
            app:layout_constraintRight_toRightOf="parent"
            android:layout_marginRight="20dp"
            android:gravity="center">

            <Button
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@color/colorAccent"
                android:onClick="chioceColor"/>
            <Button
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@color/colorPrimary"
                android:onClick="chioceColor"/>
            <Button
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#000000"
                android:onClick="chioceColor"/>
            <Button
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="#ddde11"
                android:onClick="chioceColor"/>

        </LinearLayout>

    </androidx.constraintlayout.widget.ConstraintLayout>

    <LinearLayout
        android:id="@+id/text2"
        android:orientation="horizontal"
        android:layout_width="match_parent"
        android:layout_height="60dp"
        app:layout_constraintBottom_toBottomOf="parent"
        android:gravity="center">

        <Button
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:text="上一步"
            android:onClick="lastStep"/>
        <Button
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:text="撤销"
            android:onClick="goBack"/>
        <Button
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:text="清空"
            android:onClick="clear"/>
        <Button
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:text="橡皮擦"
            android:onClick="eraser"/>
        <Button
            android:layout_width="70dp"
            android:layout_height="wrap_content"
            android:text="保存"
            android:onClick="save"/>
    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity类:

public class MainActivity extends AppCompatActivity {
    drawView drawView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        final slideView  slider = findViewById(R.id.slider);
        slider.setMax(30);
        slider.setStyle(slideView.SLIDER);
//        获取画板对象
        drawView = findViewById(R.id.dradView);
        slider.setProgress(drawView.getLineWidth());
        slider.setOnSliderChangedLisenter(new slideView.onSliderChangedLisenter() {
            @Override
            public void progerssChanged(float progress) {
//                将滑动条的进度值设置为画笔粗细
                drawView.setLineWidth((int)progress);
            }
        });
    }
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
    }
    @Override
    protected void onResume() {
        super.onResume();
//        程序运行起来屏幕就是横屏
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);
    }
    public void chioceColor(View view) {
//        获取按键的背景颜色
        ColorDrawable drawable = (ColorDrawable)view.getBackground();
        drawView.setLineColor(drawable.getColor());
    }
//    还原到上一步
    public void lastStep(View view) {
        drawView.retunrnLastStep();
    }
    public void goBack(View view) {
        drawView.removeLast();
    }
    public void clear(View view) {
        drawView.removeAll();
    }
    public void eraser(View view) {
        ColorDrawable drawable = (ColorDrawable)drawView.getBackground();
        if (drawable != null){
            drawView.setLineColor(drawable.getColor());
        }
    }
    public void save(View view) {
    }
}
成果布局:
布局样式(保存功能还没有实现)

相关文章

网友评论

      本文标题:Android_自定义控件(画板)

      本文链接:https://www.haomeiwen.com/subject/ytlzmctx.html