Android UI 之居中绘制文本内容的正确方法——实现自定义一个TextView

2023-11-09

原文地址 http://blog.csdn.net/carrey1989/article/details/10399727   


我们在自定义一个控件的时候,有时候会需要自己来绘制一些文本内容,这样就自然而然遇到确定文本的方位的问题,比如文本需要水平居中,垂直居中,居左,居右,左上。。。等等很多情况。其中最常见的就是文本位于控件的正中央了。

    既然是文本居中,那就要让文本水平居中,并且同时垂直居中,我们分开来做。

    水平居中的思路很简单,一种是得到控件的宽度A,使得文本的中心位置x坐标=A/2就可以了。还有一种思路是我们得到控件的宽度A,然后测量出要绘制的文本的宽度B,然后使得文本的左端x坐标=(A-B)/2。

    相对复杂一点的实现文本垂直居中,我们需要用到FontMetrics,这里涉及到几个概念,分别是文本的top,bottom,ascent,descent,baseline。看下面的图:


    我们在画布中绘制文本的时候,会调用Canvas.drawText(String text, float x, float y, Paint paint)这个方法,其中y的坐标就是上图中baseline的y坐标,所以,如果我们只是简单地把drawText方法中的y设置为控件高度的1/2是不准确的,如果这样做的话会发现文本整体是位于画布的上半部分的,因为baseline下面的文本部分是很小的。

    正确的做法是通过一些合理的换算使得文本的y坐标(baseline的y坐标)位于控件的下半部分区域。下面是我自己通过计算和测试得到的准确换算关系:

[java]  view plain copy
  1. 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。

    先来看一下效果图:


项目代码:

MyTextView.java

