Android 实战项目分享(一)用Android Studio绘制贝塞尔曲线的艺术之旅

2023-09-15 16:46:09

一、项目概述


欢迎来到创意之源!我们精心打造的绘图应用程序将带你进入一个充满艺术和技术的奇妙世界。通过使用Android Studio,我们实现了绘制贝塞尔曲线的功能,让你能够轻松创作出令人惊叹的艺术作品。不论你是热爱绘画的大学生还是渴望学习的艺术爱好者,这个应用程序将为你点燃创作的激情,让你沉浸在绘画的乐趣中。


二、主要技术点

  1. 贝塞尔曲线的绘制:我们巧妙地利用Android Studio的绘图功能,实现了贝塞尔曲线的绘制。通过简单的操作,你可以自由操控曲线的形状和曲率,为你的艺术作品注入无限可能。

  2. JSON数据解析:我们应用程序支持JSON数据解析,让你能够轻松处理服务器返回的数据。这样,你可以从服务器获取配置文件等信息,并在绘画过程中灵活应用。

  3. 本地文件存取:我们还提供了本地文件存取功能,让你可以保存和管理自己的绘画作品。你可以在应用程序中随时查看、编辑和分享你的艺术杰作。

  4. 全屏启动页实现:我们特别优化了应用程序的启动页,实现了无缝过渡,避免了白屏的尴尬。你将享受到完美的用户体验,让你的创作之旅更加流畅自然。

  1. 动态权限申请:我们重视用户隐私和安全,因此应用程序支持动态权限申请。这意味着在使用过程中,我们将确保你对所需权限的控制,保护你的个人信息和设备安全。

  2. HTTPS通信:我们采用HTTPS通信协议,保证你的数据传输安全和隐私保护。无论是进行GET请求还是POST请求,你都可以放心地与服务器进行安全的数据交互。

  3. 通用隐私协议服务协议弹出窗口:我们关注用户隐私权,为了保障你的合法权益,我们在应用程序中提供了通用隐私协议服务协议弹出窗口。这让你清晰了解我们对你个人信息的处理方式,建立起互信的基础。

  4. 从服务器获取配置文件,并解析:我们的应用程序能够从服务器动态获取配置文件,并进行解析。这使你能够随时更新应用程序的功能和特性,保持与最新技术的同步。

  5. AgentWeb的使用和封装:我们采用了大名鼎鼎的AgentWeb,一行代码即可实现专属浏览器的功能。这为你提供了便捷的网络浏览和搜索功能,让你在创作中获得更多灵感和参考。

  6. 本地日志接口的封装:我们为应用程序封装了本地日志接口,使你可以灵活地记录和管理应用程序的运行情况。在发布版本时,你可以根据需要关闭日志记录,优化代码性能。


在这里插入图片描述

主要演示代码:

