首先建立一个属性文件,声明了一个自定义属性集合,在这个集合中你可以添加许多自己需要的属性,其格式类型是name = 属性名 format = 属性值的类型
<?xml version="1.0" encoding="utf-8"?> <resources> <declare-styleable name = "circleview"> <attr name = "circle_color" format = "color"/> </declare-styleable> </resources>然后是在View的构造方法中解析自定义的属性值并做处理
public CircleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub //加载自定义属性集合circleview TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.circleview); //从集合中获取设置的属性值 mColor = a.getColor(R.styleable.circleview_circle_color, Color.RED); //解析完毕释放资源 a.recycle(); init(); }最后在布局文件中使用自定义属性 需要注意的是一定要通过命名空间去使用自定义属性,即一定要先声明才能使用该属性
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:mview="http://schemas.android.com/apk/res/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity" > <com.example.myroundviewactivity.CircleView android:id="@+id/m_view" android:layout_width="wrap_content" android:layout_height="match_parent" mview:circle_color = "#ffffff" /> </RelativeLayout>一个简单的自定义View代码示例:
package com.example.myroundviewactivity; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.View; public class CircleView extends View { private int mColor = Color.RED; //抗锯齿 private Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); public CircleView(Context context) { super(context); // TODO Auto-generated constructor stub init(); } public CircleView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); // TODO Auto-generated constructor stub //自定义属性 TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.circleview); mColor = a.getColor(R.styleable.circleview_circle_color, Color.RED); a.recycle(); init(); } public CircleView(Context context, AttributeSet attrs) { this(context,attrs,0); } private void init(){ mPaint.setColor(mColor); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { // TODO Auto-generated method stub super.onMeasure(widthMeasureSpec, heightMeasureSpec); //给View添加wrap_content支持 int widthSpecMode = MeasureSpec.getMode(widthMeasureSpec); int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec); int heightSpecMode = MeasureSpec.getMode(heightMeasureSpec); int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec); if (widthSpecMode == MeasureSpec.AT_MOST && heightSpecMode == MeasureSpec.AT_MOST) { setMeasuredDimension(200, 200); }else if(widthSpecMode == MeasureSpec.AT_MOST){ setMeasuredDimension(200, heightSpecSize); }else if(heightSpecMode == MeasureSpec.AT_MOST){ setMeasuredDimension(widthSpecSize, 200); } } @Override protected void onDraw(Canvas canvas) { // TODO Auto-generated method stub super.onDraw(canvas); //使自定义View支持padding属性 final int paddingleft = getPaddingLeft(); final int paddingright = getPaddingRight(); final int paddingtop = getPaddingTop(); final int paddingbottom = getPaddingBottom(); int width = getWidth()-paddingleft-paddingright; int height = getHeight()-paddingtop-paddingbottom; int radius = Math.max(width, height)/2; canvas.drawCircle(paddingleft+width/2, paddingtop+height/2, radius, mPaint); } }2.继承ViewGroup派生特殊的Layout
http://blog.csdn.net/lmj623565791/article/details/38339817/
3.继承特定的View
package com.example.commonview; import android.content.Context; import android.util.AttributeSet; /** * 一直处于滚动状态的textview */ public class AlwaysMarqueeText extends TextView { public AlwaysMarqueeText(Context context) { super(context); } public AlwaysMarqueeText(Context context, AttributeSet attrs) { super(context, attrs); } public AlwaysMarqueeText(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); } @Override public boolean isFocused() { return true; } }4.继承特定的ViewGroup
package com.example.commonview; import java.util.Date; import android.annotation.SuppressLint; import android.content.Context; import android.os.Handler; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.LinearLayout; import android.widget.TextView; @SuppressLint("NewApi") public class TimeAndDateView extends LinearLayout { private View rootView; private TextView tvDate; private TextView tvTime; private String currentTime; private String currentDate; private String currentWeek; private final static int UPDATE_TIME = 10001; private Handler mHandler = new Handler() { @Override public void handleMessage(android.os.Message msg) { switch (msg.what) { case UPDATE_TIME: updateDateTime(); mHandler.sendEmptyMessageDelayed(UPDATE_TIME, 10 * 1000); break; } }; }; public TimeAndDateView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); rootView = LayoutInflater.from(context).inflate(R.layout.time_date_layout, this, true); tvDate = (TextView)rootView.findViewById(R.id.date_textview); tvTime = (TextView)rootView.findViewById(R.id.time_textview); currentTime = "HH:mm"; currentDate = "MM/dd"; currentWeek = "EEEE"; } public TimeAndDateView(Context context, AttributeSet attrs) { super(context, attrs); rootView = LayoutInflater.from(context).inflate(R.layout.time_date_layout, this, true); tvDate = (TextView)rootView.findViewById(R.id.date_textview); tvTime = (TextView)rootView.findViewById(R.id.time_textview); currentTime = "HH:mm"; currentDate = "MM/dd"; currentWeek = "EEEE"; } public TimeAndDateView(Context context) { super(context); rootView = LayoutInflater.from(context).inflate(R.layout.time_date_layout, this, true); tvDate = (TextView)rootView.findViewById(R.id.date_textview); tvTime = (TextView)rootView.findViewById(R.id.time_textview); currentTime = "HH:mm"; currentDate = "MM/dd"; currentWeek = "EEEE"; } public void start() { if (mHandler.hasMessages(UPDATE_TIME)) { mHandler.removeMessages(UPDATE_TIME); } mHandler.sendEmptyMessage(UPDATE_TIME); } public void stop() { mHandler.removeMessages(UPDATE_TIME); } private void updateDateTime() { Date date = SynchServerTimer.getDate(); tvTime.setText(SmartLunznDate.getChinaDateStr(currentTime, date)); tvDate.setText(SmartLunznDate.getChinaDateStr(currentDate, date) + " " + SmartLunznDate.getChinaDateStr(currentWeek, date)); } }