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

news2024/11/14 15:36:26

一、项目概述


欢迎来到创意之源!我们精心打造的绘图应用程序将带你进入一个充满艺术和技术的奇妙世界。通过使用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与你的艺术梦想相遇,一起创造属于你自己的独特世界~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1013734.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

VS2015+opencv 3.4.6开发环境

VS2015+opencv 3.4.6开发环境 一、安装包下载二、安装过程三、VS环境配置四、测试一、安装包下载 这里提供两种下载方法:   1. opencv官网   2. csdn资源下载 二、安装过程 2.1 下载opencv-3.4.6 安装包 2.2 双击开始安装,选择要安装目录,点击Extract。  2.3 等待解…

I/O多路复用三种实现

一.select 实现 (1)select流程 基本流程是: 1. 先构造一张有关文件描述符的表; fd_set readfds 2. 清空表 FD_ZERO() 3. 将你关心的文件描述符加入到这…

天翎知识管理系统:智能化搜索引擎,快速定位知识资源

关键词:知识管理系统、全文检索 编者按:在当今知识经济时代,企业所面临的知识资源越来越丰富,如何高效地管理和利用这些资源成为了一个重要的问题。天翎知识管理系统凭借其智能化搜索引擎,可以帮助企业快速定位知识资源…

论文管理系统设计与实现

毕业论文管理系统的设计与实现 学生: 指导教师: 内容摘要:毕业论文管理系统是典型的MIS信息管理系统,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的库。而…

LeetCode【4. 寻找两个正序数组的中位数】

快乐安康 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 public double findMedianSortedArrays(int[] nums1, int[] nums2) {if (nums1.length &…

干净优雅的做iOS应用内全局交互屏蔽

本文字数:4930字 预计阅读时间:28分钟 01 交互屏蔽的需求 很多应用开发者都会遇到这样一个需求,当程序需要处理某个敏感的核心任务,或者执行某些动画时,需要杜绝一切外部干扰,优先保证任务的完成&#xff0…

EF Core 迁移失败、数据丢失 手动处理

一、环境 windows 10 Visual studio 2022 dotnet 6.0.404 Microsoft.EntityFrameworkCore.Tools 6.0.14 二、问题 有一记录房产交易数据的实体,已有生产数据,现需更改、添加字段,产生了迁移不成功和数据丢失的问题。 原实体定义 //唯一复合索…

数据结构与算法——11.递归

这篇文章我们来讲一个很常用的算法思想——递归 目录 1.递归的概述 2.用递归求阶乘 3.用递归反向打印字符串 4.用递归来求解二分查找 5.用递归解决冒泡排序 6.用递归解决插入排序 7.用递归解决斐波那契数列 8.用递归解决兔子问题 9.用递归解决青蛙爬楼梯问题 10.递归…

CSS - 鼠标移入整行高亮显示,适用于会员套餐各参数对比页面(display: table,div 转表格形式)

效果图 可根据基础示例和进阶示例&#xff0c;复制进行改造样式。 如下图所示&#xff0c;本文提供 2 个示例。 基础示例 找个 HTML 页面&#xff0c;一键复制运行。 <body><h1 style"text-align: center;">基础示例</h1><section class"…

软件设计模式系列之六——单例模式

1 模式的定义 单例模式&#xff08;Singleton Pattern&#xff09;是一种常见的创建型设计模式&#xff0c;其主要目的是确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。这意味着无论何时何地&#xff0c;只要需要该类的实例&#xff0c;都会返回同一个…

JAVA高级技术入门(单元测试,反射,注解,动态代理)

JAVA高级技术入门&#xff08;单元测试&#xff0c;反射&#xff0c;注解&#xff0c;动态代理&#xff09; 一、Junit单元测试二、反射1.认识反射&#xff0c;获取类概念&#xff1a;快速入门&#xff1a;获取Class对象的三种方式 2.1获取类的构造器2.2获取类的构造器的作用&a…

计算机系统概述之计算机的发展历程

计算机系统概述之计算机的发展历程 计算机的发展历程计算机系统硬件的发展微处理器的发展 软件的发展CAD/ CAM/CIMS的简单介绍 思维导图总结 计算机的发展历程 计算机系统 计算机系统由硬件和软件组成。 硬件&#xff1a;指的是计算机实体&#xff0c;如&#xff1a;主机&#…

【深度学习】 Python 和 NumPy 系列教程(廿四):Matplotlib详解:2、3d绘图类型(10)3D箱线图(3D Box Plot)

目录 一、前言 二、实验环境 三、Matplotlib详解 1、2d绘图类型 2、3d绘图类型 0. 设置中文字体 1. 3D线框图&#xff08;3D Line Plot&#xff09; 2. 3D散点图&#xff08;3D Scatter Plot&#xff09; 3. 3D条形图&#xff08;3D Bar Plot&#xff09; 4. 3D曲面图…

动态规划——01背包

背包问题经典资料背包九讲&#xff0c;可以上网查一下相关资料。 下面的资料来自代码随想录和自己的一些个人理解&#xff0c;如有需要可以跳转代码随想录进行学习&#xff1a;代码随想录 (programmercarl.com) 背包一共分为01背包&#xff0c;完全背包&#xff0c;多重背包&am…

leetcode:70. 爬楼梯

一、题目 函数原型&#xff1a;int climbStairs(int n) 二、思路 此题运用递归思想。当只有1个台阶&#xff0c;那么只有1种方法爬到楼顶——跨一个台阶&#xff1b;当有2个台阶时&#xff0c;有2种方法爬到楼顶——跨一个台阶跨两次或直接跨两个台阶。当有3个台阶或更多台阶时…

实现客户端pineline的思路

背景&#xff1a; redis集群不支持客户端的mget操作&#xff0c;但是业务上对这个redis集群的批量操作的需求一直都在&#xff0c;所以有各种客户端实现了各式各样的pineline实现,本文就记录下我们公司的实现方式 pineline实现思路 1.pineline要快 pineline之所以快是因为可…

深度学习训练过程可视化工具

1.深度学习网络结构画图工具 地址&#xff1a;https://cbovar.github.io/ConvNetDraw/ 2.caffe可视化工具 输入&#xff1a;caffe配置文件 输出&#xff1a;网络结构 地址&#xff1a;http://ethereon.github.io/netscope/#/editor 3.深度学习可视化工具Visual DL Visual D…

数据变换:数据挖掘的准备工作之一

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ &#x1f434;作者&#xff1a;秋无之地 &#x1f434;简介&#xff1a;CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作&#xff0c;主要擅长领域有&#xff1a;爬虫、后端、大数据…

【毕设选题】flink大数据淘宝用户行为数据实时分析与可视化

文章目录 0 前言1、环境准备1.1 flink 下载相关 jar 包1.2 生成 kafka 数据1.3 开发前的三个小 tip 2、flink-sql 客户端编写运行 sql2.1 创建 kafka 数据源表2.2 指标统计&#xff1a;每小时成交量2.2.1 创建 es 结果表&#xff0c; 存放每小时的成交量2.2.2 执行 sql &#x…

【python手写算法】numpy实现简易神经网络和反向传播算法【1】

import numpy as npdef dense(A,W):Znp.matmul(A,W)#矩阵乘法return 1/(1np.exp(-Z))if __name__ __main__:leanring_rate100Anp.array([[200.0,17.0]])# Wnp.array([[1,-3,5],# [-2,4,-6]])# bnp.array([[-1,1,2]])W1 np.array([[0., -10, 4],[-1,3,2]])W2np.ar…