//PanelView.java
package com.csw.luck33;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class PanelView extends View {
    private static final String TAG = "PanelView";

    private Board mBoard;
    private Dot mDotStart;
    private Dot mDotControl1;
    private Dot mDotControl2;
    private Dot mDotEnd;

    private Paint mControlPaint;
    private Paint mBezierPaint;
    private Paint mTextPaint;


    public PanelView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mBoard = new Board();
        mDotStart = new Dot(this, mBoard, true);
        mDotControl1 = new Dot(this, mBoard, false);
        mDotControl2 = new Dot(this, mBoard, false);
        mDotEnd = new Dot(this, mBoard, true);

        mControlPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mControlPaint.setColor(Color.GREEN);
        mControlPaint.setStyle(Paint.Style.STROKE);
        mControlPaint.setStrokeWidth(5f);

        mBezierPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mBezierPaint.setColor(Color.BLUE);
        mBezierPaint.setStyle(Paint.Style.STROKE);
        mBezierPaint.setStrokeWidth(6f);

        mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mTextPaint.setColor(Color.BLACK);
        mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mTextPaint.setStrokeWidth(2);
        mTextPaint.setTextSize(30);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        //Log.d(TAG, "onTouchEvent:" + event.getAction() + "(" + event.getX() + "," + event.getY() + ")");
        return mDotStart.touchEvent(event)
                || mDotControl1.touchEvent(event)
                || mDotControl2.touchEvent(event)
                || mDotEnd.touchEvent(event);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        mBoard.computeWidthAndHeight(this);
        mDotStart.setCenterPoint(mBoard.getTopLeft());

        mDotControl1.setCenterPoint(mBoard.getTopCenter());

        mDotControl2.setCenterPoint(mBoard.getBottomCenter());

        mDotEnd.setCenterPoint(mBoard.getBottomRight());

    }


    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mBoard.draw(canvas);
        drawBezierText(mDotStart, mDotControl1, mDotControl2, mDotEnd, canvas);
        drawLine(mDotStart, mDotControl1, canvas);
        drawLine(mDotControl1, mDotEnd, canvas);
        drawLine(mDotStart, mDotControl2, canvas);
        drawLine(mDotControl2, mDotEnd, canvas);
        drawBezier(mDotStart, mDotControl1, mDotControl2, mDotEnd, canvas);

        mDotStart.draw(canvas);
        mDotControl1.draw(canvas);
        mDotControl2.draw(canvas);
        mDotEnd.draw(canvas);

    }

    private void drawLine(Dot start, Dot end, Canvas canvas) {
        canvas.drawLine(start.getX(), start.getY(), end.getX(), end.getY(), mControlPaint);
    }

    private Path mBezierPath = new Path();

    private void drawBezier(Dot start, Dot control1, Dot control2, Dot end, Canvas canvas) {
        mBezierPath.reset();
        mBezierPath.moveTo(start.getX(), start.getY());
        mBezierPath.cubicTo(control1.getX(), control1.getY(), control2.getX(), control2.getY(), end.getX(), end.getY());
        canvas.drawPath(mBezierPath, mBezierPaint);
    }

    private void drawBezierText(Dot start, Dot control1, Dot control2, Dot end, Canvas canvas) {
        canvas.drawText("moveTo( " + start.mCenterPointVirtual.x + " , " + start.mCenterPointVirtual.y + " );"
                        + " cubicTo(" + control1.mCenterPointVirtual.x + " , " + control1.mCenterPointVirtual.y + " , "
                        + control2.mCenterPointVirtual.x + " , " + control2.mCenterPointVirtual.y + " , "
                        + end.mCenterPointVirtual.x + " , " + end.mCenterPointVirtual.y
                        + " );"
                , mBoard.getTopLeft().x / 2f, mBoard.getTopLeft().y / 2f, mTextPaint);
    }
}

三、开发环境

开发环境是 Android Studio 最新版本,只要从官网下载最新的即可编译运行 。

jdk 版本是 17 ,sdk 版本31,gradle plugin version 4.2.2 ,gradle version 版本6.7.1 。

在这里插入图片描述

在这里插入图片描述

四、运行演示

1、启动程序,首先是1s的启动界面。

2、进入主界面

在这里插入图片描述

在这里插入图片描述

现在下载源码,让Android Studio与你的艺术梦想相遇,一起创造属于你自己的独特世界~

更多推荐

二分类问题的解决利器:逻辑回归算法详解(一)

文章目录🍋引言🍋逻辑回归的原理🍋逻辑回归的应用场景🍋逻辑回归的实现🍋引言逻辑回归是机器学习领域中一种重要的分类算法,它常用于解决二分类问题。无论是垃圾邮件过滤、疾病诊断还是客户流失预测,逻辑回归都是一个强大的工具。本文将深入探讨逻辑回归的原理、应用场景以及如何在Python中实现它。🍋逻辑回归的原理逻辑回归

Rust解决Bug错误“error: future cannot be sent between threads safely”

