使用Kotlin的Android TextView –全面教程
Kotlin是用于Android应用程序开发的官方编程语言。
在本教程中,我们将讨论使用Kotlin编程的Android应用程序中的TextView。
我们将在Kotlin编程中创建和更改TextViews代码。
Android TextView概述
Android TextView是View类的子类。
View类通常占据我们的窗口。
TextView用于在屏幕上显示文本。
我们可以使用TextView做很多花哨的事情。
让我们从Android Studio中的一个新项目开始。
创建一个新项目,并确保已在设置向导中启用Kotlin。
在XML布局中创建TextView
TextView以以下方式在xml布局中创建。
<TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello World!"
上面定义的四个属性是TextView小部件的核心属性。
id属性用于设置唯一标识符。
它设置为@ + id /
,后跟您分配的名称。
相同的名称将用于检索Kotlin Activity类中的TextView属性。text属性用于设置要在TextView中显示的字符串文本。
从名称本身可以明显看出,layout_width和layout_height用于设置TextView的边界。
wrap_content表示将宽度,高度包装为文本的长度。
match_parent表示TextView与封闭的父视图的宽度/高度匹配。
我们还可以设置dp(与设备无关的像素)中的硬编码值。
干净的代码提示:不用在字符串上进行硬编码,而是在strings.xml
中定义它,并按如下所示在布局中设置文本。
android:text="@string/app_name"
让我们在XML的TextView上应用一些属性。
TextView XML属性
让我们快速浏览一下TextView小部件的一些流行属性。
android:textSize
:设置TextView的大小。
建议使用sp而不是dp。
sp代表与比例无关的像素并缩放字体。
示例:16sp。android:textColor用于设置文本的颜色。
通常,其格式为#rgb,#rrggbb,#aarrggbb。android:background属性用于设置TextView的背景颜色。
android:textStyle用于设置粗体,斜体和普通样式。
如果要设置粗体和斜体,请使用android:textStyle =" bold | italic"。android:textAppearance属性用于在TextView上设置样式,该样式包括其自己的颜色,字体和大小。
我们可以在" styles.xml"文件中创建自定义样式。android:visibility用于设置文本的可视性,可能的值包括visible,invisible和goone。
"消失"使文本视图不可见,并将其从布局中的当前位置删除。android:ellipsize用于处理文本长度超过限制的情况。
当文本达到TextView的限制宽度时," end"会添加点。
"开始"在开始处添加点。
"选取框"用于使文本连续左右滑动以显示全文。android:onClick是Kotlin活动类中的方法名称,将在TextView点击时调用。
我们需要确保将此属性的android:clickable设置为true。android:typeface用于设置文本的字体。
android:drawableLeft用来设置TextView之外的drawable/mipmap图像或者矢量资源。
android:gravity用于设置文本相对于其尺寸的位置。
android:layout_margin用于设置TextView与布局中其他视图的间距。
layout_marginLeft,layout_marginRight,layout_marginTop,layout_marginBottom用于在各个面上设置边距。android:padding用于在TextView的四个侧面之间添加间距。
可能的值为paddingLeft,paddingRight,paddingTop和paddingBottom。
让我们在布局中的TextView上使用xml属性。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:id="@+id/linearLayout" android:orientation="vertical" tools:context="net.androidly.androidtextviewkotlin.MainActivity"> <TextView android:id="@+id/textViewEllipsize" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:ellipsize="end" android:maxLines="1" android:text="@string/long_string" android:textSize="18sp" <TextView android:id="@+id/textViewClickMe" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="8dp" android:background="@color/colorPrimaryDark" android:padding="@android:dimen/app_icon_size" android:shadowColor="@android:color/black" android:text="TextView Click Me" <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Android TextView Color" android:textAllCaps="true" android:textAppearance="?android:attr/textAppearanceLarge" android:textColor="#234568" android:textStyle="bold|italic" <TextView android:id="@+id/textViewOpacity" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:drawableLeft="@mipmap/ic_launcher" android:drawablePadding="16dp" android:gravity="center" android:text="Android TextView Opacity is 50 percent" android:textColor="#50234568" android:textSize="14sp" android:typeface="serif" </LinearLayout>
注意:为了方便起见,我们将ConstraintLayout替换为LinearLayout。
注意最后一个TextView中的不透明度
有关Android TextView的XML属性的详细信息,请访问此页末尾随附的Google文档或者theitroad Android TextView教程。
在以下部分中,我们将使用Kotlin以编程方式创建TextView,并设置Kotlin函数,属性,并在TextView上使用lambda函数。
使用Kotlin创建Android TextView
我们可以使用findViewById在MainActivity.kt Kotlin类中获取TextView。
" findViewById"用于使用指定的ID从Activity类中的XML获取视图。
它就像字典一样-键/值对。
package net.androidly.androidtextviewkotlin import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.util.Log import android.widget.TextView class MainActivity : AppCompatActivity() { val TAG = "MainActivity" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var textView = findViewById<textview>(R.id.textView) //text property is equivalent to getText() or setText() in Java. Log.d(TAG,"TextView text is ${textView.text}") //Logs TextView text is Android TextView Color //setting the text. textView.text = "Text changed" //Setting the text from the strings.xml file. textView.text = resources.getString(R.string.app_name) } }
代码说明:
MainActivity Kotlin类扩展了AppCompatActivity。
我们已经使用
findViewById
创建了textView属性。
虽然从Android API> 24开始,您可以忽略显式指定类型。text属性用作TextView上的getter/setter方法。
它返回一个CharSequence。${textView.text}
不正确地将CharSequence转换为字符串。Kotlin中的
text
属性等效于Java中的getText()
和setText(String)
。要从strings.xml文件设置字符串,我们调用
resources.getString(R.string )
。
resources属性等效于Java中的getResources()
。
在TextView Kotlin代码中处理空值
Kotlin有一个非常安全的方法来处理空值。
可选类型充当当前类型的包装。
需要安全地解开它们才能使用非null值,从而在我们的Kotlin代码中启用null安全性。
让我们看一下当textView为null时上述应用程序的行为。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) var textView = findViewById<textview>(R.id.textView) textView.text = null Log.d(TAG, "TextView text is ${textView.text}") //Logs TextView text is textView = null Log.d(TAG, "TextView text is ${textView.text}") //compilation error. Add safe call. }
因此,当文本为null时,编译器将忽略它。
当textView为null时,我们需要添加一个安全调用以解开textView。
这样Kotlin会自动为我们提供零安全。
如果textView在运行时为null怎么办?
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //we've set a random id available from the autocomplete just to set textView to null at runtime. var textView = findViewById<textview>(R.id.ALT) Log.d(TAG, "TextView text is ${textView.text}") }
它将引发错误消息为ʻIllegalStateException。
TextView不能为null。
因此,让我们在声明中将TextView属性设置为Optional。
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) val otherTextView: TextView? = findViewById(R.id.textViewOpacity) otherTextView?.text = null Log.d(TAG, "TextView displays ${otherTextView?.text ?: "NA"}") }
我们已经将otherTextView设置为TextView
类型。
因此,通过TextView调用任何内容都需要安全的调用。
如果文本为空怎么办?我们显示什么呢?
我们使用Kotlin的Elvis运算符?:
来确保安全。
在上面的代码中,如果otherTextView?.text
为null,则显示NA。
安全调用也可以由let
lambda表达式代替。
Kotlin Android扩展
多亏了我们build.gradle文件中的apply plugin:'kotlin-android-extensions',我们可以在Kotlin活动类中直接从布局中绑定视图。
在MainActivity.kt类中添加以下导入语句。
import kotlinx.android.synthetic.main.activity_main.*
现在,您可以直接使用TextView属性,而无需使用findViewById。
Android TextView Kotlin onClick侦听器
package net.androidly.androidtextviewkotlin import android.graphics.Color import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v4.content.ContextCompat import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { val TAG = "MainActivity" override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) //set textView to clickable textView.isClickable = true textView.setOnClickListener{ textView.text = resources.getString(R.string.app_name) } textViewClickMe.setOnClickListener { textViewClickMe.setTextColor(Color.WHITE) } textViewEllipsize.ellipsize = TextUtils.TruncateAt.MARQUEE textViewEllipsize.setHorizontallyScrolling(true) textViewEllipsize.marqueeRepeatLimit = -1 textViewEllipsize.isSelected = true val mipMapDrawable = ContextCompat.getDrawable(this, R.mipmap.ic_launcher) textViewOpacity.setCompoundDrawablesWithIntrinsicBounds(mipMapDrawable,null,mipMapDrawable,null) } }
在上面的代码中,对于setOnClickListener
,我们使用Kotlin的lambda表达式。
与Java相比,它使代码更短,更易于阅读。
要使" textViewEllipsize"幻灯片滑动,请将其设置为" MARQUEE"。
为了使其连续循环,我们将marqueeRepeatLimit设置为-1。
" mipMapDrawable"的类型为Drawable,而" setCompoundDrawablesWithIntrinsicBounds()"的类型相当于" android:drawablePadding"。
应用程序的输出显示在以下GIF中。
Android TextView扩展功能
我们可以在TextView上创建Kotlin扩展功能,以添加自定义功能和属性。
下面的扩展功能为currentTextColor
属性和setTextColor()
函数创建了一个一致的属性。
在类外添加以下代码。
var TextView.textColor: Int get() = currentTextColor set(v) = setTextColor(v)
然后,我们可以使用textColor
属性在TextView上设置颜色。
textViewOpacity.textColor = ContextCompat.getColor(this, R.color.colorPrimaryDark)
Android TextView" with"表达式
代替使用多余的行,我们在同一个TextView属性上像下面这样设置属性:
textViewEllipsize.ellipsize = TextUtils.TruncateAt.MARQUEE textViewEllipsize.setHorizontallyScrolling(true) textViewEllipsize.marqueeRepeatLimit = -1 textViewEllipsize.isSelected = true textViewEllipsize.setOnClickListener { println("So many calls to the same TextView") }
我们可以使用with
表达式使它更好。
with(textViewEllipsize) { ellipsize = TextUtils.TruncateAt.MARQUEE setHorizontallyScrolling(true) marqueeRepeatLimit = -1 isSelected = true setOnClickListener { println("WOW. AWESOME.") } }
在Kotlin中以编程方式创建TextView
下面,我们以编程方式创建了两个TextView。
我们从资产文件夹中设置了自定义字体,并其中一个TextView上设置了下划线。
另外,我们将字符串设置为HTML形式。
资产目录在src下创建。
main文件夹,用于保存自定义字体的TTF文件。
package net.androidly.androidtextviewkotlin import android.graphics.Color import android.graphics.Paint import android.graphics.Typeface import android.os.Build import android.support.v7.app.AppCompatActivity import android.os.Bundle import android.support.v4.content.ContextCompat import android.text.Html import android.text.TextUtils import android.view.Gravity import android.widget.TextView import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { val TAG = "MainActivity" lateinit var programmaticTextView : TextView var optionalTextView : TextView? = null override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) programmaticTextView = TextView(this) with(programmaticTextView) { text = "I'm Created Programmatically. Kotlin makes life simple" textSize = 20f textColor = Color.parseColor("#1F2135") typeface = Typeface.DEFAULT_BOLD isClickable = true setOnClickListener { println("I contain the string: $text") } } linearLayout.addView(programmaticTextView) optionalTextView = TextView(this) optionalTextView.let { with(optionalTextView!!) { text = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { "${Html.fromHtml(" <h4>this is underlined text</h4> Body goes here",Html.FROM_HTML_MODE_LEGACY)}" } else { @Suppress("DEPRECATION") "${Html.fromHtml("this is <u>underlined</u> text")}" } typeface = Typeface.createFromAsset(assets, "Pacifico.ttf") textSize = 20f gravity = Gravity.CENTER paintFlags = Paint.UNDERLINE_TEXT_FLAG } } linearLayout.addView(optionalTextView) } } var TextView.textColor: Int get() = currentTextColor set(v) = setTextColor(v)
Kotlin属性需要在此处本身进行初始化。
如果不可能的话,我们可以为属性设置一个" lateinit"修饰符。
默认情况下,以编程方式创建textView时,其宽度为match_parent,高度为wrap_content。
paintFlags
用于在字符串上添加下划线。
下图显示了将上述TextViews以编程方式添加到布局中的输出。
使用跨度字符串
当我们必须在TextView的不同子字符串上设置不同的样式时,可扩展字符串很有用。
val string = "this is normal, this is underlined" val firstWord = string.substringBefore(",") val secondWord = string.substringAfterLast(",") val redColor = ForegroundColorSpan( ContextCompat.getColor(this,android.R.color.holo_red_dark)) val ssb = SpannableStringBuilder(firstWord) ssb.setSpan( redColor, //the span to add 0, //the start of the span (inclusive) ssb.length, //the end of the span (exclusive) Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) ssb.append(" ") val underlineSpan = UnderlineSpan() ssb.append(secondWord) ssb.setSpan( underlineSpan, ssb.length - secondWord.length, ssb.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE) optionalTextView = TextView(this) optionalTextView.let { with(optionalTextView!!) { text = ssb typeface = Typeface.createFromAsset(assets, "Pacifico.ttf") textSize = 20f gravity = Gravity.CENTER } } linearLayout.addView(optionalTextView)