zoukankan      html  css  js  c++  java
  • Android突击:定制控件

    继承,组合和绘制。
    在安卓里,好多控件都是TextView的子控件
    容器类:布局类,其实也是个控件,不过他可以包含其他的控件。

    组合方式构建:
    1,在控件类中定义TextView和EditText类中
    2,在控件类的构造方法读取控件的属性
    3,根据控件属性值设置TextView和EditText值及二者的相对位置。
    这个例子是从线性布局中继承。这个是不用带命名空间的。
    所有的控件类都会有context,所有的属性名值即放在res目录下的资源就是用AttributeSet里。
    1. public class LabelEditText extends LinearLayout
    2. {
    3. private TextView textView;
    4. private String labelText;
    5. private int labelFontSize;
    6. private String labelPosition;
    7. public LabelEditText(Context context, AttributeSet attrs)
    8. {
    9. super(context, attrs);
    10. // 读取labelText属性的资源ID
    11. int resourceId = attrs.getAttributeResourceValue(null, "labelText", 0);
    12. // 未获得资源ID,继续读取属性值
    13. if (resourceId == 0)
    14. labelText = attrs.getAttributeValue(null, "labelText");
    15. // 从资源文件中获得labelText属性的值
    16. else
    17. labelText = getResources().getString(resourceId);
    18. // 如果按两种方式都未获得labelTex属性的值,表示未设置该属性,抛出异常
    19. if (labelText == null)
    20. {
    21. throw new RuntimeException("必须设置labelText属性.");
    22. }
    23. // 获得labelFontSize属性的资源ID
    24. resourceId = attrs.getAttributeResourceValue(null, "labelFontSize", 0);
    25. // 继续读取labelFontSize属性的值,如果未设置该属性,将属性值设为14
    26. if (resourceId == 0)
    27. labelFontSize = attrs.getAttributeIntValue(null, "labelFontSize",
    28. 14);
    29. // 从资源文件中获得labelFontSize属性的值
    30. else
    31. labelFontSize = getResources().getInteger(resourceId);
    32. // 获得labelPosition属性的资源ID
    33. resourceId = attrs.getAttributeResourceValue(null, "labelPosition", 0);
    34. // 继续读取labelPosition属性的值
    35. if (resourceId == 0)
    36. labelPosition = attrs.getAttributeValue(null, "labelPosition");
    37. // 从资源文件中获得labelPosition属性的值
    38. else
    39. labelPosition = getResources().getString(resourceId);
    40. // 如果未设置labelPosition属性值,将该属性值设为left
    41. if (labelPosition == null)
    42. labelPosition = "left";
    43. String infService = Context.LAYOUT_INFLATER_SERVICE;
    44. LayoutInflater li;
    45. // 获得LAYOUT_INFLATER_SERVICE服务
    46. li = (LayoutInflater) context.getSystemService(infService);
    47. LinearLayout linearLayout = null;
    48. // 根据labelPosition属性的值装载不同的布局文件
    49. if("left".equals(labelPosition))
    50. linearLayout = (LinearLayout)li.inflate(R.layout.labeledittext_horizontal, this);
    51. else if("top".equals(labelPosition))
    52. linearLayout = (LinearLayout)li.inflate(R.layout.labeledittext_vertical, this);
    53. else
    54. throw new RuntimeException("labelPosition属性的值只能是left或top.");
    55. // 下面的代码从相应的布局文件中获得了TextView对象,并根据LabelTextView的属性值设置TextView的属性
    56. textView = (TextView) findViewById(R.id.textview);
    57. //textView.setTextSize((float)labelFontSize);
    58. textView.setTextSize(labelFontSize);
    59. textView.setText(labelText);
    60. }
    61. }

    继承方式构建:
    需要使用命名空间。
    xmlns:android="http://schemas.android.com/apk/res/android"  这个是系统的命名空间值,在R类里。
    1. public class IconTextView extends TextView
    2. {
    3. // 命名空间的值
    4. private final String namespace = "http://cn.eoe.icon.textview";
    5. // 图像资源ID
    6. private int resourceId = 0;
    7. private Bitmap bitmap;
    8. public IconTextView(Context context, AttributeSet attrs)
    9. {
    10. super(context, attrs);
    11. resourceId = attrs.getAttributeResourceValue(namespace, "iconSrc", 0);
    12. if (resourceId > 0)
    13. bitmap = BitmapFactory.decodeResource(getResources(), resourceId);
    14. }
    15. @Override
    16. protected void onDraw(Canvas canvas)
    17. {
    18. if (bitmap != null)
    19. {
    20. // 从原图上截取图像的区域,在本例中为整个图像
    21. Rect src = new Rect();
    22. // 将截取的图像复制到bitmap上的目标区域,在本例中与复制区域相同
    23. Rect target = new Rect();
    24. src.left = 0;
    25. src.top = 0;
    26. src.right = bitmap.getWidth();
    27. src.bottom = bitmap.getHeight();
    28. int textHeight = (int) getTextSize();
    29. target.left = 0;
    30. // 计算图像复制到目录区域的纵坐标。由于TextView中文本内容并不是从最顶端开始绘制的,因此,需要重新计算绘制图像的纵坐标
    31. target.top = (int) ((getMeasuredHeight() - getTextSize()) / 2) + 1;
    32. target.bottom = target.top + textHeight;
    33. // 为了保证图像不变形,需要根据图像高度重新计算图像的宽度
    34. target.right = (int) (textHeight * (bitmap.getWidth() / (float) bitmap
    35. .getHeight()));
    36. // 开始绘制图像
    37. canvas.drawBitmap(bitmap, src, target, getPaint());
    38. // 将TextView中的文本向右移动一定的距离(在本例中移动了图像宽度加2个象素点的位置)
    39. canvas.translate(target.right + 2, 0);
    40. }
    41. super.onDraw(canvas);
    42. }
    43. }
    安卓是不区分资源的ID类型的。





  • 相关阅读:
    好玩的spring boot banner 图
    数据结构和算法二(数组)
    数据结构与算法三(链表)
    数据结构和算法一(基础知识)
    jenkins 部署node应用
    Docker-compose 安装Jenkins
    Docker 网络模式
    exe4j 转jar
    c#索引器的简单用法
    Adapter模式
  • 原文地址:https://www.cnblogs.com/zhuzhenfeng/p/4641365.html
Copyright © 2011-2022 走看看