热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android实现颜色选取圆盘

这篇文章主要为大家详细介绍了Android实现颜色选取圆盘,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了Android实现颜色选取圆盘的具体代码,供大家参考,具体内容如下

先看效果图

xml布局

<&#63;xml version="1.0" encoding="utf-8"&#63;> 
 
 
 
 
  
 
 
 

ColorPickerView颜色选取圆盘

package com.myview; 
 
import android.annotation.SuppressLint; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.graphics.Canvas; 
import android.graphics.Color; 
import android.graphics.Paint; 
import android.graphics.PointF; 
import android.graphics.drawable.BitmapDrawable; 
import android.util.AttributeSet; 
import android.view.MotionEvent; 
import android.widget.ImageView; 
 
public class ColorPickerView extends ImageView { 
 Context context; 
 private Bitmap iconBitMap; 
 float iconRadius;// 吸管圆的半径 
 float iconCenterX; 
 float iconCenterY; 
 PointF iconPoint;// 点击位置坐标 
 
 public ColorPickerView(Context context) { 
  this(context, null); 
 } 
 
 public ColorPickerView(Context context, AttributeSet attrs, int defStyle) { 
  super(context, attrs, defStyle); 
  this.cOntext= context; 
  init(); 
 } 
 
 public ColorPickerView(Context context, AttributeSet attrs) { 
  this(context, attrs, 0); 
  init(); 
 } 
 
 Paint mBitmapPaint; 
 Bitmap imageBitmap; 
 float viewRadius;// 整个view半径 
 float radius;// 图片半径 
 
 /** 
  * 初始化画笔 
  */ 
 private void init() { 
  icOnBitMap= BitmapFactory.decodeResource(context.getResources(), 
    R.drawable.pickup);// 吸管的图片 
  icOnRadius= iconBitMap.getWidth() / 2;// 吸管的图片一半 
 
  mBitmapPaint = new Paint(); 
  icOnPoint= new PointF(); 
 
  imageBitmap = ((BitmapDrawable) getDrawable()).getBitmap(); 
  radius = imageBitmap.getHeight() / 2;// 图片半径 
 
  // // 初始化 
  iconPoint.x = radius; 
  iconPoint.y = radius; 
 
 } 
 
 @Override 
 protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
  // TODO Auto-generated method stub 
  super.onMeasure(widthMeasureSpec, heightMeasureSpec); 
 } 
 
 Canvas canvas; 
 
 @Override 
 protected void onDraw(Canvas canvas) { 
  // TODO Auto-generated method stub 
  super.onDraw(canvas); 
  this.canvas = canvas; 
 
  viewRadius = this.getWidth() / 2;// 整个view半径 
 
  canvas.drawBitmap(iconBitMap, iconPoint.x - iconRadius, iconPoint.y 
    - iconRadius, mBitmapPaint); 
 } 
 
 @SuppressLint("ClickableViewAccessibility") 
 @Override 
 public boolean onTouchEvent(MotionEvent event) { 
  float x = event.getX(); 
  float y = event.getY(); 
  int pixel; 
  int r; 
  int g; 
  int b; 
  switch (event.getAction()) { 
  case MotionEvent.ACTION_MOVE: 
   proofLeft(x, y); 
   pixel = getImagePixel(iconPoint.x, iconPoint.y); 
   r = Color.red(pixel); 
   g = Color.green(pixel); 
   b = Color.blue(pixel); 
   if (mChangedListener != null) { 
    mChangedListener.onMoveColor(r, g, b); 
   } 
   if (isMove) { 
    isMove = !isMove; 
    invalidate(); 
   } 
   break; 
  case MotionEvent.ACTION_UP: 
   pixel = getImagePixel(iconPoint.x, iconPoint.y); 
   r = Color.red(pixel); 
   g = Color.green(pixel); 
   b = Color.blue(pixel); 
   if (mChangedListener != null) { 
    mChangedListener.onColorChanged(r, g, b); 
   } 
   break; 
 
  default: 
   break; 
  } 
  return true; 
 } 
 
 public int getImagePixel(float x, float y) { 
 
  Bitmap bitmap = imageBitmap; 
  // 为了防止越界 
  int intX = (int) x; 
  int intY = (int) y; 
  if (intX <0) 
   intX = 0; 
  if (intY <0) 
   intY = 0; 
  if (intX >= bitmap.getWidth()) { 
   intX = bitmap.getWidth() - 1; 
  } 
  if (intY >= bitmap.getHeight()) { 
   intY = bitmap.getHeight() - 1; 
  } 
  int pixel = bitmap.getPixel(intX, intY); 
  return pixel; 
 
 } 
 
 /** 
  * R = sqrt(x * x + y * y) 
  * point.x = x * r / R + r 
  * point.y = y * r / R + r 
  */ 
 private void proofLeft(float x, float y) { 
 
  float h = x - viewRadius; // 取xy点和圆点 的三角形宽 
  float w = y - viewRadius;// 取xy点和圆点 的三角形长 
  float h2 = h * h; 
  float w2 = w * w; 
  float distance = (float) Math.sqrt((h2 + w2)); // 勾股定理求 斜边距离 
  if (distance > radius) { // 如果斜边距离大于半径,则取点和圆最近的一个点为x,y 
   float maxX = x - viewRadius; 
   float maxY = y - viewRadius; 
   x = ((radius * maxX) / distance) + viewRadius; // 通过三角形一边平行原理求出x,y 
   y = ((radius * maxY) / distance) + viewRadius; 
  } 
  iconPoint.x = x; 
  iconPoint.y = y; 
 
  isMove = true; 
 } 
 
 boolean isMove; 
 
 public void setOnColorChangedListenner(OnColorChangedListener l) { 
  this.mChangedListener = l; 
 } 
 
 private OnColorChangedListener mChangedListener; 
 
 // 内部接口 回调颜色 rgb值 
 public interface OnColorChangedListener { 
  // 手指抬起,确定颜色回调 
  void onColorChanged(int r, int g, int b); 
 
  // 移动时颜色回调 
  void onMoveColor(int r, int g, int b); 
 } 
} 

