01)java代码的组件
package com.example.mworld;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
public class mView extends View{
private final String TAG = "mView";
private Resources mResources;
private Paint mPaint;
private Context mContext;
private int mNormalColor;
private TextView mTextView;
public static int STATUS_PLAY = 0;
public static int STATUS_PAUSE = 1;
public static int STATUS_STOP = 2;
private Drawable mHourHigh;
private Drawable mHourLow;
private Drawable mMinuteHigh;
private Drawable mMinuteLow;
private Drawable mSecondHigh;
private Drawable mSecondLow;
private Drawable mDivider;
private int mChildrenGap;
private int mDividerWidth;
private int mNumberMinuteWidth;
private int mNumberMinuteHeight;
private int mNumberHourWidth;
private int mNumberHourHeight;
private int mNumberSecondWidth;
private int mNumberSecondHeight;
private int mWidth;
private int mHeight;
private int mDateHeight;
private int mDateMarginTop;
private int mDateWidth;
private int mDividerHeight;
private int mTimeHeight;
private String mDate;
private TypedArray mTimeDrawableArray;
private int mPlayResId;
private int mPauseResId;
private int mStopResId;
private int mHour = -1;
private int mMin = -1;
private int mSecond = -1;
private int mChooseColor;
public mView(Context context) {
super(context);
}
public mView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public mView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mContext = context;
mResources = mContext.getResources();
InitLayout( attrs, defStyleAttr);
}
private void InitLayout(AttributeSet attrs, int defStyleAttr) {
TypedArray a = mContext.obtainStyledAttributes(attrs,
R.styleable.DigitalClock, defStyleAttr, 0);
mChooseColor = mContext.getResources().getColor(R.color.edit_choose_color);
mTextView.setTextColor(mNormalColor);
mPlayResId = a.getResourceId(R.styleable.DigitalClock_time_start_res, 0);
mTimeDrawableArray = mResources.obtainTypedArray(mStopResId);
mDivider = mTimeDrawableArray.getDrawable(mTimeDrawableArray.length() - 1);
mChildrenGap = (int) a.getDimension(R.styleable.DigitalClock_children_gap, 0);
mMinuteHigh = mTimeDrawableArray.getDrawable(0);
mHourHigh = mTimeDrawableArray.getDrawable(0);
mMinuteLow = mTimeDrawableArray.getDrawable(0);
mHourLow = mTimeDrawableArray.getDrawable(0);
mSecondHigh = mTimeDrawableArray.getDrawable(0);
mSecondLow = mTimeDrawableArray.getDrawable(0);
int textColor = (int) a.getColor(R.styleable.DigitalClock_text_color, 0xffffffff);
mDateHeight = (int) a.getDimension(R.styleable.DigitalClock_date_height, 0);
mDateMarginTop = (int) a.getDimension(R.styleable.DigitalClock_date_margin_top, 0);
mDateWidth = (int) a.getDimension(R.styleable.DigitalClock_date_width, 0);
mPaint = new Paint();
mPaint.setColor(textColor);
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
Log.i(TAG, "onMeasure- mWidth" + mWidth + "; mHeight: " + mHeight);
setMeasuredDimension(mWidth, mHeight);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
int left = 0;
mHourHigh.setBounds(left, 0, left + mNumberHourWidth, mNumberHourHeight);
mHourHigh.draw(canvas);
left = left + mNumberHourWidth + mChildrenGap;
mHourLow.setBounds(left, 0, left + mNumberHourWidth, mNumberHourHeight);
mHourLow.draw(canvas);
left = left + mNumberHourWidth + mChildrenGap;
mDivider.setBounds(left, 0, left + mDividerWidth, mDividerHeight);
mDivider.draw(canvas);
left = left + mDividerWidth + mChildrenGap;
mMinuteHigh.setBounds(left, 0, left + mNumberMinuteWidth, mNumberMinuteHeight);
mMinuteHigh.draw(canvas);
left = left + mNumberMinuteWidth + mChildrenGap;
mMinuteLow.setBounds(left, 0, left + mNumberMinuteWidth, mNumberMinuteHeight);
mMinuteLow.draw(canvas);
left = left + mNumberHourWidth + mChildrenGap;
mDivider.setBounds(left, 0, left + mDividerWidth, mDividerHeight);
mDivider.draw(canvas);
left = left + mDividerWidth + mChildrenGap;
mSecondHigh.setBounds(left, 0, left + mNumberSecondWidth, mNumberSecondHeight);
mSecondHigh.draw(canvas);
left = left + mNumberMinuteWidth + mChildrenGap;
mSecondLow.setBounds(left, 0, left + mNumberSecondWidth, mNumberSecondHeight);
mSecondLow.draw(canvas);
if (mDate != null && mDate.length() > 0) {
left = left + mNumberMinuteWidth;
mPaint.setTextSize(mDateHeight);
canvas.drawText(mDate, left - mDateWidth, mTimeHeight
+ mDateMarginTop + mDateHeight - 5, mPaint);
}
}
public void setTime(long time) {
if ( time < 0) {
return;
}
mHour = (int)(time/3600);
mMin = (int)(time/60%60);
mSecond =(int)(time%60);
mHourHigh = mTimeDrawableArray.getDrawable(mHour / 10);
mHourLow = mTimeDrawableArray.getDrawable(mHour % 10);
mMinuteHigh = mTimeDrawableArray.getDrawable(mMin / 10);
mMinuteLow = mTimeDrawableArray.getDrawable(mMin % 10);
mSecondHigh = mTimeDrawableArray.getDrawable(mSecond / 10);
mSecondLow = mTimeDrawableArray.getDrawable(mSecond % 10);
invalidate();
}
public void setTimeColorStatus (int status) {
switch (status) {
case 0 :
mTimeDrawableArray = mResources.obtainTypedArray(mPlayResId);
mDivider = mTimeDrawableArray.getDrawable(mTimeDrawableArray.length() - 1);
break;
case 1 :
mTimeDrawableArray = mResources.obtainTypedArray(mPauseResId);
mDivider = mTimeDrawableArray.getDrawable(mTimeDrawableArray.length() - 1);
break;
case 2 :
mTimeDrawableArray = mResources.obtainTypedArray(mStopResId);
mDivider = mTimeDrawableArray.getDrawable(mTimeDrawableArray.length() - 1);
break;
default :
break;
}
invalidate();
}
}
02)array.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="recoder_time_start">
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
<item>@drawable/recoder_number_play_0</item>
</array>
</resources>
03)自定义style,提供接口,供使用者修改,res/values/attr.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DigitalClock">
<attr name="time_start_res" format="reference" />
<attr name="time_pause_res" format="reference" />
<attr name="time_stop_res" format="reference" />
<attr name="children_gap" format="dimension" />
<attr name="text_color" format="color" />
<attr name="date_format" format="reference" />
<attr name="date_height" format="dimension" />
<attr name="date_margin_top" format="dimension" />
<attr name="date_width" format="dimension" />
<attr name="ampm_height" format="dimension" />
<attr name="ampm_width" format="dimension" />
<attr name="showdivider" format="reference"/>
<attr name="ampm_gravity">
<flag name="top" value="0x01" />
<flag name="bottom" value="0x02" />
<flag name="left" value="0x04" />
<flag name="right" value="0x08" />
</attr>
</declare-styleable>
</resources>
04)如,在布局中使用该组件时:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:mandroid="http://schemas.android.com/apk/res-auto"
.../>
<!--声明 mandroid ,供下面使用, 类似于android-->
<com.example.mworld.mView
android:id="@+id/digital_clock"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_marginTop="@dimen/digital_marginTop"
mandroid:children_gap ="@dimen/digital_gap"
mandroid:time_start_res="@array/recoder_time_start"
/>