在Api Demo里面有一个叫ColorPickerDialog的对话框,该对话框扩展了Dialog 的功能,使其具备颜色选择器的功能。具体可以参考Api Demo源代码,路径为:android-sdk-windows\samples\android-7\ApiDemos\src\com\example\android\apis\graphics\ColorPickerDialog.java 本功能是基于上述的颜色选择器对话框进行扩展,模仿PreferceActivity 组件的实现方式,新建一个名为ColorPickerPreference 的类使其继承自DialogPreference 并实现其内部功能菜单,如图: 在Api Demo里面的颜色选择器是不具备有黑色和白色的选择的,这里我们虽然使用api Demo 里面的颜色选择器但其内部我们稍稍改造了一下。使其支持黑色和白色的选择,如上图中间的一条颜色条,头部和尾部分别代表黑色和白色。 为了显示的友好性,如果用户选择了颜色应该应该会有一个内容窗口或者一个文本对用户的选择做出相应的预览效果,。我们这里使用了一个TextView 做为颜色的预览效果,我们知道,Preference 的summary 只支持字符串的操作,类似下面的图: 如上图,只支持类型类型为CharSequence和字符所在的资源ID位置,那么我们这里如何使其支持颜色的显示和动态更换颜色呢? 这一切都在神奇的回调函数,onCreateView 里面这个方法先于 onBindView 执行,在里面初始化视图并且返回视图。具体处理见下面代码: @Override
protected ViewonCreateView(ViewGroupparent){
// TODOAuto-generatedmethodstub

Viewview
= LayoutInflater.from(getContext()).inflate(
R.layout.preference,
null );

TextViewtitle
= (TextView)view.findViewById(R.id.title);
title.setText(getTitle());

summary
= (TextView)view.findViewById(R.id.summary);
summary.setText(getSummary());
SharedPreferencesprefs
= getPreferenceManager().getSharedPreferences();
mInitialColor
= prefs.getInt(getKey(),Color.LTGRAY);
summary.setTextColor(mInitialColor);
return view;
}
上面代码,我们通过LayoutInflater 函数引入一个外部的布局文件,然后设置其title 和summary 并初始其颜色,通过SharedPreferences类调用保存后的颜色值,布局文件如下: <? xmlversion="1.0"encoding="UTF-8" ?>
< LinearLayout android:id ="@+id/LinearLayout01"
android:layout_width
="fill_parent" android:layout_height ="fill_parent"
xmlns:android
="http://schemas.android.com/apk/res/android" >


< RelativeLayout android:layout_width ="fill_parent"
android:gravity
="center" android:layout_height ="fill_parent" >
< TextView android:id ="@+id/title" android:layout_width ="wrap_content"
android:layout_marginLeft
="15dp" android:textAppearance ="?android:attr/textAppearanceLarge"
android:layout_height
="wrap_content" ></ TextView >
< ImageView android:src ="@drawable/ic_dialog_menu_generic"
android:layout_marginRight
="15dp" android:layout_alignParentRight ="true"
android:layout_width
="wrap_content" android:layout_height ="wrap_content" ></ ImageView >
< TextView android:id ="@+id/summary" android:layout_below ="@id/title"
android:layout_marginLeft
="15dp" android:layout_width ="wrap_content"
android:layout_height
="wrap_content" ></ TextView >