介绍:在开发过程中,我们可能会遇到错误消息:“error:futurecannotbesentbetweenthreadssafely”。这个错误通常是由于使用了不可发送(notSend)的类型引起的,尤其是std::sync::MutexGuard类型。这意味着我们不能将一个互斥锁(mutex)在不同线程间进行传递,

在游戏行业中需要选择高防服务器么?

对于飞速发展的互联网,导致攻击成本越来越低,最明显的就是游戏行业,很多游戏公司都遭受此类网络攻击,所以更需要选择高防服务器,让防御功能变得更加靠谱,游戏公司的高防服务器应该如何选择呢?今天就让小编来讲一讲吧!服务器配置要高。游戏行业和普通的中小型企业对于服务器的需求是不一样的,要保障游戏页面的流畅,这对于玩家来说是非常

QT-day2

1、完善登录框头文件widget.h#ifndefWIDGET_H#defineWIDGET_H#include<QWidget>#include<QMessageBox>//消息对话框类头文件#include<QDebug>#include<QPushButton>#include"second.h"QT_BEGIN

Linux学习之gdb的使用

目录1.Debug与Release模式如何证明debug是可以被调试的?2.Linux调试器-gdb使用gdb调试的指令指令一:list(l)查看源代码编辑​编辑命令二:run(r)运行程序命令三:breakpoint(b)设置断点命令四:infobreak(info)查看断点命令五:deletebreakpoint(

基于Java的设计模式 - 代理模式

代理模式是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式。简单来讲就是在不修改目标对象的基础上,增强主业务逻辑的设计模式。代理模式基本可分为三种静态代理JDK动态代理CGLIB动态代理上述简单分就是静态和动态代理,静态代理即程序运行之前已创建了代理类,动态代理是程序运行时通过反射机制动

幸福里基于 Flink & Paimon 的流式数仓实践

摘要:本文整理自字节跳动基础架构工程师李国君,在StreamingLakehouseMeetup的分享。幸福里业务是一种典型的交易、事务类型的业务场景,这种业务场景在实时数仓建模中遇到了诸多挑战。本次分享主要介绍幸福里业务基于Flink&Paimon构建流式数仓的实践经验,从业务背景、流批一体数仓架构、实践中遇到的问题

新能源汽车驱动电机的基本知识

学习目标:了解电机的基本知识。能力目标:培养学生搜集和整理相关资料的能力。素质目标:培养学生良好的职业素养。额定电店.在夫见定条件下电池工作的*于佳电压知识准备术语和定义。(1)驱动电机系统通过有效的控制策略将动力蓄电池提供的直流电转化为交流实现电机的正转以及反转控制。在减速/制动时将电机发出的交流电转化为直流电,将能

APEX数据源加载实现Excel表数据导入及自定义存储过程

在APEX应用程序中会涉及到数据加载,说白了就是导入导出数据到数据库中,这里就以Excel导入数据到TEST_DATA_WXX表为例,来学习共享组件数据源数据加载定义1第一步先导出一个数据模板进入《王小小鸭的学习demo》打开【用户管理】-【操作】-【下载】-【Excel】下载后的Excel数据表是这样的↓2.建表TE

【Linux】基础IO,软硬链接,动静态库

1.认识IO什么是IOI/O简单来说对应的就是两个单词Input和Output,指的是计算机系统与外部环境(通常是硬件设备或其他计算机系统)之间的数据交换过程I/O可以分为两种主要类型:输入(Input):输入是指计算机系统接收来自外部环境的数据或信息的过程。例如,当用户在键盘上输入文本时,这些输入字符被视为输入操作。

9.21号作业

实现把注册的信息导入数据库中second.h#ifndefSECOND_H#defineSECOND_H#include<QWidget>#include<QDebug>namespaceUi{classSecond;}classSecond:publicQWidget{Q_OBJECTpublic:voidnewsl

热文推荐