[java]  view plain copy
  1. package com.example.textalignment.mytextview;  
  2.   
  3. import com.example.textalignment.util.DisplayParams;  
  4. import com.example.textalignment.util.DisplayUtil;  
  5.   
  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.     /** 要显示的文字 */  
  31.     private String text;  
  32.     /** 文字的颜色 */  
  33.     private int textColor;  
  34.     /** 文字的大小 */  
  35.     private int textSize;  
  36.     /** 文字的方位 */  
  37.     private int textAlign;  
  38.       
  39. //  public static final int TEXT_ALIGN_CENTER            = 0x00000000;  
  40.     public static final int TEXT_ALIGN_LEFT              = 0x00000001;  
  41.     public static final int TEXT_ALIGN_RIGHT             = 0x00000010;  
  42.     public static final int TEXT_ALIGN_CENTER_VERTICAL   = 0x00000100;  
  43.     public static final int TEXT_ALIGN_CENTER_HORIZONTAL = 0x00001000;  
  44.     public static final int TEXT_ALIGN_TOP               = 0x00010000;  
  45.     public static final int TEXT_ALIGN_BOTTOM            = 0x00100000;  
  46.       
  47.     /** 文本中轴线X坐标 */  
  48.     private float textCenterX;  
  49.     /** 文本baseline线Y坐标 */  
  50.     private float textBaselineY;  
  51.       
  52.     /** 控件的宽度 */  
  53.     private int viewWidth;  
  54.     /** 控件的高度 */  
  55.     private int viewHeight;  
  56.     /** 控件画笔 */  
  57.     private Paint paint;  
  58.       
  59.     private FontMetrics fm;  
  60.     /** 场景 */  
  61.     private Context context;  
  62.       
  63.     public MyTextView(Context context) {  
  64.         super(context);  
  65.         this.context = context;  
  66.         init();  
  67.     }  
  68.   
  69.     public MyTextView(Context context, AttributeSet attrs) {  
  70.         super(context, attrs);  
  71.         this.context = context;  
  72.         init();  
  73.     }  
  74.   
  75.     /** 
  76.      * 变量初始化 
  77.      */  
  78.     private void init() {  
  79.         paint = new Paint();  
  80.         paint.setAntiAlias(true);  
  81.         paint.setTextAlign(Align.CENTER);  
  82.         //默认情况下文字居中显示  
  83.         textAlign = TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL;  
  84.         //默认的文本颜色是黑色  
  85.         this.textColor = Color.BLACK;  
  86.     }  
  87.       
  88.     @Override  
  89.     protected void onLayout(boolean changed, int left, int top, int right,  
  90.             int bottom) {  
  91.         viewWidth = getWidth();  
  92.         viewHeight = getHeight();  
  93.         super.onLayout(changed, left, top, right, bottom);  
  94.     }  
  95.       
  96.     @Override  
  97.     protected void onDraw(Canvas canvas) {  
  98.         //绘制控件内容  
  99.         setTextLocation();  
  100.         canvas.drawText(text, textCenterX, textBaselineY, paint);  
  101.         super.onDraw(canvas);  
  102.     }  
  103.       
  104.     /** 
  105.      * 定位文本绘制的位置 
  106.      */  
  107.     private void setTextLocation() {  
  108.         paint.setTextSize(textSize);  
  109.         paint.setColor(textColor);  
  110.         fm = paint.getFontMetrics();  
  111.         //文本的宽度  
  112.         float textWidth = paint.measureText(text);  
  113.         float textCenterVerticalBaselineY = viewHeight / 2 - fm.descent + (fm.descent - fm.ascent) / 2;  
  114.         switch (textAlign) {  
  115.         case TEXT_ALIGN_CENTER_HORIZONTAL | TEXT_ALIGN_CENTER_VERTICAL:  
  116.             textCenterX = (float)viewWidth / 2;  
  117.             textBaselineY = textCenterVerticalBaselineY;  
  118.             break;  
  119.         case TEXT_ALIGN_LEFT | TEXT_ALIGN_CENTER_VERTICAL:  
  120.             textCenterX = textWidth / 2;  
  121.             textBaselineY = textCenterVerticalBaselineY;  
  122.             break;  
  123.         case TEXT_ALIGN_RIGHT | TEXT_ALIGN_CENTER_VERTICAL:  
  124.             textCenterX = viewWidth - textWidth / 2;  
  125.             textBaselineY = textCenterVerticalBaselineY;  
  126.             break;  
  127.         case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_CENTER_HORIZONTAL:  
  128.             textCenterX = viewWidth / 2;  
  129.             textBaselineY = viewHeight - fm.bottom;   
  130.             break;  
  131.         case TEXT_ALIGN_TOP | TEXT_ALIGN_CENTER_HORIZONTAL:  
  132.             textCenterX = viewWidth / 2;  
  133.             textBaselineY = -fm.ascent;  
  134.             break;  
  135.         case TEXT_ALIGN_TOP | TEXT_ALIGN_LEFT:  
  136.             textCenterX = textWidth / 2;  
  137.             textBaselineY = -fm.ascent;  
  138.             break;  
  139.         case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_LEFT:  
  140.             textCenterX = textWidth / 2;  
  141.             textBaselineY = viewHeight - fm.bottom;   
  142.             break;  
  143.         case TEXT_ALIGN_TOP | TEXT_ALIGN_RIGHT:  
  144.             textCenterX = viewWidth - textWidth / 2;  
  145.             textBaselineY = -fm.ascent;  
  146.             break;  
  147.         case TEXT_ALIGN_BOTTOM | TEXT_ALIGN_RIGHT:  
  148.             textCenterX = viewWidth - textWidth / 2;  
  149.             textBaselineY = viewHeight - fm.bottom;   
  150.             break;  
  151.         }  
  152.     }  
  153.       
  154.     /** 
  155.      * 设置文本内容 
  156.      * @param text 
  157.      */  
  158.     public void setText(String text) {  
  159.         this.text = text;  
  160.         invalidate();  
  161.     }  
  162.     /** 
  163.      * 设置文本大小 
  164.      * @param textSizeSp 文本大小,单位是sp 
  165.      */  
  166.     public void setTextSize(int textSizeSp) {  
  167.         DisplayParams displayParams = DisplayParams.getInstance(context);  
  168.         this.textSize = DisplayUtil.sp2px(textSizeSp, displayParams.fontScale);  
  169.         invalidate();  
  170.     }  
  171.     /** 
  172.      * 设置文本的方位 
  173.      */  
  174.     public void setTextAlign(int textAlign) {  
  175.         this.textAlign = textAlign;  
  176.         invalidate();  
  177.     }  
  178.     /** 
  179.      * 设置文本的颜色 
  180.      * @param textColor 
  181.      */  
  182.     public void setTextColor(int textColor) {  
  183.         this.textColor = textColor;  
  184.         invalidate();  
  185.     }  
  186. }  
