文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Android如何实现绘画板功能

2023-06-15 05:31

关注

这篇文章主要介绍了Android如何实现绘画板功能,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

实现流程:

        一、预期效果
        二、设置横竖屏切换
        三、确定布局
        四、自定义滑动条
        五、绘画区域
        六、MainActivity

实现步骤:

一、预期效果

Android如何实现绘画板功能

二、设置横竖屏切换

screenOrientation属性       作用
user用户当前设置的方向。
unspecified由系统选择显示方向,不同的设备可能会有所不同。(旋转手机,界面会跟着旋转)
landscape限制界面为横屏,旋转屏幕也不会改变当前状态。
portrait限制界面为竖屏,旋转屏幕也不会改变当前状态。
behind与前一个activity方向相同。
sensor根据传感器定位方向,旋转手机90度,180,270,360,界面都会发生变化。
nosensor不由传感器确定方向。旋转设备的时候,界面不会跟着旋转。初始界面方向由系统提供。
sensorLandscape(横屏的旋转,不会出现竖屏的现象)根据传感器定位方向,旋转手机180度界面旋转。一般横屏游戏会是这个属性。
sensorPortrait(竖屏的旋转,不会出现横屏的现象)根据传感器定位方向,旋转手机180度界面会旋转。

三、确定布局

因为横竖屏切换后控件的宽高都是不一样的,也就是不固定的,不能用线性布局,而是根据相对位置进行布局。先用constraintLayout约束,再将小控件组合成一个线性布局,然后对整个线性布局进行相对布局。

Android如何实现绘画板功能

<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_constraintTop_toTopOf="parent"        app:layout_constraintBottom_toTopOf="@id/operation"        >        <!--滑动条-->        <com.example.a16drawboard.Slider            android:id="@+id/slider"            android:layout_width="20dp"            android:layout_height="match_parent"            android:layout_marginLeft="20dp"            android:layout_marginTop="20dp"            android:layout_marginBottom="20dp"            app:layout_constraintLeft_toLeftOf="parent"            />        <!--画板-->        <com.example.a16drawboard.DrawBoardView            android:id="@+id/board"            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="60dp"            android:layout_height="match_parent"            android:orientation="vertical"            android:layout_marginRight="20dp"            app:layout_constraintRight_toRightOf="parent"            android:gravity="center">            <Button                android:layout_width="match_parent"                android:layout_height="50dp"                android:background="@color/colorAccent"                android:onClick="choiceColor"/>            <Button                android:layout_width="match_parent"                android:layout_height="50dp"                android:background="@color/colorPrimary"                android:onClick="choiceColor"/>            <Button                android:layout_width="match_parent"                android:layout_height="50dp"                android:background="#f00"                android:onClick="choiceColor"/>            <Button                android:layout_width="match_parent"                android:layout_height="50dp"                android:background="#000"                android:onClick="choiceColor"/>        </LinearLayout>    </androidx.constraintlayout.widget.ConstraintLayout>    <LinearLayout        android:id="@+id/operation"        android:layout_width="match_parent"        android:layout_height="60dp"        android:background="#f00"        android:orientation="horizontal"        app:layout_constraintBottom_toBottomOf="parent"        android:gravity="center">        <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"/>        <Button            android:layout_width="70dp"            android:layout_height="wrap_content"            android:text="上一步"            android:onClick="lastStep"/>    </LinearLayout></androidx.constraintlayout.widget.ConstraintLayout>

四、自定义滑动条

