自定义View笔记(一)

来源:互联网 发布:在线互动课堂源码 编辑:程序博客网 时间:2024/06/05 23:46

注:该笔记是整理学习鸿洋大神自定义View系列博客的部分知识点。

自定义View(自定义控件)四大步骤:

1. 自定义View的属性2. 在View的构造方法中获取自定义的属性3. 重写onMesure()   不是选项4. 重写onDraw()

自定义View属性

/**    在res/values下建立一个attrs.xml文件    */<resources>      <attr name="titleText" format="string" />      <attr name="titleTextSize" format="dimension" />      <attr name="titleTextColor" format="color" />      <attr name="image" format="reference" />      <attr name="imageScaleType">          <enum name="fillXY" value="0" />          <enum name="center" value="1" />      </attr>      <declare-styleable name="CustomImageView">          <attr name="titleText" />          <attr name="titleTextSize" />          <attr name="titleTextColor" />          <attr name="image" />          <attr name="imageScaleType" />      </declare-styleable>  </resources>  

注:format的取值类型有:
string — 字符串
color — 颜色值
demension — 尺寸值
integer — 整型值
float — 浮点值
reference — 参考某一资源ID
boolean — 布尔值
fraction — 百分数
enum — 枚举值
flag — 位或运算

获取自定义的样式属性

public CustomTitleView(Context context, AttributeSet attrs, int defStyle)      {          super(context, attrs, defStyle);          /**         * 获得我们所定义的自定义样式属性         */          TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomTitleView, defStyle, 0);          int n = a.getIndexCount();          for (int i = 0; i < n; i++)          {              int attr = a.getIndex(i);              switch (attr)              {              case R.styleable.CustomTitleView_titleText:                  mTitleText = a.getString(attr);                  break;              case R.styleable.CustomTitleView_titleTextColor:                  // 默认颜色设置为黑色                  mTitleTextColor = a.getColor(attr, Color.BLACK);      //参数:a.getColor(输入值, 默认值)                break;              case R.styleable.CustomTitleView_titleTextSize:                  // 默认设置为16sp,TypeValue也可以把sp转化为px                  mTitleTextSize = a.getDimensionPixelSize(attr, (int) TypedValue.applyDimension(                          TypedValue.COMPLEX_UNIT_SP, 16, getResources().getDisplayMetrics()));                  break;              }          }          a.recycle();  //将TypedArray回收        /**         * 获得绘制文本的宽和高         */          mPaint = new Paint();          mPaint.setTextSize(mTitleTextSize);          // mPaint.setColor(mTitleTextColor);          mBound = new Rect();          mPaint.getTextBounds(mTitleText, 0, mTitleText.length(), mBound);      //通过 getTextBound(String text,int start,int end,Rect bounds) 或者 getTextBound(char[] text,int index,int count,Rect bounds) 获取绘制的大小    }  

重写onMeasure()

@Override  protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)  {      // super.onMeasure(widthMeasureSpec, heightMeasureSpec);      /**     * 设置宽度     */      int specMode = MeasureSpec.getMode(widthMeasureSpec);      int specSize = MeasureSpec.getSize(widthMeasureSpec);      if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate      {          mWidth = specSize;      } else{          // 由图片决定的宽          int desireByImg = getPaddingLeft() + getPaddingRight() + mImage.getWidth();          // 由字体决定的宽          int desireByTitle = getPaddingLeft() + getPaddingRight() + mTextBound.width();          if (specMode == MeasureSpec.AT_MOST)// wrap_content          {              int desire = Math.max(desireByImg, desireByTitle);     //取 desireByImg, desireByTitle中最大值            mWidth = Math.min(desire, specSize);          }      }      /**     * 设置高度     */      specMode = MeasureSpec.getMode(heightMeasureSpec);      specSize = MeasureSpec.getSize(heightMeasureSpec);      if (specMode == MeasureSpec.EXACTLY)// match_parent , accurate      {          mHeight = specSize;      } else {          int desire = getPaddingTop() + getPaddingBottom() + mImage.getHeight() + mTextBound.height();          if (specMode == MeasureSpec.AT_MOST)// wrap_content          {              mHeight = Math.min(desire, specSize);          }      }      setMeasuredDimension(mWidth, mHeight);  }  
原创粉丝点击