本文罗列Android中字体宽度和高度的相关概念,及测量方法 。

原文请参考Android_FontMetrics、Android字符串进阶之三:字体属性及测量(FontMetrics)、 Android UI 之居中绘制文本内容的正确方法——实现自定义一个TextView。

我们在自定义一个控件的时候,有时候会需要自己来绘制一些文本内容,这样就自然而然遇到确定文本的宽高尺寸和方位的问题,事实上明确了控件和文本的宽高,就可以根据需要确定文本的方位是居中、居上还是左上等。

Canvas 绘制文本时,使用FontMetrics对象,计算文本位置的坐标。

  1. public static class FontMetrics {
  2. /**
  3. * The maximum distance above the baseline for the tallest glyph in
  4. * the font at a given text size.
  5. */
  6. public float top;
  7. /**
  8. * The recommended distance above the baseline for singled spaced text.
  9. */
  10. public float ascent;
  11. /**
  12. * The recommended distance below the baseline for singled spaced text.
  13. */
  14. public float descent;
  15. /**
  16. * The maximum distance below the baseline for the lowest glyph in
  17. * the font at a given text size.
  18. */
  19. public float bottom;
  20. /**
  21. * The recommended additional space to add between lines of text.
  22. */
  23. public float leading;
  24. }

说明如下:
1. 基准点是baseline
2. Ascent是baseline之上至字符最高处的距离
3. Descent是baseline之下至字符最低处的距离
4. Leading文档说的很含糊,其实是上一行字符的descent到下一行的ascent之间的距离
5. Top指的是指的是最高字符到baseline的值,即ascent的最大值
6. 同上,bottom指的是最下字符到baseline的值,即descent的最大值
descent-ascent就可以看作文本的高度。
图示如下:

Paint类有两个方法,也可以获取文本的高度:

  1. /**
  2. * Return the distance above (negative) the baseline (ascent) based on the
  3. * current typeface and text size.
  4. *
  5. * @return the distance above (negative) the baseline (ascent) based on the
  6. * current typeface and text size.
  7. */
  8. public native float ascent();
  9. /**
  10. * Return the distance below (positive) the baseline (descent) based on the
  11. * current typeface and text size.
  12. *
  13. * @return the distance below (positive) the baseline (descent) based on
  14. * the current typeface and text size.
  15. */
  16. public native float descent();

ascent():the distance above the baseline(baseline以上的height)
descent():the distance below the baseline(baseline以下的height)
所以descent()-ascent()也可以看成文字的height。

上面两种方法得到的文字高度是一致的,但从本人经验来说,这种高度对数字来说略高,比如在画折线图上的坐标轴值时就有很明显的体现,这种方式drawText()在Y轴上的值看上去比其值略偏下。

这种情况下,下面这种方式计算出来的文字宽高更准确一些。

  1. Paint pFont = new Paint();
  2. Rect rect = new Rect();
  3. pFont.getTextBounds("豆", 0, 1, rect);
  4. Log.v(TAG, "height:"+rect.height()+"width:"+rect.width());

下面给出一个综合Demo演示:

  1. package com.example.textmeasure;
  2. import android.app.Activity;
  3. import android.graphics.Paint;
  4. import android.graphics.Rect;
  5. import android.graphics.Paint.FontMetrics;
  6. import android.os.Bundle;
  7. import android.util.DisplayMetrics;
  8. import android.util.Log;
  9. public class MainActivity extends Activity {
  10. Paint mPaint=null;
  11. public float screenDensity;
  12. public float screenScaledDensity;
  13. public float textHeight1;
  14. public float textHeight2;
  15. public float textHeight3;
  16. public float textWidthA;
  17. public float textWidthB;
  18. @Override
  19. protected void onCreate(Bundle savedInstanceState) {
  20. super.onCreate(savedInstanceState);
  21. setContentView(R.layout.activity_main);
  22. //获取屏幕密度和字体适用的密度
  23. DisplayMetrics dm = getResources().getDisplayMetrics();
  24. screenDensity = dm.density;
  25. screenScaledDensity = dm.scaledDensity;
  26. mPaint=new Paint();
  27. mPaint.setTextSize(15*screenScaledDensity);
  28. //第一种获取文本高度的方式
  29. FontMetrics fm=mPaint.getFontMetrics();
  30. textHeight1=fm.descent-fm.ascent;
  31. //第二种获取文本高度的方式
  32. textHeight2=mPaint.descent()-mPaint.ascent();
  33. //第三种获取文本高度的方式
  34. Rect bounds=new Rect();
  35. mPaint.getTextBounds("0.00", 0, "0.00".length(), bounds);
  36. textHeight3=bounds.height();
  37. //获取文本宽度
  38. textWidthA=bounds.width();
  39. //获取文本宽度的另一种方式
  40. textWidthB=mPaint.measureText("0.00");
  41. Log.i("publish","textHeight1: "+textHeight1);
  42. Log.i("publish","textHeight2: "+textHeight2);
  43. Log.i("publish","textHeight3: "+textHeight3);
  44. Log.i("publish","textWidthA: "+textWidthA);
  45. Log.i("publish","textWidthB: "+textWidthB);
  46. }
  47. }