</ RelativeLayout >
</ LinearLayout >
实始化对话框的回调函数里面我们为其添加一个ColorPickerDialog 本身的颜色改变的事件监听并为其初始化颜色值,代码如下: @Override
protected void onPrepareDialogBuilder(Builderbuilder){
super.onPrepareDialogBuilder(builder);

OnColorChangedListenerl
= new OnColorChangedListener(){
public void colorChanged( int color){
mCurrentColor
= color;
onDialogClosed(
true );
getDialog().dismiss();
}
};

LinearLayoutlayout
= new LinearLayout(getContext());
layout.setPadding(
20 , 20 , 20 , 20 );
layout.setOrientation(LinearLayout.VERTICAL);
mCPView
= new ColorPickerView(getContext(),l,mInitialColor);

LinearLayout.LayoutParamsparams1
= new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params1.gravity
= Gravity.CENTER;
mCPView.setLayoutParams(params1);
layout.addView(
this .mCPView);
layout.setId(android.R.id.widget_frame);
builder.setView(layout);
}
当对话框关闭时,即选择完颜色后,我们就要马上回去更新文本的颜色和将颜色值保存到键值里面,代码如下: @Override
protected void onDialogClosed(booleanpositiveResult){
if (positiveResult){
mCurrentColor
= mCPView.getColor();
summary.setTextColor(mCurrentColor);
SharedPreferences.Editoreditor
= getEditor();
editor.putInt(getKey(),mCurrentColor);
editor.commit();
callChangeListener(
new Integer(mCurrentColor));
}
}
通过重写,onDialogClosed 回调函数,到这一步整个的封装就己结束,在XML可以通过如下使用: < com.terry.util.ColorPickerPreference
android:key ="colorpiker" android:persistent ="true" android:summary ="@string/app_name"
android:dialogTitle
="@string/str_fontscolor" android:title ="@string/str_fontscolor" /> Tip:自己封装控件不论是自定义控件也好,preference 也好在XML里面都是无法智能提示的,只要自己把握好输入的属性准确无误就行。 完整代码如下: packagecom.terry.util;

importandroid.app.AlertDialog.Builder;
importandroid.content.Context;
importandroid.content.SharedPreferences;
importandroid.graphics.Canvas;
importandroid.graphics.Color;
importandroid.graphics.LinearGradient;
importandroid.graphics.Paint;
importandroid.graphics.RectF;
importandroid.graphics.Shader;
importandroid.graphics.SweepGradient;
importandroid.preference.DialogPreference;
importandroid.util.AttributeSet;
importandroid.view.Gravity;
importandroid.view.LayoutInflater;
importandroid.view.MotionEvent;
importandroid.view.View;
importandroid.view.ViewGroup;
importandroid.widget.LinearLayout;
importandroid.widget.TextView;

importcom.terry.eBook.R;

