Android實(shí)現(xiàn)顏色選取圓盤
本文實(shí)例為大家分享了Android實(shí)現(xiàn)顏色選取圓盤的具體代碼,供大家參考,具體內(nèi)容如下
先看效果圖
xml布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:id="@+id/tv_rgb"/> <RelativeLayout android:id="@+id/relativeLayout1" android:layout_height="fill_parent" android:layout_width="fill_parent"> <com.myview.ColorPickerView android:id="@+id/cpv" android:layout_width="230dp" android:layout_height="230dp" android:layout_centerInParent="true" android:scaleType="center" android:src="@drawable/rgb" /> </RelativeLayout> </LinearLayout>
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;// 點(diǎn)擊位置坐標(biāo) 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;// 整個(gè)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;// 整個(gè)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點(diǎn)和圓點(diǎn) 的三角形寬 float w = y - viewRadius;// 取xy點(diǎn)和圓點(diǎn) 的三角形長(zhǎng) float h2 = h * h; float w2 = w * w; float distance = (float) Math.sqrt((h2 + w2)); // 勾股定理求 斜邊距離 if (distance > radius) { // 如果斜邊距離大于半徑,則取點(diǎn)和圓最近的一個(gè)點(diǎn)為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; // 內(nèi)部接口 回調(diào)顏色 rgb值 public interface OnColorChangedListener { // 手指抬起,確定顏色回調(diào) void onColorChanged(int r, int g, int b); // 移動(dòng)時(shí)顏色回調(diào) 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() { /** * 手指抬起,選定顏色時(shí) */ @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(); } /** * 顏色移動(dòng)的時(shí)候 */ @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); } }); } }
詳細(xì)項(xiàng)目代碼:
源碼下載:Android實(shí)現(xiàn)顏色選取圓盤
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Android星級(jí)評(píng)分條控件RatingBar使用詳解
這篇文章主要為大家詳細(xì)介紹了Android星級(jí)評(píng)分條控件RatingBar的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-06-06Android源碼學(xué)習(xí)之單例模式應(yīng)用及優(yōu)點(diǎn)介紹
動(dòng)態(tài)確保某一個(gè)類只有一個(gè)實(shí)例,而且自行實(shí)例化并向整個(gè)系統(tǒng)提供這個(gè)實(shí)例這就是Android單例模式應(yīng)用,接下來詳細(xì)介紹,有需求的朋友可以參考下2013-01-01Android實(shí)現(xiàn)簡(jiǎn)易登陸注冊(cè)邏輯的實(shí)例代碼
在android的應(yīng)用中越來越多的包含了網(wǎng)絡(luò)互動(dòng)功能,這就帶來了注冊(cè),登陸賬號(hào)功能,這篇文章主要給大家介紹了關(guān)于Android實(shí)現(xiàn)簡(jiǎn)易登陸注冊(cè)邏輯的相關(guān)資料,需要的朋友可以參考下2021-06-06Android開發(fā)ThreadPoolExecutor與自定義線程池詳解
這篇文章主要為大家介紹了Android開發(fā)ThreadPoolExecutor與自定義線程池詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Android使用OkHttp請(qǐng)求自簽名的https網(wǎng)站的示例
本篇文章主要介紹了Android使用OkHttp請(qǐng)求自簽名的https網(wǎng)站的示例,非常具有實(shí)用價(jià)值,需要的朋友可以參考下、2017-09-09Android IPC機(jī)制ACtivity綁定Service通信代碼實(shí)例
這篇文章主要介紹了Android IPC機(jī)制ACtivity綁定Service通信代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09Android實(shí)現(xiàn)客戶端語(yǔ)音動(dòng)彈界面實(shí)例代碼
這篇文章主要介紹了Android實(shí)現(xiàn)客戶端語(yǔ)音動(dòng)彈界面實(shí)例代碼,文章只給大家介紹了控件布局的方法,需要的朋友可以參考下2017-11-11android實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳功能
這篇文章主要為大家詳細(xì)介紹了android實(shí)現(xiàn)多線程斷點(diǎn)續(xù)傳功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-11-11