打印结果:

  1. 03-23 12:54:16.325: I/publish(27219): screenDensity: 3.0
  2. 03-23 12:54:16.325: I/publish(27219): screenScaledDensity: 3.0
  3. 03-23 12:54:16.325: I/publish(27219): textHeight1: 52.734375
  4. 03-23 12:54:16.325: I/publish(27219): textHeight2: 52.734375
  5. 03-23 12:54:16.325: I/publish(27219): textHeight3: 32.0
  6. 03-23 12:54:16.325: I/publish(27219): textWidthA: 82.0
  7. 03-23 12:54:16.325: I/publish(27219): textWidthB: 87.0

上面的Demo中使用到屏幕密度,代码中出现的所有尺寸单位都是像素,因此需要使用屏幕密度进行适配,其中dm.density是与控件尺寸相关的密度,dm.scaledDensity是与字体大小相关的密度。

在Android layout文件中使用sp,dp尺寸已经在一定程度上进行了适配。

下面说一下如何在一个自定义View中drawText()时设置文本居中,这部分内容转载于http://blog.csdn.net/carrey1989/article/details/10399727。

我们在画布中绘制文本的时候,会调用Canvas.drawText(String text, float x, float y, Paint paint)这个方法,其中y的坐标就是上图中baseline的y坐标,x坐标是文本绘制的起始x轴坐标。

因此要想文本居中,应如下计算:
float textCenterVerticalBaselineY = viewHeight / 2 - fm.descent + (fm.bottom - fm.top) / 2;
其中,textCenterVerticalBaselineY就是绘制文本时候的y坐标,viewHeight是控件的高度。这个换算关系不难理解,viewHeight/2-fm.descent的意思是将整个文字区域抬高到控件的1/2,然后我们再加上(fm.bottom - fm.top) / 2的意思就是将文本下沉文本top到bottom长度的一半,从而实现文本垂直居中的目的。 
有的人或许会问,为什么最后加上的是bottom到top距离的一半而不是descent到ascent的一半呢?其实这个是我测试的结果,我发现如果用bottom到top距离的一半来设置文本垂直居中,和系统控件TextView的文本居中效果是一样的,我们来看下面的效果: 
首先是使用(fm.bottom - fm.top) / 2的:

然后是使用然后是使用(fm.descent - fm.ascent) / 2: 

左边绿色的是系统的TextView文字居中效果,右边是我们自定义控件的文字居中效果,可以看出使用(fm.bottom - fm.top) / 2与TextView的效果是一样的,当然,我们不必一定要与TextView的效果相同,所以使用(fm.descent - fm.ascent) / 2也是可以的。