public class ColorPickerPreferenceextendsDialogPreference{
private int mInitialColor;
private int mCurrentColor;
private ColorPickerViewmCPView;
private TextViewsummary;

private static class ColorPickerViewextendsView{
private PaintmPaint;
private PaintmCenterPaint;
private PaintmHSVPaint;
private final int []mColors;
private int []mHSVColors;
private booleanmRedrawHSV;
private OnColorChangedListenermListener;

ColorPickerView(Contextc,OnColorChangedListenerl,
int color){
super(c);
mListener
= l;
mColors
= new int []{ 0xFFFF0000 , 0xFFFF00FF , 0xFF0000FF ,
0xFF00FFFF , 0xFF00FF00 , 0xFFFFFF00 , 0xFFFF0000 };
Shaders
= new SweepGradient( 0 , 0 ,mColors, null );

mPaint
= new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint.setShader(s);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeWidth(
55 );

mCenterPaint
= new Paint(Paint.ANTI_ALIAS_FLAG);
mCenterPaint.setColor(color);
mCenterPaint.setStrokeWidth(
5 );

mHSVColors
= new int []{ 0xFF000000 ,color, 0xFFFFFFFF };

mHSVPaint
= new Paint(Paint.ANTI_ALIAS_FLAG);
mHSVPaint.setStrokeWidth(
10 );

mRedrawHSV
= true ;

}

private booleanmTrackingCenter;
private booleanmHighlightCenter;

public int getColor(){
return mCenterPaint.getColor();
}

@Override
protected void onDraw(Canvascanvas){
float r = CENTER_X - mPaint.getStrokeWidth() * 0.5f ;

canvas.translate(CENTER_X,CENTER_X);
int c = mCenterPaint.getColor();

if (mRedrawHSV){
mHSVColors[
1 ] = c;
mHSVPaint.setShader(
new LinearGradient( - 100 , 0 , 100 , 0 ,
mHSVColors,
null ,Shader.TileMode.CLAMP));
}

canvas.drawOval(
new RectF( - r, - r,r,r),mPaint);
canvas.drawCircle(
0 , 0 ,CENTER_RADIUS,mCenterPaint);
canvas.drawRect(
new RectF( - 100 , 130 , 100 , 110 ),mHSVPaint);

if (mTrackingCenter){
mCenterPaint.setStyle(Paint.Style.STROKE);

if (mHighlightCenter){
mCenterPaint.setAlpha(
0xFF );
}
else {
mCenterPaint.setAlpha(
0x80 );
}
canvas.drawCircle(
0 , 0 ,CENTER_RADIUS
+ mCenterPaint.getStrokeWidth(),mCenterPaint);

mCenterPaint.setStyle(Paint.Style.FILL);
mCenterPaint.setColor(c);
}

mRedrawHSV
= true ;
}

@Override
protected void onMeasure( int widthMeasureSpec, int heightMeasureSpec){
setMeasuredDimension(CENTER_X
* 2 ,(CENTER_Y + 25 ) * 2 );
}

private static final int CENTER_X = 100 ;
private static final int CENTER_Y = 100 ;
private static final int CENTER_RADIUS = 30 ;

private int ave( int s, int d, float p){
return s + java.lang.Math.round(p * (d - s));
}

private int interpColor( int colors[], float unit){
if (unit <= 0 ){
return colors[ 0 ];
}
if (unit >= 1 ){
return colors[colors.length - 1 ];
}

float p = unit * (colors.length - 1 );
int i = ( int )p;
p
-= i;

// nowpisjustthefractionalpart[0...1)andiistheindex
int c0 = colors[i];
int c1 = colors[i + 1 ];
int a = ave(Color.alpha(c0),Color.alpha(c1),p);
int r = ave(Color.red(c0),Color.red(c1),p);
int g = ave(Color.green(c0),Color.green(c1),p);
int b = ave(Color.blue(c0),Color.blue(c1),p);

return Color.argb(a,r,g,b);
}

private static final float PI = 3.1415926f ;

@Override
public booleanonTouchEvent(MotionEvent event ){
float x = event .getX() - CENTER_X;
float y = event .getY() - CENTER_Y;
booleaninCenter
= java.lang.Math.sqrt(x * x + y * y) <= CENTER_RADIUS;

switch ( event .getAction()){
case MotionEvent.ACTION_DOWN:
mTrackingCenter
= inCenter;
if (inCenter){
mHighlightCenter
= true ;
invalidate();
break ;
}
case MotionEvent.ACTION_MOVE:
if (mTrackingCenter){
if (mHighlightCenter != inCenter){
mHighlightCenter
= inCenter;
invalidate();
}
}
else if ((x >= - 100 & x <= 100 ) && (y <= 130 && y >= 110 )) // see
// if
// we're
// in
// the
// hsv
// slider
{
int a,r,g,b,c0,c1;
float p;

// setthecenterpainttothiscolor
if (x < 0 ){
c0
= mHSVColors[ 0 ];
c1
= mHSVColors[ 1 ];
p
= (x + 100 ) / 100 ;
}
else {
c0
= mHSVColors[ 1 ];
c1
= mHSVColors[ 2 ];
p
= x / 100 ;
}

a
= ave(Color.alpha(c0),Color.alpha(c1),p);
r
= ave(Color.red(c0),Color.red(c1),p);
g
= ave(Color.green(c0),Color.green(c1),p);
b
= ave(Color.blue(c0),Color.blue(c1),p);

mCenterPaint.setColor(Color.argb(a,r,g,b));

mRedrawHSV
= false ;
invalidate();
}
else {
float angle = ( float )java.lang.Math.atan2(y,x);
// needtoturnangle[-PI...PI]intounit[0....1]
float unit = angle / ( 2 * PI);
if (unit < 0 ){
unit
+= 1 ;
}
mCenterPaint.setColor(interpColor(mColors,unit));
invalidate();
}
break ;
case MotionEvent.ACTION_UP:
if (mTrackingCenter){
if (inCenter){
mListener.colorChanged(mCenterPaint.getColor());
}
mTrackingCenter
= false ; // sowedraww/ohalo
invalidate();
}
break ;
}
return true ;
}
}

public interface OnColorChangedListener{
void colorChanged( int color);
}

public ColorPickerPreference(Contextcontex){
this (contex, null );
}

public ColorPickerPreference(Contextcontext,AttributeSetattrs){
super(context,attrs);

}

public ColorPickerPreference(Contextcontext,AttributeSetattrs,
int defStyle){
super(context,attrs,defStyle);

}

@Override
protected void onDialogClosed(booleanpositiveResult){
if (positiveResult){
mCurrentColor
= mCPView.getColor();
summary.setTextColor(mCurrentColor);
SharedPreferences.Editoreditor
= getEditor();
editor.putInt(getKey(),mCurrentColor);
editor.commit();
callChangeListener(
new Integer(mCurrentColor));
}
}

@Override
protected ViewonCreateView(ViewGroupparent){
// TODOAuto-generatedmethodstub

Viewview
= LayoutInflater.from(getContext()).inflate(
R.layout.preference,
null );

TextViewtitle
= (TextView)view.findViewById(R.id.title);
title.setText(getTitle());

summary
= (TextView)view.findViewById(R.id.summary);
summary.setText(getSummary());
SharedPreferencesprefs
= getPreferenceManager().getSharedPreferences();
mInitialColor
= prefs.getInt(getKey(),Color.LTGRAY);
summary.setTextColor(mInitialColor);
return view;
}

@Override
protected void onPrepareDialogBuilder(Builderbuilder){
super.onPrepareDialogBuilder(builder);

OnColorChangedListenerl
= new OnColorChangedListener(){
public void colorChanged( int color){
mCurrentColor
= color;
onDialogClosed(
true );
getDialog().dismiss();
}
};

LinearLayoutlayout
= new LinearLayout(getContext());
layout.setPadding(
20 , 20 , 20 , 20 );
layout.setOrientation(LinearLayout.VERTICAL);
mCPView
= new ColorPickerView(getContext(),l,mInitialColor);

LinearLayout.LayoutParamsparams1
= new LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
params1.gravity
= Gravity.CENTER;
mCPView.setLayoutParams(params1);
layout.addView(
this .mCPView);
layout.setId(android.R.id.widget_frame);
builder.setView(layout);
}
}
完。

更多相关文章

  1. Android程序反编译
  2. Android(安卓)WindowManager悬浮窗
  3. Android培训班(85)升级到4.0版本
  4. Android仿微信发送语音消息动态提示,支持上滑取消发送
  5. 魅族MX2 Smartbar的支持
  6. Android(安卓)自定义弹出对话框实例
  7. Android开发指南(40) —— Adding Recent Query Suggestions
  8. [置顶] android jni 调用
  9. undefined reference to `android::Mutex::lock()'

随机推荐

  1. android CTS test
  2. Android LK Bootlaoder启动概览
  3. Android跳转WIFI界面的四种方式
  4. 编译android 64位openssl库
  5. Android获取移动设备的IP地址
  6. 解决Conversion to Dalvik format failed
  7. android 开源自组织网络开源包
  8. 今天玩玩Android -==-- 了解一下
  9. 如何在Android单元测试中调试async-http
  10. Android小代码——设置全屏