MainActivity.java

[java]  view plain copy
  1. package com.example.textalignment;  
  2.   
  3. import com.example.textalignment.mytextview.MyTextView;  
  4. import com.example.textalignment.util.DisplayParams;  
  5. import com.example.textalignment.util.DisplayUtil;  
  6.   
  7. import android.os.Bundle;  
  8. import android.app.Activity;  
  9. import android.graphics.Bitmap;  
  10. import android.graphics.BitmapFactory;  
  11. import android.graphics.Color;  
  12. import android.view.Menu;  
  13. import android.widget.LinearLayout;  
  14. import android.widget.ScrollView;  
  15.   
  16. public class MainActivity extends Activity {  
  17.   
  18.     @Override  
  19.     protected void onCreate(Bundle savedInstanceState) {  
  20.         super.onCreate(savedInstanceState);  
  21.         setContentView(R.layout.activity_main);  
  22.           
  23.         DisplayParams displayParams = DisplayParams.getInstance(this);  
  24.           
  25.         LinearLayout container = (LinearLayout) findViewById(R.id.container);  
  26.           
  27.         MyTextView myTextView1 = new MyTextView(this);  
  28.         myTextView1.setText("居中的文本");  
  29.         myTextView1.setTextSize(30);  
  30.         myTextView1.setTextAlign(MyTextView.TEXT_ALIGN_CENTER_HORIZONTAL | MyTextView.TEXT_ALIGN_CENTER_VERTICAL);  
  31.         myTextView1.setTextColor(Color.BLUE);  
  32.         myTextView1.setBackgroundColor(Color.RED);  
  33.         container.addView(myTextView1, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  34.           
  35.         MyTextView myTextView2 = new MyTextView(this);  
  36.         myTextView2.setText("居左的文本");  
  37.         myTextView2.setTextSize(25);  
  38.         myTextView2.setTextAlign(MyTextView.TEXT_ALIGN_CENTER_VERTICAL | MyTextView.TEXT_ALIGN_LEFT);  
  39.         myTextView2.setTextColor(Color.GREEN);  
  40.         myTextView2.setBackgroundColor(Color.YELLOW);  
  41.         container.addView(myTextView2, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  42.           
  43.         MyTextView myTextView3 = new MyTextView(this);  
  44.         myTextView3.setText("右下的文本");  
  45.         myTextView3.setTextSize(15);  
  46.         myTextView3.setTextAlign(MyTextView.TEXT_ALIGN_BOTTOM | MyTextView.TEXT_ALIGN_RIGHT);  
  47.         myTextView3.setTextColor(Color.RED);  
  48.         myTextView3.setBackgroundColor(Color.BLUE);  
  49.         container.addView(myTextView3, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  50.           
  51.         MyTextView myTextView4 = new MyTextView(this);  
  52.         myTextView4.setText("左下的文本");  
  53.         myTextView4.setTextSize(15);  
  54.         myTextView4.setTextAlign(MyTextView.TEXT_ALIGN_BOTTOM | MyTextView.TEXT_ALIGN_LEFT);  
  55.         myTextView4.setTextColor(Color.YELLOW);  
  56.         myTextView4.setBackgroundColor(Color.GREEN);  
  57.         container.addView(myTextView4, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  58.           
  59.         MyTextView myTextView5 = new MyTextView(this);  
  60.         myTextView5.setText("中下的文本");  
  61.         myTextView5.setTextSize(35);  
  62.         myTextView5.setTextAlign(MyTextView.TEXT_ALIGN_BOTTOM | MyTextView.TEXT_ALIGN_CENTER_HORIZONTAL);  
  63.         myTextView5.setTextColor(Color.GRAY);  
  64.         myTextView5.setBackgroundColor(Color.RED);  
  65.         container.addView(myTextView5, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  66.           
  67.         MyTextView myTextView6 = new MyTextView(this);  
  68.         myTextView6.setText("居右的文本");  
  69.         myTextView6.setTextSize(25);  
  70.         myTextView6.setTextAlign(MyTextView.TEXT_ALIGN_RIGHT | MyTextView.TEXT_ALIGN_CENTER_VERTICAL);  
  71.         myTextView6.setTextColor(Color.BLUE);  
  72.         myTextView6.setBackgroundColor(Color.YELLOW);  
  73.         container.addView(myTextView6, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  74.           
  75.         MyTextView myTextView7 = new MyTextView(this);  
  76.         myTextView7.setText("左上的文本");  
  77.         myTextView7.setTextSize(25);  
  78.         myTextView7.setTextAlign(MyTextView.TEXT_ALIGN_TOP | MyTextView.TEXT_ALIGN_LEFT);  
  79.         myTextView7.setTextColor(Color.GREEN);  
  80.         myTextView7.setBackgroundColor(Color.CYAN);  
  81.         container.addView(myTextView7, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  82.           
  83.         MyTextView myTextView8 = new MyTextView(this);  
  84.         myTextView8.setText("中上的文本");  
  85.         myTextView8.setTextSize(25);  
  86.         myTextView8.setTextAlign(MyTextView.TEXT_ALIGN_TOP | MyTextView.TEXT_ALIGN_CENTER_HORIZONTAL);  
  87.         myTextView8.setTextColor(Color.RED);  
  88.         myTextView8.setBackgroundColor(Color.GREEN);  
  89.         container.addView(myTextView8, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  90.           
  91.         MyTextView myTextView9 = new MyTextView(this);  
  92.         myTextView9.setText("右上的文本");  
  93.         myTextView9.setTextSize(25);  
  94.         myTextView9.setTextAlign(MyTextView.TEXT_ALIGN_TOP | MyTextView.TEXT_ALIGN_RIGHT);  
  95.         myTextView9.setTextColor(Color.YELLOW);  
  96.         myTextView9.setBackgroundColor(Color.BLUE);  
  97.         container.addView(myTextView9, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtil.dip2px(150, displayParams.scale));  
  98.           
  99.     }  
  100. }  
activity_main.xml
[html]  view plain copy
  1. <ScrollView xmlns:android="http://schemas.android.com/apk/res/android"  
  2.     xmlns:tools="http://schemas.android.com/tools"  
  3.     android:layout_width="match_parent"  
  4.     android:layout_height="match_parent"  
  5.     android:paddingBottom="@dimen/activity_vertical_margin"  
  6.     android:paddingLeft="@dimen/activity_horizontal_margin"  
  7.     android:paddingRight="@dimen/activity_horizontal_margin"  
  8.     android:paddingTop="@dimen/activity_vertical_margin"  
  9.     tools:context=".MainActivity" >  
  10.   
  11.     <LinearLayout   
  12.         android:id="@+id/container"  
  13.         android:layout_width="match_parent"  
  14.         android:layout_height="wrap_content"  
  15.         android:orientation="vertical"/>  
  16.   
  17. </ScrollView>  
另外,还用到了两个工具类,代码可以参考这篇文章http://blog.csdn.net/carrey1989/article/details/10360613

在进行垂直偏上和垂直偏下的设置时,关键是设置baseline的y坐标分别等于-fm.ascent和viewHeight - fm.bottom,意思就是可以让文字刚好不超过控件的边缘。

整体思路就是这样,如需转载,请注明转载地址http://blog.csdn.net/carrey1989/article/details/10399727


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Android UI 之居中绘制文本内容的正确方法——实现自定义一个TextView 的相关文章

  • 将“R.id.myID”从字符串转换为 int 值 R.id.myID?

    我的观点上的文字代表一个ID 因此 当单击时 我想获得对该资源的引用 以下不正确的代码代表了我想要做的事情 public void onCreate Bundle savedInstanceState super onCreate save
  • 处理 SavedInstances 并恢复活动

    基本上我的应用程序有 2 个活动 说 A 和 B A 启动 B Activity B 播放音乐并且还有通知 情况 1 当视图仍在活动 B 上时 我按主页按钮 然后单击通知 活动 B 将打开 其视图完好无损并播放音乐 因为在清单中我使用 an
  • animation.start() 或animation.startNow() 不会立即开始动画

    我有一个奇怪的问题 有时应该淡出我的控件 ImageButton 的动画不会立即启动 我使用淡出动画来隐藏它 然后在 myListener 的末尾 onAnimationEnd 中 我将新资源作为按钮上的图像 我的应用程序代码中的某处 An
  • 在android Gridview中合并行和列

    我正在android中做一个图像查看页面 我需要在某些地方合并行 在某些地方合并列 我们可以在gridview中做到这一点吗 如果我们选择任何合并图像 则应选择整个图像视图 请任何人告诉我一个建议 提前致谢 Try 非对称网格视图 http
  • 通过模拟器控制台或 ADB 更改 Android 模拟器方向

    我正在尝试构建一个自动化测试框架 用于检查应用程序应该响应的基本内容 而不会崩溃 其中之一是检查应用程序是否正确响应配置更改 现在 由于它是自动化的 我必须以编程方式在横向和纵向之间切换模拟器的方向 并观察它是否崩溃 大写 因为有很多与 c
  • 获取Android库中的上下文

    我正在编写一个 Android 应用程序 它的一些功能封装在内部库中 但是 要使此功能发挥作用 库需要一个应用程序上下文的实例 为图书馆提供这种上下文的最佳方式是什么 我看到了一些选择 但没有一个有吸引力 Have my library c
  • 使用全局变量从内部函数获取空字符串

    请帮助我解决一些小问题 我确信你能做到 D 我试图在 firestore 文档 user cases information 上设置一个字段 其中包含一个字段 case number 首先我声明这个全局变量 private String c
  • webview 中的 android 移动 Twitter 页面无法打开?

    我正在尝试打开以 https 开头的 Twitter 页面webview在安卓中 但它没有打开 并且持续加载时出现黑屏 屏幕截图如下 Edit 在主网络视图中我有 Twitter 页面的链接https twitter com mytwitt
  • RxJava android mvp 单元测试 NullPointerException

    我是 mvp 单元测试的新手 我想对演示者进行一个非常基本的测试 它负责登录 我只想断言 view onLoginSuccess 这是演示者代码 public LoginPresenter LoginViewContract loginVi
  • 如何告诉 OkHttpClient 忽略缓存并强制从服务器刷新?

    在我的 Android 应用程序中 我将 Retrofit 与 OkHttpClient 结合使用 并启用缓存来访问某些 API 我们的一些 API 有时会返回空数据 我们在应用程序中提供了一个 刷新 按钮 供客户端从特定 API 重新加载
  • Android 导航组件 - 从“任何地方”/基本片段导航?

    我正在开发一个应用程序 它有一个奇怪的花招 可以在设备旋转时打开特定的片段 在实现 android 的导航组件之前 所需要的只是对当前活动的引用 并且可以在特定时刻向用户显示的任何内容之上执行手动片段事务 但是在转移到导航组件之后 我发现很
  • 如何在 LazyColumn 底部添加空白区域?

    我想添加 LazyColumn 的空白底部 并且我想允许用户调出底部元素 我怎样才能实现这个 Example LazyColumn modifier Modifier fillMaxWidth height 300 dp border 2
  • Proguard 正在破坏我的清洁度。 Gson 和泛型

    我有一个从持久性加载信息的函数 我只是以一种非常简单的方式告诉它的类型 该类称为SharedPreferencesHelper kt所以它是一个真正的生活问题解决者 fun
  • 以编程方式创建 FloatingActionButton(无需 xml)

    我很欣赏 Android 的 FloatingActionButton fab 功能 并希望在我的项目中的许多不同地方使用它们 现在 我有这样的东西 我有几个 xml 规范 除了 id 图标和 onclick 之外 所有这些规范都是相同的
  • Android Studio - 无法解析符号“firebase”

    我目前正在将应用程序升级到新的 Firebase 版本 我按照指南进行操作 包括classpath com google gms google services 3 0 0 在我的项目 build gradle 的依赖项中以及compile
  • Firebase:用户注册后如何进行电话号码验证?

    所以我知道我可以使用电子邮件验证或电话号码验证 但我想做的是在用户注册或登录后进行电话号码验证 如何连接这两种身份验证方法 最后 Firebase中是否有一个函数可以检查用户是否通过电话号码验证 谢谢 即使用户已通过身份验证 您仍然可以使用
  • 如何在android中将文本放在单选按钮的左侧

    我想将单选按钮的文本放在左侧而不是右侧 我找到了这个解决方案
  • 永久删除Android文件

    我发现了一个名为这会从 Android 设备中永久删除文件和文件夹 以便删除的文件无法再恢复 这是我正在谈论的应用程序 但我想知道如何做到这一点 我知道它是用 android studio 制作的 i尝试了常规的删除方式file delet
  • 连接到具有相同 SSID 的最强接入点(信号最强的接入点)

    我正在编写一个程序来始终连接到最强的接入点 我的意思是信号最强的接入点 首先 我扫描所有可用的 WiFi 网络 然后限制它们仅查看具有相同 SSID 的网络 这样我就可以看到一个网络的所有AP 当我连接到该网络时 它没有连接到最强的信号 但
  • (Unity 中的 Firebase 数据库)在 Android 构建期间在 Temp 中缺少classes.jar

    I am using Firebase Database in my Unity project but I am having some issues when building the project for android It ru

随机推荐

  • vscode中preLaunchTask“g++”已终止,退出代码为1的解决方案

    问题背景 楼主原来做的项目 电脑中装了MinGW64 还有MinGW的32位版在用vscode时发现出现了 preLaunchTask g 已终止 退出代码为1的问题 找了好久 解决了问题 launch json 注释的位置 这里修改GDB
  • Vue中实现放大镜效果

    先来看一下我们需要实现的效果是怎样的 这里我们没有使用原生的 js 方法去实现 而是使用的 Vue3 官方推荐的一个工具库 vueuse cor 中的 useMouseInElement 方法来实现放大镜的效果 首先来看一下 useMous
  • 如何安装和配置树莓派

    如何安装和配置树莓派 如果你有一块树莓派的板子 还有一个没安装系统的SD卡 怎么能把系统装上 配置好跑起来 这篇文章主要就讲这个事 这是一块Raspberry Pi Zero W板 以及一个空SD卡 当然 我们需要一个SD卡读卡器 还需要一
  • Flink Native Kubernetes (一)

    目录 文章目录 目录 概述 Linux 集群描述 版本 部署K8S环境 配置Yum 安装docker 安装Rancher 安装K8s 工作集群 添加KubeCtl命令上下文 运行FlinkDemo FlinkSession关于K8s的基础环
  • 三:Sensor SLPI层代码分析---

    三 Sensor SLPI层代码分析 在学习SLPI侧代码前我们先了解下SEE的registry config registry 放在 persist sensors registry registry中 它是通过config生成的 是给S
  • 循环遍历本地的图片使用BASE64编码,并在ajax也遍历图片

    前端调用ajax到后端去图片的方法 并返回 public void search HttpServletRequest request HttpServletResponse response throws Exception String
  • 【毕业设计】基于stm32的智能扫地机器人设计与实现 - 单片机 物联网

    文章目录 0 简介 1 课题背景 2 硬件系统总体框架 2 1 电机驱动 2 2 红外线传感器 2 3 超声波传感器 2 4 MPU6050 2 5 ATK ESP8266 WI FI 模块 2 6 电源管理模块 3 软件系统设计 3 1
  • 前端知识点

    写在前面 CSDN话题挑战赛第1期 活动详情地址 CSDN 参赛话题 前端面试宝典 话题描述 欢迎各位加入话题创作得小伙伴 如果我没有猜错得话 我觉得你是应该同我一样是一位前端人 如今前端在IT事业中的占比越来越重 已经成为不可缺少的部分
  • 2019年DNS服务器速度排行榜

    第一名 DNSPod 不得不说腾讯自从收购了DNSPod后 无论是服务还是速度都有显著的提升 无论是访问速度还是解析速度都在国内是处于龙头大哥的地位 昔日的老大114的地位已经不保 作为腾讯旗下的公司 在游戏解析这一块来说 技术自然是领先于
  • 排序算法详解(堆,归并,快速排序最简及理解写法)

    十大排序算法和复杂度 常见排序的详解 只讲解真实场景中常用的 简单的就不分析了大家稍微看一下就行 快速排序 快排的思想主要就是每次把一个位置放好后 可以把数组分成两半 递归处理子问题即可 空间复杂度OlogN 分析 每次都分成两半处理子问题
  • IDEA报错程序包xxx不存在,但Depandencies依赖里明明有

    IDEA报错程序包xxx不存在 但依赖里明明有 看一下这个项目的pom xml 我这边引用的是公共依赖 应该是运行的时候依赖没有引用过来 搞了半天 网上搜了很多没搜到 后来我把 settings gt Runner 设置调了一下 就没有问题
  • CUDA之Warp Shuffle详解

    之前我们有介绍shared Memory对于提高性能的好处 在CC3 0以上 支持了shuffle指令 允许thread直接读其他thread的寄存器值 只要两个thread在 同一个warp中 这种比通过shared Memory进行th
  • Zabbix 学习(六) 自动发现功能与主动监控的实现

    一 自动发现 当被监控的设备非常多的时候 手工添加将会变得非常不方便 可以使用自动发现功能 实现添加主机 添加到主机组 链接模板 自动发现流程 创建自动发现规则 创建动作 当主机被发现之后 执行什么操作 通过动作 添加主机 将模板应用到发现
  • qt 实现翻金币游戏

    游戏玩法介绍 游戏设置关卡二十关 通过选关界面可以选择进入到对应的关卡中 进入对应关卡之后 点击任意金币 可以使该硬币以及周边 上 下 左 右 金边翻转 如果硬币都翻转为金币 则游戏胜利 游戏界面设置 开始界面 开始场景中需要自定义一个按钮
  • MyBatis实现简单的增删查改操作(XML配置)

    最近在跟着B站传智的课程学习SSM 先学的是MyBatis 写一篇博客记录一下如何利用MyBatis实现简单的增删查改 主要是记录一下实现过程 实现思路 注意事项 避坑 本教程使用XML配置进行实现 一 软件环境 Java IDEA mys
  • Windows下,Hexo+GitHub搭建博客

    一 注册GitHub账号 二 创建GitHub仓库 创建git仓库时候 仓库的名称有格式要求 例如我的GitHub仓库用户名是thinkerwalker 那么我创建的仓库名称就是thinkerwalker github io 此处的警告是因
  • 2D人体姿态估计 - Convolutional Pose Machines(CPM)

    https github com namedBen Convolutional Pose Machines Pytorch https github com timctho convolutional pose machines tenso
  • QFileDialog打开文件夹,获得文件名(getOpenFileName,getExistingDirectory)

    1 QFileDialog getOpenFileName 示例 括号里的参数分别是 指定父类窗口部件 对话框使用的标题 默认打开后显示的目录 即告诉它从哪一级目录开始 右下角的文件过滤器 QString file name QFileDi
  • MongoDB复制集数据是如何复制的

    MongoDB 复制集 MongoDB复制集的主要意义在于实现服务高可用 类似于Redis中的哨兵模式 它主要提供两个方面的功能 1 数据写入主节点 Primary 时将数据复制到另一个副本节 Secondary 点上 2 主节点发生故障时
  • Android UI 之居中绘制文本内容的正确方法——实现自定义一个TextView

    原文地址 http blog csdn net carrey1989 article details 10399727 我们在自定义一个控件的时候 有时候会需要自己来绘制一些文本内容 这样就自然而然遇到确定文本的方位的问题 比如文本需要水平