下面自定义一个可以控制内部文本绘制方位的TextView:

  1. //项目代码:
  2. //MyTextView.java
  3. package com.example.textalignment.mytextview;
  4. import com.example.textalignment.util.DisplayParams;
  5. import com.example.textalignment.util.DisplayUtil;
  6. import android.content.Context;
  7. import android.graphics.Bitmap;
  8. import android.graphics.Canvas;
  9. import android.graphics.Color;
  10. import android.graphics.Matrix;
  11. import android.graphics.Paint;
  12. import android.graphics.RectF;
  13. import android.graphics.Paint.Align;
  14. import android.graphics.Paint.FontMetrics;
  15. import android.graphics.drawable.Drawable;
  16. import android.util.AttributeSet;
  17. import android.util.DisplayMetrics;
  18. import android.view.View;
  19. /**
  20. * 自定义文本显示控件
  21. * 该自定义控件中的文本可以在9个方位进行控制
  22. * 左上——中上——右上
  23. * 左中——中中——右中
  24. * 左下——中下——右下
  25. * @author carrey
  26. *
  27. */
  28. public class MyTextView extends View {
  29. /** 要显示的文字 */
  30. private String text;
  31. /** 文字的颜色 */
  32. private int textColor;
  33. /** 文字的大小 */
  34. private int textSize;
  35. /** 文字的方位 */
  36. private int textAlign;
  37. // public static final int TEXT_ALIGN_CENTER = 0x00000000;
  38. public static final int TEXT_ALIGN_LEFT = 0x00000001;
  39. public static final int TEXT_ALIGN_RIGHT = 0x00000010;
  40. public static final int TEXT_ALIGN_CENTER_VERTICAL = 0x00000100;
  41. public static final int TEXT_ALIGN_CENTER_HORIZONTAL = 0x00001000;
  42. public static final int TEXT_ALIGN_TOP = 0x00010000;
  43. public static final int TEXT_ALIGN_BOTTOM = 0x00100000;
  44. /** 文本中轴线X坐标 */
  45. private float textCenterX;
  46. /** 文本baseline线Y坐标 */
  47. private float textBaselineY;
  48. /** 控件的宽度 */
  49. private int viewWidth;
  50. /** 控件的高度 */
  51. private int viewHeight;
  52. /** 控件画笔 */
  53. private Paint paint;
  54. private FontMetrics fm;
  55. /** 场景 */
  56. private Context context;
  57. public MyTextView(Context context) {
  58. super(context);
  59. this.context = context;
  60. init();
  61. }
  62. public MyTextView(Context context, AttributeSet attrs) {
  63. super(context, attrs);
  64. this.context = context;
  65. init();
  66. }
  67. /**
  68. * 变量初始化
  69. */
  70. private void init() {
  71. paint = new Paint();
  72. paint.setAntiAlias(true);
  73. paint.setTextAlign(Align.CENTER);
  74. //默认情况下文字居中显示
  75. textAlign = TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL;
  76. //默认的文本颜色是黑色
  77. this.textColor = Color.BLACK;
  78. }
  79. @Override
  80. protected void onLayout(boolean changed, int left, int top, int right,
  81. int bottom) {
  82. viewWidth = getWidth();
  83. viewHeight = getHeight();
  84. super.onLayout(changed, left, top, right, bottom);
  85. }
  86. @Override
  87. protected void onDraw(Canvas canvas) {
  88. //绘制控件内容
  89. setTextLocation();
  90. canvas.drawText(text, textCenterX, textBaselineY, paint);
  91. super.onDraw(canvas);
  92. }
  93. /**
  94. * 定位文本绘制的位置
  95. */
  96. private void setTextLocation() {
  97. paint.setTextSize(textSize);
  98. paint.setColor(textColor);
  99. fm = paint.getFontMetrics();
  100. //文本的宽度
  101. float textWidth = paint.measureText(text);
  102. float textCenterVerticalBaselineY = viewHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2;
  103. switch (textAlign) {
  104. case TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL:
  105. textCenterX = (float)viewWidth / 2;
  106. textBaselineY = textCenterVerticalBaselineY;
  107. break;
  108. case TEXT_ALIGN_LEFT | TEXT_ALIGN_CENTER_VERTICAL:
  109. textCenterX = textWidth / 2;
  110. textBaselineY = textCenterVerticalBaselineY;
  111. break;
  112. case TEXT_ALIGN_RIGHT | TEXT_ALIGN_CENTER_VERTICAL:
  113. textCenterX = viewWidth - textWidth / 2;
  114. textBaselineY = textCenterVerticalBaselineY;
  115. break;
  116. case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_CENTER_HORIZONTAL:
  117. textCenterX = viewWidth / 2;
  118. textBaselineY = viewHeight - fm.bottom;
  119. break;
  120. case TEXT_ALIGN_TOP | TEXT_ALIGN_CENTER_HORIZONTAL:
  121. textCenterX = viewWidth / 2;
  122. textBaselineY = -fm.ascent;
  123. break;
  124. case TEXT_ALIGN_TOP | TEXT_ALIGN_LEFT:
  125. textCenterX = textWidth / 2;
  126. textBaselineY = -fm.ascent;
  127. break;
  128. case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_LEFT:
  129. textCenterX = textWidth / 2;
  130. textBaselineY = viewHeight - fm.bottom;
  131. break;
  132. case TEXT_ALIGN_TOP | TEXT_ALIGN_RIGHT:
  133. textCenterX = viewWidth - textWidth / 2;
  134. textBaselineY = -fm.ascent;
  135. break;
  136. case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_RIGHT:
  137. textCenterX = viewWidth - textWidth / 2;
  138. textBaselineY = viewHeight - fm.bottom;
  139. break;
  140. }
  141. }
  142. /**
  143. * 设置文本内容
  144. * @param text
  145. */
  146. public void setText(String text) {
  147. this.text = text;
  148. invalidate();
  149. }
  150. /**
  151. * 设置文本大小
  152. * @param textSizeSp 文本大小,单位是sp
  153. */
  154. public void setTextSize(int textSizeSp) {
  155. DisplayParams displayParams = DisplayParams.getInstance(context);
  156. this.textSize = DisplayUtil.sp2px(textSizeSp, displayParams.fontScale);
  157. invalidate();
  158. }
  159. /**
  160. * 设置文本的方位
  161. */
  162. public void setTextAlign(int textAlign) {
  163. this.textAlign = textAlign;
  164. invalidate();
  165. }
  166. /**
  167. * 设置文本的颜色
  168. * @param textColor
  169. */
  170. public void setTextColor(int textColor) {
  171. this.textColor = textColor;
  172. invalidate();
  173. }
  174. }
  1. //MainActivity.java
  2. package com.example.textalignment;
  3. import com.example.textalignment.mytextview.MyTextView;
  4. import com.example.textalignment.util.DisplayParams;
  5. import com.example.textalignment.util.DisplayUtil;
  6. import android.os.Bundle;
  7. import android.app.Activity;
  8. import android.graphics.Bitmap;
  9. import android.graphics.BitmapFactory;
  10. import android.graphics.Color;
  11. import android.view.Menu;
  12. import android.widget.LinearLayout;
  13. import android.widget.ScrollView;
  14. public class MainActivity extends Activity {
  15. @Override
  16. protected void onCreate(Bundle savedInstanceState) {
  17. super.onCreate(savedInstanceState);
  18. setContentView(R.layout.activity_main);
  19. DisplayParams displayParams = DisplayParams.getInstance(this);
  20. LinearLayout container = (LinearLayout) findViewById(R.id.container);
  21. MyTextView myTextView1 = new MyTextView(this);
  22. myTextView1.setText("居中的文本");
  23. myTextView1.setTextSize(30);
  24. myTextView1.setTextAlign(MyTextView.TEXT_ALIGN_CENTER_HORIZONTAL | MyTextView.TEXT_ALIGN_CENTER_VERTICAL);
  25. myTextView1.setTextColor(Color.BLUE);
  26. myTextView1.setBackgroundColor(Color.RED);
  27. container.addView(myTextView1, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  28. MyTextView myTextView2 = new MyTextView(this);
  29. myTextView2.setText("居左的文本");
  30. myTextView2.setTextSize(25);
  31. myTextView2.setTextAlign(MyTextView.TEXT_ALIGN_CENTER_VERTICAL | MyTextView.TEXT_ALIGN_LEFT);
  32. myTextView2.setTextColor(Color.GREEN);
  33. myTextView2.setBackgroundColor(Color.YELLOW);
  34. container.addView(myTextView2, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  35. MyTextView myTextView3 = new MyTextView(this);
  36. myTextView3.setText("右下的文本");
  37. myTextView3.setTextSize(15);
  38. myTextView3.setTextAlign(MyTextView.TEXT_ALIGN_BOTTOM | MyTextView.TEXT_ALIGN_RIGHT);
  39. myTextView3.setTextColor(Color.RED);
  40. myTextView3.setBackgroundColor(Color.BLUE);
  41. container.addView(myTextView3, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  42. MyTextView myTextView4 = new MyTextView(this);
  43. myTextView4.setText("左下的文本");
  44. myTextView4.setTextSize(15);
  45. myTextView4.setTextAlign(MyTextView.TEXT_ALIGN_BOTTOM | MyTextView.TEXT_ALIGN_LEFT);
  46. myTextView4.setTextColor(Color.YELLOW);
  47. myTextView4.setBackgroundColor(Color.GREEN);
  48. container.addView(myTextView4, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  49. MyTextView myTextView5 = new MyTextView(this);
  50. myTextView5.setText("中下的文本");
  51. myTextView5.setTextSize(35);
  52. myTextView5.setTextAlign(MyTextView.TEXT_ALIGN_BOTTOM | MyTextView.TEXT_ALIGN_CENTER_HORIZONTAL);
  53. myTextView5.setTextColor(Color.GRAY);
  54. myTextView5.setBackgroundColor(Color.RED);
  55. container.addView(myTextView5, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  56. MyTextView myTextView6 = new MyTextView(this);
  57. myTextView6.setText("居右的文本");
  58. myTextView6.setTextSize(25);
  59. myTextView6.setTextAlign(MyTextView.TEXT_ALIGN_RIGHT | MyTextView.TEXT_ALIGN_CENTER_VERTICAL);
  60. myTextView6.setTextColor(Color.BLUE);
  61. myTextView6.setBackgroundColor(Color.YELLOW);
  62. container.addView(myTextView6, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  63. MyTextView myTextView7 = new MyTextView(this);
  64. myTextView7.setText("左上的文本");
  65. myTextView7.setTextSize(25);
  66. myTextView7.setTextAlign(MyTextView.TEXT_ALIGN_TOP | MyTextView.TEXT_ALIGN_LEFT);
  67. myTextView7.setTextColor(Color.GREEN);
  68. myTextView7.setBackgroundColor(Color.CYAN);
  69. container.addView(myTextView7, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  70. MyTextView myTextView8 = new MyTextView(this);
  71. myTextView8.setText("中上的文本");
  72. myTextView8.setTextSize(25);
  73. myTextView8.setTextAlign(MyTextView.TEXT_ALIGN_TOP | MyTextView.TEXT_ALIGN_CENTER_HORIZONTAL);
  74. myTextView8.setTextColor(Color.RED);
  75. myTextView8.setBackgroundColor(Color.GREEN);
  76. container.addView(myTextView8, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  77. MyTextView myTextView9 = new MyTextView(this);
  78. myTextView9.setText("右上的文本");
  79. myTextView9.setTextSize(25);
  80. myTextView9.setTextAlign(MyTextView.TEXT_ALIGN_TOP | MyTextView.TEXT_ALIGN_RIGHT);
  81. myTextView9.setTextColor(Color.YELLOW);
  82. myTextView9.setBackgroundColor(Color.BLUE);
  83. container.addView(myTextView9, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));
  84. }
  85. }
  1. activity_main.xml
  2. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. android:layout_width="match_parent"
  5. android:layout_height="match_parent"
  6. android:paddingBottom="@dimen/activity_vertical_margin"
  7. android:paddingLeft="@dimen/activity_horizontal_margin"
  8. android:paddingRight="@dimen/activity_horizontal_margin"
  9. android:paddingTop="@dimen/activity_vertical_margin"
  10. tools:context=".MainActivity" >
  11. <LinearLayout
  12. android:id="@+id/container"
  13. android:layout_width="match_parent"
  14. android:layout_height="wrap_content"
  15. android:orientation="vertical"/>
  16. </ScrollView>

还用到了两个工具类,代码可以参考这篇文章http://blog.csdn.net/carrey1989/article/details/10360613 
在进行垂直偏上和垂直偏下的设置时,关键是设置baseline的y坐标分别等于-fm.ascent和viewHeight - fm.bottom,意思就是可以让文字刚好不超过控件的边缘。

Android中获取文本宽度和高度相关推荐

  1. android中控制ListView宽度和高度

    ============问题描述============ 给listveiw填充item布局都是wrap_content,listview自身也使用wrap_content,可是实际显示效果listv ...

  2. Android中获取屏幕信息的几种方式

    Android中获取屏幕信息的几种方式 方案一 方案二 方案三 Note:以下方案中的this均指Activity. 方案一 WindowManager wm = (WindowManager) th ...

  3. 显示android 运行时异常,在android中获取运行时异常

    我做了一个简单的android应用程序,从一个活动移动到另一个活动,长度为5个编辑文本输入.但我得到了例外.我附加了两个java文件(MainActicity和Another),mainfest文件和 ...

  4. html怎么获取设备宽度,css - 在javascript中获取设备宽度

    css - 在javascript中获取设备宽度 有没有办法使用javascript获取用户设备宽度,而不是视口宽度? 正如我所说,CSS媒体查询提供了这一点 @media screen and (m ...

  5. Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用

    关于PackageManager和ActivityManager的使用 ,自己也写了一些DEMO 了,基本上写的线路参考了Settings模块下的 应用程序,大家如果真正的有所兴趣,建议大家看看源码, ...

  6. Android中获取网络图片的三种方法

    android中获取网络图片是一件耗时的操作,如果直接获取有可能会出现应用程序无响应(ANR:Application Not Responding)对话框的情况.对于这种情况,一般的方法就是耗时操作用 ...

  7. android中获取时间

    android中获取时间 1)通过calendar类获取 Calendar calendar = Calendar.getInstance(); int moth = calendar.get(Cal ...

  8. android中获取应用程序(包)的信息,Android中获取应用程序(包)的信息PackageManager的使用(一).doc...

    Android中获取应用程序(包)的信息PackageManager的使用(一) 本节内容是如何获取Android系统中应用程序的信息,主要包括packagename.label.icon.占用大小等 ...

  9. android获取运行应用程序,Android中获取正在运行的应用程序

    Android中获取正在运行的应用程序 ActivityMain.java 1.public class ActivityMain extends ListActivity { 2. @Overrid ...

最新文章

  1. [javascript]JS获取当前时间戳的方法
  2. 树莓派AI视觉云台——8、WiringPi库函数
  3. Oracle client 安装、配置
  4. 黑客泄露50多万服务器、路由器和物联网设备的密码
  5. USACO Sorting a Three-Valued Sequence
  6. Splice Beatmaker for Mac(音乐节拍工具)
  7. JDK 8和Java 8的下载与安装
  8. SPSS26版本软件超详细安装指导+内附安装资源
  9. python编辑视频教程_Maya中Python编辑基础核心技术训练视频教程
  10. vue js 前端实现PDF文件下载的三种方式 解决vue下载pdf文件打开文件后空白
  11. python 快乐数判断_利用Python实现MACD顶底背离形态,并实现自动化交易!
  12. 湖人控卫鲍尔左脚踝三级扭伤 预计缺席4-6周
  13. 正定子龙大桥正式开工建设
  14. SyntaxError: invalid syntax(遇到问题)(已解决)
  15. cad.net 利用win32api实现一个命令开关参照面板
  16. Stream流的具体使用讲解
  17. Android Intent之传递带有对象的集合(Serializable传递对象和对象集合)
  18. Flink Table和SQL的表和视图、Connectors和timestamp数据类型
  19. 52单片机设计时钟(串口控制)
  20. 基于51单片机的智能光控路灯设计及设计报告

热门文章

  1. 用malloc动态申请一个二维数组的三种方法
  2. 前端基础——数组的方法
  3. JAVA javaweb JSP水果管理系统源码(水果进销存管理系统水果管理系统(水果进销存)
  4. python从TXT导入两列数据绘图 直线多点等分坐标可视化
  5. 怎么用计算机弹心如水止,心静如水, 怎样用心看自己
  6. 在线AI日语视频音频翻译中文字幕
  7. 铁流:苹果为何不找IBM,而选择中国浪潮
  8. pyqt QLineEdit 详细用法
  9. 服务器硬盘可以换盘位吗,RAID里的硬盘可以互换槽位吗
  10. MongoDB学习(二)MongoDB 认证详解