MyViewActivity主界面

package com.myview; 
 
import com.myview.ColorPickerView.OnColorChangedListener; 
 
import android.app.Activity; 
import android.os.Bundle; 
import android.widget.TextView; 
import android.widget.Toast; 
 
public class MyViewActivity extends Activity { 
  
 TextView tv_rgb; 
  
 /** Called when the activity is first created. */ 
 @Override 
 public void onCreate(Bundle savedInstanceState) { 
  super.onCreate(savedInstanceState); 
  setContentView(R.layout.main); 
   
  tv_rgb=(TextView)this.findViewById(R.id.tv_rgb); 
   
  ColorPickerView cpv=(ColorPickerView)this.findViewById(R.id.cpv); 
  cpv.setOnColorChangedListenner(new OnColorChangedListener() { 
   /** 
    * 手指抬起,选定颜色时 
    */ 
   @Override 
   public void onColorChanged(int r, int g, int b) { 
    if(r==0 && g==0 && b==0){ 
     return; 
    } 
    Toast.makeText(MyViewActivity.this, "选取 RGB:"+r+","+g+","+b, Toast.LENGTH_SHORT).show(); 
   } 
 
   /** 
    * 颜色移动的时候 
    */ 
   @Override 
   public void onMoveColor(int r, int g, int b) { 
    if(r==0 && g==0 && b==0){ 
     return; 
    } 
    tv_rgb.setText("RGB:"+r+","+g+","+b); 
   } 
  }); 
 } 
} 

详细项目代码:

源码下载:Android实现颜色选取圆盘

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 本文探讨了如何有效地构建和优化微信公众平台账号,涵盖了用户信息管理、内容创作与发布、互动策略及数据分析等方面。通过合理设置用户信息字段,如用户名、昵称、密码、真实姓名和性别等,确保账号的安全性和用户体验。同时,文章还介绍了如何利用微信公众平台的各项功能,提升用户参与度和品牌影响力。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 本文探讨了Android系统中支持的图像格式及其在不同版本中的兼容性问题,重点涵盖了存储、HTTP传输、相机功能以及SparseArray的应用。文章详细分析了从Android 10 (API 29) 到Android 11 的存储规范变化,并讨论了这些变化对图像处理的影响。此外,还介绍了如何通过系统升级和代码优化来解决版本兼容性问题,以确保应用程序在不同Android版本中稳定运行。 ... [详细]
  • 深入解析InnoDB中的多版本并发控制机制
    多版本并发控制(MVCC)是InnoDB存储引擎中的一项关键技术,通过维护数据在不同时间点的多个版本,确保了事务的隔离性和一致性。每个读取操作都能获得一个与事务启动时一致的数据视图,从而提高了并发性能并减少了锁竞争。此外,MVCC还支持多种隔离级别,如可重复读和读已提交,进一步增强了系统的灵活性和可靠性。 ... [详细]
  • 如何高效利用Hackbar插件提升网页调试效率
    通过合理利用Hackbar插件,可以显著提升网页调试的效率。本文介绍了如何获取并使用未包含收费功能的2.1.3版本,以确保在不升级到最新2.2.2版本的情况下,依然能够高效进行网页调试。此外,文章还提供了详细的使用技巧和常见问题解决方案,帮助开发者更好地掌握这一工具。 ... [详细]
  • 您是否了解:火狐浏览器会收集用户数据?
    您是否知道:火狐浏览器会收集用户数据?尽管Firefox浏览器的地理位置服务在浏览器关闭后仍会在后台运行,这引发了对用户隐私的担忧。最近,关于浏览器插件的争议进一步加剧了这种不安,因为这些插件原本旨在保护隐私,却反而泄露了用户信息。 ... [详细]
  • 本文详细解析了微信服务端示例类的功能与应用。其中,`ClientResponseHandler` 类主要用于处理微信支付所需的响应数据,而 `TenpayHttpClient` 则是对 HTTP 请求(包括 GET 和 POST 方法)进行了封装,以便在内部调用时更加便捷和高效。这些工具类在实际开发中起到了关键作用,开发者无需深入了解其底层实现细节,即可轻松集成微信支付功能。 ... [详细]
  • 深入解析:React与Webpack配置进阶指南(第二部分)
    在本篇进阶指南的第二部分中,我们将继续探讨 React 与 Webpack 的高级配置技巧。通过实际案例,我们将展示如何使用 React 和 Webpack 构建一个简单的 Todo 应用程序,具体包括 `TodoApp.js` 文件中的代码实现,如导入 React 和自定义组件 `TodoList`。此外,我们还将深入讲解 Webpack 配置文件的优化方法,以提升开发效率和应用性能。 ... [详细]
  • 本文详细介绍了如何安全地手动卸载Exchange Server 2003,以确保系统的稳定性和数据的完整性。根据微软官方支持文档(https://support.microsoft.com/kb833396/zh-cn),在进行卸载操作前,需要特别注意备份重要数据,并遵循一系列严格的步骤,以避免对现有网络环境造成不利影响。此外,文章还提供了详细的故障排除指南,帮助管理员在遇到问题时能够迅速解决,确保整个卸载过程顺利进行。 ... [详细]
  • 从文本中全面提取所有URL链接
    本文探讨了一种高效的方法,用于从大量文本数据中全面提取所有URL链接。通过使用正则表达式和Python编程语言,该方法能够准确识别并提取出各种格式的URL,包括HTTP、HTTPS等常见协议。实验结果表明,该方法在处理大规模文本数据时具有较高的准确率和效率。 ... [详细]
  • 润乾报表JNDI配置异常分析与解决方法
    在使用润乾报表时,通过JNDI连接数据源是常见的配置方式。本文详细分析了JNDI配置异常的原因,并提供了具体的解决方法。重点讨论了JNDI名称在三个关键位置的配置:1. Tomcat或应用服务器的数据源配置(以Tomcat为例);2. 润乾报表中的数据源配置;3. 应用程序代码中的JNDI名称引用。通过这些步骤,可以有效解决JNDI配置异常问题,确保报表系统的稳定运行。 ... [详细]
  • Python 实战:异步爬虫(协程技术)与分布式爬虫(多进程应用)深入解析
    本文将深入探讨 Python 异步爬虫和分布式爬虫的技术细节,重点介绍协程技术和多进程应用在爬虫开发中的实际应用。通过对比多进程和协程的工作原理,帮助读者理解两者在性能和资源利用上的差异,从而在实际项目中做出更合适的选择。文章还将结合具体案例,展示如何高效地实现异步和分布式爬虫,以提升数据抓取的效率和稳定性。 ... [详细]
  • 本文深入解析了Spring Cloud路由网关Zuul的核心功能及其典型应用场景。通过对方志朋老师教材的学习和实践,详细探讨了Zuul在微服务架构中的重要作用,包括请求路由、过滤器链管理以及服务动态扩展等关键特性。同时,结合实际案例,展示了Zuul在高并发和复杂业务场景下的应用优势,为读者提供了全面的技术参考。 ... [详细]
  • 面向切面编程(AOP)是Spring框架的两大核心概念之一,另一个核心概念是控制反转(IoC)。AOP通过在应用程序中分离横切关注点,如日志记录、事务管理和安全性,从而提高代码的模块化和可维护性。本文将深入探讨AOP的核心概念和术语,帮助读者更好地理解和应用这一重要技术。 ... [详细]
  • 虚拟网络连接配置指南旨在详细阐述如何在两台区域边界路由器(ABR)之间,通过一个非骨干区域(即传输区域)建立一条逻辑连接通道。该指南提供了具体的配置步骤和最佳实践,帮助网络管理员高效地实现跨区域的虚拟连接,确保网络的稳定性和可靠性。 ... [详细]
author-avatar
星宿
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有