之前在我的另外一个帐号中,发了一篇博文
博客地址:http://blog.csdn.net/u012790647/article/details/16007559
不涉及版权的情况下,某些源码不是你的也不是我的,源码是共享的。交流才能进步。。。。。不重复造轮子创新才是王道
先上图:这是本博文的自定义控件
使用的就是这篇博文将要写的一个自定义view,MyButton这个控件可以参考sdk中:
LabelView
/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.view;
// Need the following import to get access to the app resources, since this
// class is in a sub-package.
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;
import com.example.android.apis.R;
/**
* Example of how to write a custom subclass of View. LabelView
* is used to draw simple text views. Note that it does not handle
* styled text or right-to-left writing systems.
*
*/
public class LabelView extends View {
private Paint mTextPaint;
private String mText;
private int mAscent;
/**
* Constructor. This version is only needed if you will be instantiating
* the object manually (not from a layout XML file).
* @param context
*/
public LabelView(Context context) {
super(context);
initLabelView();
}
/**
* Construct object, initializing with any attributes we understand from a
* layout file. These attributes are defined in
* SDK/assets/res/any/classes.xml.
*
* @see android.view.View#View(android.content.Context, android.util.AttributeSet)
*/
public LabelView(Context context, AttributeSet attrs) {
super(context, attrs);
initLabelView();
TypedArray a = context.obtainStyledAttributes(attrs,
R.styleable.LabelView);
CharSequence s = a.getString(R.styleable.LabelView_text);
if (s != null) {
setText(s.toString());
}
// Retrieve the color(s) to be used for this view and apply them.
// Note, if you only care about supporting a single color, that you
// can instead call a.getColor() and pass that to setTextColor().
setTextColor(a.getColor(R.styleable.LabelView_textColor, 0xFF000000));
int textSize = a.getDimensionPixelOffset(R.styleable.LabelView_textSize, 0);
if (textSize > 0) {
setTextSize(textSize);
}
a.recycle();
}
private final void initLabelView() {
mTextPaint = new Paint();
mTextPaint.setAntiAlias(true);
// Must manually scale the desired text size to match screen density
mTextPaint.setTextSize(16 * getResources().getDisplayMetrics().density);
mTextPaint.setColor(0xFF000000);
setPadding(3, 3, 3, 3);
}
/**
* Sets the text to display in this label
* @param text The text to display. This will be drawn as one line.
*/
public void setText(String text) {
mText = text;
requestLayout();
invalidate();
}
/**
* Sets the text size for this label
* @param size Font size
*/
public void setTextSize(int size) {
// This text size has been pre-scaled by the getDimensionPixelOffset method
mTextPaint.setTextSize(size);
requestLayout();
invalidate();
}
/**
* Sets the text color for this label.
* @param color ARGB value for the text
*/
public void setTextColor(int color) {
mTextPaint.setColor(color);
invalidate();
}
/**
* @see android.view.View#measure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
setMeasuredDimension(measureWidth(widthMeasureSpec),
measureHeight(heightMeasureSpec));
}
/**
* Determines the width of this view
* @param measureSpec A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = (int) mTextPaint.measureText(mText) + getPaddingLeft()
+ getPaddingRight();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Determines the height of this view
* @param measureSpec A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
mAscent = (int) mTextPaint.ascent();
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = (int) (-mAscent + mTextPaint.descent()) + getPaddingTop()
+ getPaddingBottom();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Render the text
*
* @see android.view.View#onDraw(android.graphics.Canvas)
*/
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
canvas.drawText(mText, getPaddingLeft(), getPaddingTop() - mAscent, mTextPaint);
}
}
然后在其基础上扩展,今天写的这个,关于写的一个自定义控件。
在进入商品详细画面后,会呈现出这个商品的相关颜色,尺码属性。最近公司闲的蛋疼,叫加上这个功能,加了也一直放着不知道肿么?,于是这几天就弄了下,虽说是个自定义控件但感觉高级不了哪里去,但也是辛勤劳动成果。贴上来,或许某些情况下还用的着。并不是100%原创,在customLinearlayout也参考过别人的代码(http://blog.csdn.net/long704480904/article/details/9011115)、所谓不重复造轮子嘛,就看你怎么发挥了。参考也说的理直气壮,嘿嘿,自我嘲讽一下。
先说下图片中的Button(extends View )
package com.example.androidcustomwidget;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
/**
*
* 自定义控件
*/
public class MyButton extends View {
/**
* 画笔,包含了画几何图形、文本等的样式和颜色信息
*/
private Paint mPaint;
/**
* 控件文本
*/
private String _text = "二零一三年";
/**
* 字体颜色
*/
private int textColor = Color.BLACK;
/**
* 字体大小
*/
private float textSize = 30;// 在MEIZU MX2上必须要设置这个值才行 一般手机上只要20就够大了。。。。。
/**
* 存储当前按下状态
*/
private boolean _isPress = false;
/**
* 存储当前选中状态
*/
private boolean _isChecked = false;
/**
* 控件的id 该自定义控件的事件处理已经在onTouchEvent里面处理,再调用回调,可以不要id属性
*/
private int m_id;
/**
* 选中状态改变后,触发回调
*/
private ChangedCheckCallBackAttri mCallback;
private int _mAscent;
private int mWidth = 0;
private int mHeight = 0;
public int getmWidth() {
return mWidth;
}
public void setmWidth(int mWidth) {
this.mWidth = mWidth;
}
public int getmHeight() {
return mHeight;
}
public void setmHeight(int mHeight) {
this.mHeight = mHeight;
}
public MyButton(Context context, String name) {
super(context);
mPaint = new Paint();
setPadding(10, 5, 10, 5);
mPaint.setColor(textColor);
mPaint.setTextSize(textSize);
mPaint.setAntiAlias(true);
mPaint.setDither(true);
this.setText(name);
// mPaint.setTypeface(Typeface.DEFAULT_BOLD) ;//设置字体
}
public MyButton(Context context, AttributeSet attrs) {
super(context, attrs);
mPaint = new Paint();
mPaint.setAntiAlias(true);// 抗锯齿
mPaint.setDither(true);// 图像抖动处理
setPadding(10, 5, 10, 5);
// TypedArray是一个用来存放由context.obtainStyledAttributes获得的属性的数组
// 在使用完成后,一定要调用recycle方法
// 属性的名称是styleable中的名称+“_”+属性名称
TypedArray array = context.obtainStyledAttributes(attrs,
R.styleable.MyButton);
// String strText = array.getText(R.styleable.jwradiobtn_text, "");
CharSequence text = array.getText(R.styleable.MyButton_android_text);
if (text != null)
_text = text.toString();
textColor = array.getColor(R.styleable.MyButton_textColor, Color.BLACK); // 提供默认值,放置未指定
textSize = array.getDimension(R.styleable.MyButton_textSize, 20);
mPaint.setColor(textColor);
mPaint.setTextSize(textSize);
array.recycle(); // 一定要调用,否则这次的设定会对下次的使用造成影响
}
public void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (_text != null && !_text.equals("")) {
mPaint.setTextSize(textSize);
mPaint.setColor(textColor);
mPaint.setTextAlign(Align.CENTER);// 文字居中显示
mPaint.setStrokeWidth(0);
FontMetrics fontMetrics = mPaint.getFontMetrics();
float fontHeight = fontMetrics.bottom - fontMetrics.top;// 文本高度
float baseY = this.getHeight() - (this.getHeight() - fontHeight)
/ 2 - fontMetrics.bottom;
canvas.drawText(_text, this.getWidth() / 2, baseY, mPaint);// (this.getHeight()
// -
// fontHeight)/
// 2
// __额外
// 设置了mPaint.setTextAlign(Align.CENTER);//文字居中显示
// 所以canvas.drawText(text,x,y,paint);中,x,为横坐标中点位置
}
if (_isPress) {
// 按下时边框绘制橘黄色
mPaint.setColor(Color.rgb(255, 165, 0));
mPaint.setStyle(Style.STROKE); // 设置填充
mPaint.setStrokeWidth(5);
canvas.drawRect(1, 1, this.getWidth() - 1, this.getHeight() - 1,
mPaint); // 绘制矩形
return;
}
if (_isChecked) {
// 选中时边框绘制红色
// Canvas中含有很多画图的接口,利用这些接口,我们可以画出我们想要的图形
// mPaint = new Paint();
mPaint.setColor(Color.RED);
mPaint.setStyle(Style.STROKE); // 设置填充
mPaint.setStrokeWidth(5);
canvas.drawRect(1, 1, this.getWidth() - 1, this.getHeight() - 1,
mPaint); // 绘制矩形
// 绘制右下角的三角形
mPaint.setStyle(Style.FILL);
Path path = new Path();
path.moveTo(this.getWidth(), this.getHeight());
path.lineTo(this.getWidth(), this.getHeight() - 15);
path.lineTo(this.getWidth() - 15, this.getHeight());
canvas.drawPath(path, mPaint);
} else {
// 选中时边框绘制黑色
mPaint.setColor(Color.BLACK);
mPaint.setStyle(Style.STROKE); // 设置填充
mPaint.setStrokeWidth(1);
canvas.drawRect(0, 0, this.getWidth(), this.getHeight(), mPaint); // 绘制矩形
}
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
// if (event.getAction() == MotionEvent.ACTION_DOWN)
// return true;
return super.dispatchTouchEvent(event);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.e("JWRadioBtn", "JWRadioBtn_onTouchEvent:" + event.getAction());
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
_isPress = true;
this.invalidate();// 重绘,执行onDraw
return true;// 要返回true,后面的action_up和move才能执行
case MotionEvent.ACTION_UP:
if (mCallback != null) {
mCallback.ChangedCheck(this);
}
_isPress = false;
setChecked(!_isChecked);
break;
case MotionEvent.ACTION_MOVE:
break;
default:
_isPress = false;
this.invalidate();// 重绘,执行onDraw
break;
}
return super.onTouchEvent(event);
}
/**
* @see android.view.View#measure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// setMeasuredDimension(measureWidth(widthMeasureSpec),
// measureHeight(heightMeasureSpec));
setMeasuredDimension(resolveSize(mWidth, widthMeasureSpec),
resolveSize(mHeight, widthMeasureSpec));
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureWidth(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text
result = (int) mPaint.measureText(_text) + getPaddingLeft()
+ getPaddingRight();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by
// measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureHeight(int measureSpec) {
int result = 0;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
_mAscent = (int) mPaint.ascent();
if (specMode == MeasureSpec.EXACTLY) {
// We were told how big to be
result = specSize;
} else {
// Measure the text (beware: ascent is a negative number)
result = (int) (-_mAscent + mPaint.descent()) + getPaddingTop()
+ getPaddingBottom();
if (specMode == MeasureSpec.AT_MOST) {
// Respect AT_MOST value if that was what is called for by
// measureSpec
result = Math.min(result, specSize);
}
}
return result;
}
public void setChecked(boolean value) {
_isChecked = value;
this.invalidate();
// if (mCallback != null)
// mCallback.ChangedCheck();
}
/**
*
* @return 控件状态 true:选中 false :未被选中
*/
public boolean getChecked() {
return _isChecked;
}
public void setText(String value) {
_text = value;
this.invalidate();
}
public String getText() {
return _text;
}
public void setTextColor(int value) {
textColor = value;
this.invalidate();
}
public int getTextColor() {
return textColor;
}
public void setTextSize(float value) {
textSize = value;
this.invalidate();
}
public float getTextSize() {
return textSize;
}
public void setId(int id) {
this.m_id = id;
}
public int getId() {
return this.m_id;
}
/**
* 获取控件宽度
*
* @return 文本总宽度 + padding消耗值
*/
public int getRealWidth() {
if (this.getWidth() == 0) {
Rect rect = new Rect();
mPaint.getTextBounds(_text, 0, _text.length(), rect);
return rect.width() + this.getPaddingLeft()
+ this.getPaddingRight();
} else {
return this.getWidth();
}
}
/**
* 获取控件高度
*
* @return 文本高度+ pading消耗值
*/
public int getRealHeight() {
if (this.getHeight() == 0) {
Rect rect = new Rect();
mPaint.getTextBounds(_text, 0, _text.length(), rect);
return rect.height() + this.getPaddingTop()
+ this.getPaddingBottom();
} else {
return this.getHeight();
}
}
/**
* 接口用于回调
*/
public interface ChangedCheckCallBackAttri {
void ChangedCheck(MyButton attributeBtn);
}
public void setCallback(ChangedCheckCallBackAttri callBack) {
this.mCallback = callBack;
}
}
主要的几个方法:public void onDraw(Canvas canvas)、public boolean onTouchEvent(MotionEvent event)、protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
/**
* 接口用于回调
*/
public interface ChangedCheckCallBackAttri {
void ChangedCheck(MyButton attributeBtn);
}
public void setCallback(ChangedCheckCallBackAttri callBack) {
this.mCallback = callBack;
}
回调接口主要用于在view被选中的时候,处理一些相关操作,比如我在AttributeMyWidget中的操作:
attriBtn.setCallback(new ChangedCheckCallBackAttri() {
@Override
public void ChangedCheck(MyButton attributeBtn) {
if (attributeBtn.getTag() == null) {
return;
}
int index = Integer.valueOf(attributeBtn.getTag()
.toString());
if (index != selectedIndex) {
MyButton btn = radioBtnList.get(selectedIndex);
btn.setChecked(false);
selectedIndex = index;
}
Toast.makeText(context,
"你点击了" + attriDetailList.get(index).get("name"),
Toast.LENGTH_SHORT).show();
// String attId = getAttriDetail();
// if (attId.equals("")) {
// return;
// }
//
// // 重选属性时,回调,更新库存,价格数据显示
// AttributeMyWidget.this.modifyedListener.modifyed(attId,
// flag);
}
});
因为是动态添加View所以在添加的同时给每个View给了tag,在回调时候就派上用场了,这里我根据tag获得他的index进而做更多操作。
还有个问题:
/**
* @see android.view.View#measure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// setMeasuredDimension(measureWidth(widthMeasureSpec),
// measureHeight(heightMeasureSpec));
setMeasuredDimension(resolveSize(mWidth, widthMeasureSpec),
resolveSize(mHeight, widthMeasureSpec));
}
这里mWidth,mHeight是我固定设定的固定宽高。在创建
public AttributeMyWidget(Context context, int childViewWidth,
int childViewHeight) {
的时候设定。也可以根据内容来决定其宽高。
说到这里:几者之间关系:MyButton + CustomLinearLayout------>AttributeMyWidget ------>in Activity中new
接下来是CustomLinearLayout
package com.example.androidcustomwidget;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
/**
*
* 实现自动换行
*
*/
public class CustomLinearLayout extends LinearLayout {
private Context mContext;
public CustomLinearLayout(Context context) {
super(context);
mContext = context;
}
public CustomLinearLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
}
/** 控件总行数 **/
private int num = 1;
/** 按钮总行数 **/
private int columns = 0;
/** 设置子view的宽度外部设定,需要根据子view的宽度布局换行时会用 **/
private int mCellWidth = 0;
/** 设置子view的高度 **/
private int mCellHeight = 0;
/** //layout总宽度 **/
int layoutTotalWidth = 0;
public int getLayoutTotalWidth() {
return layoutTotalWidth;
}
public void setLayoutTotalWidth(int layoutTotalWidth) {
this.layoutTotalWidth = layoutTotalWidth;
}
public int getmCellWidth() {
return mCellWidth;
}
public void setmCellWidth(int mCellWidth) {
this.mCellWidth = mCellWidth;
}
public int getmCellHeight() {
return mCellHeight;
}
public void setmCellHeight(int mCellHeight) {
this.mCellHeight = mCellHeight;
}
/**
* 根据LinearLayout总宽度自动匹配布局
*/
public void autoLayout() {
int cellWidth = 0;// 子空间宽
int cellHeight = 0;// 子空间高
int totalWidth = 0;// 每一行总宽度
int x = 0;
int y = 0;
int count = getChildCount();// 5
for (int j = 0; j < count; j++) {
View childView = getChildAt(j);// [35,70]
// 获取子控件Child的宽高[38,31]
cellWidth = ((MyButton) childView).getRealWidth();
cellHeight = ((MyButton) childView).getRealHeight();
// +5 保持+5间距
int left = x + 5;
int top = y;
// childView.layout(x, y, x + cellWidth, y + cellHeight);
// 布局子控件0
childView.layout(left, top, left + cellWidth, top + cellHeight);
x = left + 5;
if (totalWidth > this.getLayoutTotalWidth()) {
// 换行
x = 0;
totalWidth = 0;
y += cellHeight + 5;
num++;
} else {
x += cellWidth;
totalWidth += x;
}
}
}
/**
* 根据子view宽度布局
*/
public void byChildWidthLayout(boolean changed, int l, int t, int r, int b) {
int cellWidth = mCellWidth;
int cellHeight = mCellHeight;
columns = (r - l) / cellWidth;
if (columns < 0) {
columns = 1;
}
int x = 0;
int y = 0;
int i = 0;
int count = getChildCount();
for (int j = 0; j < count; j++) {
View childView = getChildAt(j);
// 获取子控件Child的宽高
int w = ((MyButton) childView).getmWidth();
int h = ((MyButton) childView).getmHeight();
// 计算子控件的顶点坐标
int left = x + 5;
int top = y;
// 布局子控件0
childView.layout(left, top, left + w, top + h);
x = left + 5;
if (i >= (columns - 1)) {
i = 0;
x = 0;
y += cellHeight + 5;
num++;
} else {
i++;
x += cellWidth;
}
}
}
/**
* 自动换行模式下
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
public void onMeasureByChildContent(int widthMeasureSpec,
int heightMeasureSpec) {
int count = getChildCount();
int layoutWidth = 0;
int childHeight = 0; // 子view的高
int a = this.getLayoutParams().width;
int b = this.getLayoutParams().height;
// Log.e("customlayout 随内容...", "getLayoutParams宽度"+a
// +"**********************" + "getLayoutParams高度"+ b ) ;
// 设置子空间Child的宽高
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);
layoutWidth += ((MyButton) childView).getRealWidth();
childHeight = ((MyButton) childView).getHeight();
}
// 设置容器控件所占区域大小
setMeasuredDimension(resolveSize(layoutWidth, widthMeasureSpec),
resolveSize(num * childHeight, heightMeasureSpec));
// layoutTotalWidth = this.getWidth() ;
Log.e("总宽度", "************************" + layoutTotalWidth);
}
/**
*
* 子view宽度来
*
* @param widthMeasureSpec
* @param heightMeasureSpec
*/
public void onMeasureByChildWidth(int widthMeasureSpec,
int heightMeasureSpec) {
// 创建测量参数
int cellWidthSpec = MeasureSpec.makeMeasureSpec(mCellWidth,
MeasureSpec.EXACTLY);
int cellHeightSpec = MeasureSpec.makeMeasureSpec(mCellHeight,
MeasureSpec.EXACTLY);
int count = getChildCount();
// 设置子空间Child的宽高
for (int i = 0; i < count; i++) {
View childView = getChildAt(i);
childView.measure(cellWidthSpec, cellHeightSpec);
}
// 设置容器控件所占区域大小
setMeasuredDimension(
resolveSize(mCellWidth * columns + 5, widthMeasureSpec),
resolveSize(mCellHeight * num + 10, heightMeasureSpec));
}
/**
* 控制子控件的换行
*/
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
byChildWidthLayout(changed, l, t, r, b);
// autoLayout();
}
/**
* 计算控件及子控件所占区域
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
// onMeasureByChildContent(widthMeasureSpec, heightMeasureSpec);
onMeasureByChildWidth(widthMeasureSpec, heightMeasureSpec);
}
}
AttributeMyWidget的布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E8E8E8"
android:orientation="vertical" >
<TextView
android:id="@+id/attriname"
android:layout_width="match_parent"
android:layout_height="30dp"
android:ellipsize="end"
android:gravity="left|center_vertical"
android:paddingLeft="5dp"
android:singleLine="true"
android:text=""
android:textColor="#CD2626"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="1dp"
android:background="#B0B0B0" />
<com.example.androidcustomwidget.CustomLinearLayout
android:id="@+id/attri_radiogrouplayout"
android:layout_width="800dp"
android:layout_height="wrap_content" >
</com.example.androidcustomwidget.CustomLinearLayout>
</LinearLayout>
最后是MainActivity
package com.example.androidcustomwidget;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.LinearLayout;
public class MainActivity extends Activity {
AttributeMyWidget attributeMyWidget;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
LinearLayout layout = (LinearLayout) findViewById(R.id.layout);
// 魅族Mx2手机分辨率比较大因此,这里我设置了[120,80]的大小,通常情况下的话[70,35就差不多了]
attributeMyWidget = new AttributeMyWidget(this, 120, 80);
// attributeMyWidget = new AttributeMyWidget(this,800) ;
attributeMyWidget.loadAttriData();
attributeMyWidget.setName("颜色属性");
layout.addView(attributeMyWidget);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
源码下载:http://download.csdn.net/detail/xxm282828/6856641