public class Slider extends View {    private int lineSize = 6; // 线条的粗细    private int lineColor = Color.BLACK;// 默认线条颜色    private Paint linePaint;    private Paint circlePaint; // 圆点画笔    private int thumbColor = Color.MAGENTA; // 圆点颜色    private int cx; // 中心点x    private int cy; // 中心点y    private int radius; // 小圆点半径    private int thumbScale = 4; // 圆点缩放尺寸    private float position; // 触摸点的坐标    private Paint progressPaint; // 进度条进度的画笔    private int progressColor = Color.MAGENTA; // 进度条颜色    public static int PROGRESS = 0; // 进度条    public static int SLIDER = 1; // 滑动条    private int style = PROGRESS; // 用户选择的样式,默认为进度条    public int max = 100; // 设置最大值    public float progress; // 进度值    private OnSliderChangeListener onSliderChangeListener; // 滑动改变监听者    public Slider(Context context) {        super(context);    }    public Slider(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    private void init(){        // 背景线        linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        linePaint.setColor(lineColor);        linePaint.setStrokeWidth(lineSize);        // 圆点        circlePaint = new Paint(Paint.ANTI_ALIAS_FLAG);        circlePaint.setColor(thumbColor);        circlePaint.setStyle(Paint.Style.FILL);        // 进度条        progressPaint = new Paint(Paint.ANTI_ALIAS_FLAG);        progressPaint.setColor(progressColor);        progressPaint.setStrokeWidth(lineSize);    }    @Override    protected void onDraw(Canvas canvas) {        if (getWidth() > getHeight()){            // 横着            canvas.drawLine(0, getHeight()/2, getWidth(), getHeight()/2, linePaint);            if (position>0){                canvas.drawLine(0, getHeight()/2, position, getHeight()/2, progressPaint);            }            radius = getHeight()/thumbScale;            cy = getHeight()/2;            // 确定cx的值            if (position < radius) {                cx = radius;            }else if (position > getWidth()-radius){                cx = getWidth()-radius;            }else {                cx = (int) position;            }        }else{            // 竖着            canvas.drawLine(getWidth()/2, 0, getWidth()/2, getHeight(), linePaint);            if (position>0){                canvas.drawLine(getWidth()/2, 0, getWidth()/2, position, progressPaint);            }            radius = getWidth()/thumbScale;            cx = getWidth()/2;            // 确定中心点cy的值            if (position<radius){                cy = radius;            }else if (position > getHeight()-radius){                cy = getHeight()-radius;            }else {                cy = (int) position;            }        }        // 画小圆点        if (style == SLIDER){            canvas.drawCircle(cx,cy,radius,circlePaint);        }    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                // 圆点放大                thumbScale = 2;                // 点下去就到那个位置                if (getWidth()>getHeight()){                    // 横向时,y不变 x改变                    position = event.getX();                }else {                    // 纵向时,x不变 y改变                    position = event.getY();                }                callback();                break;            case MotionEvent.ACTION_MOVE:                // 获取当前触摸点的值XY                if (getWidth()>getHeight()){                    // 横向时,y不变 x改变                    position = event.getX();                    if (position<0){                        progress = 0;                    }else if (position>getWidth()){                        position = getWidth();                    }                }else {                    // 竖着时,x不变 y改变                    position = event.getY();                    if (position<0){                        progress = 0;                    }else if (position>getHeight()){                        position = getHeight();                    }                }                callback();                break;            case MotionEvent.ACTION_UP:                thumbScale = 4;                break;        }        if (style == SLIDER){            invalidate();        }        return true;    }    private void callback(){        if (onSliderChangeListener != null){            if (getWidth()>getHeight()){                progress = position/getWidth();            }else {                progress = position/getHeight();            }            onSliderChangeListener.progressChange(progress*max);        }    }    public int getStyle() {        return style;    }    public void setStyle(int style) {        this.style = style;    }    public float getProgress() {        return progress;    }    public void setProgress(int progress){        // 计算比例        float rate = (float)(progress*1.0/max);        setProgress(rate);    }    public void setProgress(float progress) {        this.progress = progress;        if (progress <1.001) {            // 将进度值转化为控件中的尺寸位置            if (getWidth() > getHeight()) {                position = progress * getWidth();            } else {                position = progress * getHeight();            }            invalidate();        }    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        if (getWidth() > getHeight()) {            position = progress * getWidth();        } else {            position = progress * getHeight();        }    }    public void setMax(int max) {        this.max = max;    }    public interface OnSliderChangeListener{        void progressChange(float progress);    }    public void setOnSliderChangeListener(OnSliderChangeListener onSliderChangeListener) {        this.onSliderChangeListener = onSliderChangeListener;    }}

五、绘画区域

public class DrawBoardView extends View {    private ArrayList<Graph> graphs; // 操作数组    private ArrayList<Graph> orginalGraphs; // 原始数组    private int lineColor = Color.BLACK;    private int lineSize = 5;    Path mPath;    public DrawBoardView(Context context) {        super(context);    }    public DrawBoardView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init();    }    private void init(){        // 初始化数组        graphs = new ArrayList<>();        orginalGraphs = new ArrayList<>();        setBackgroundColor(Color.WHITE);    }    @Override    protected void onDraw(Canvas canvas) {        // 遍历数组        Iterator<Graph> iterator = graphs.iterator();        while (iterator.hasNext()){            // 从集合中获取一个图形对象            Graph line = iterator.next();            // 绘制图形            canvas.drawPath(line.path,line.paint);        }    }    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction()){            case MotionEvent.ACTION_DOWN:                // 创建这条线对应的paint和path                Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);                mPaint.setColor(lineColor);                mPaint.setStrokeWidth(lineSize);                mPaint.setStyle(Paint.Style.STROKE);                mPath = new Path();                // 设置图形的起点                mPath.moveTo(event.getX(),event.getY());                // 保存当前这个图形的详细信息                Graph temp = new Graph(mPaint,mPath);                graphs.add(temp);                orginalGraphs.add(temp);                break;            case MotionEvent.ACTION_MOVE:                // 连接从path终点到当前触摸点的线                mPath.lineTo(event.getX(),event.getY());                break;            case MotionEvent.ACTION_UP:                break;        }        invalidate();        return true;    }    // 用私有类来管理图形的画笔和路径    private class Graph{        Paint paint;        Path path;        public Graph(Paint paint,Path path){            this.paint=paint;            this.path=path;        }    }    // 删除最后一个图形  撤销    public void removeLast(){        if (graphs.size() >0){            graphs.remove(graphs.size()-1);            invalidate();        }    }    // 删除所有 清空    public void removeAll(){        graphs.clear();        invalidate();    }    // 还原上一步    public void returnToLastStep(){        // 判断缓存中是否有        if (graphs.size() < orginalGraphs.size()){            // 获取上一步的索引值            int index = graphs.size()-1+1;            // 从缓存中获取index,添加到操作数组中            graphs.add(orginalGraphs.get(index));            invalidate();        }    }    public int getLineSize() {        return lineSize;    }    public void setLineSize(int lineSize) {        this.lineSize = lineSize;    }    public int getLineColor() {        return lineColor;    }    public void setLineColor(int lineColor) {        this.lineColor = lineColor;    }}

六、MainActivity

public class MainActivity extends AppCompatActivity {    private DrawBoardView boardView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        // 获取画板对象        boardView = findViewById(R.id.board);        // 获取滑动条对象        final Slider slider = findViewById(R.id.slider);        slider.setStyle(Slider.SLIDER);        slider.setMax(30);        slider.setOnSliderChangeListener(new Slider.OnSliderChangeListener() {            @Override            public void progressChange(float progress) {                boardView.setLineSize((int) progress);            }        });        slider.setProgress(boardView.getLineSize());    }    @Override    public void onWindowFocusChanged(boolean hasFocus) {        super.onWindowFocusChanged(hasFocus);    }    @Override    protected void onStart() {        super.onStart();    }    @Override    protected void onResume() {        super.onResume();        // 设置横屏        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);    }    @Override    protected void onPause() {        super.onPause();    }    @Override    protected void onStop() {        super.onStop();    }    // 选择颜色 获取按钮上面的背景颜色    public void choiceColor(View view) {        // 获取按钮上面的背景颜色        ColorDrawable drawable = (ColorDrawable) view.getBackground();        // 获取颜色        boardView.setLineColor(drawable.getColor());    }    // 撤回    public void goBack(View view) {        boardView.removeLast();    }    // 清空    public void clear(View view) {        boardView.removeAll();    }    // 橡皮擦    public void eraser(View view) {        // 获取画板的drawable        ColorDrawable drawable = (ColorDrawable) boardView.getBackground();        // 设置线条颜色和背景色相同        if (drawable != null){            boardView.setLineColor(drawable.getColor());        }else {            boardView.setLineColor(Color.TRANSPARENT);        }    }    // 保存    public void save(View view) {    }    // 还原    public void lastStep(View view) {        boardView.returnToLastStep();    }}

到这里就结束啦。

Android是什么

Android是一种基于Linux内核的自由及开放源代码的操作系统,主要使用于移动设备,如智能手机和平板电脑,由美国Google公司和开放手机联盟领导及开发。

感谢你能够认真阅读完这篇文章,希望小编分享的“Android如何实现绘画板功能”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