標簽:xml文件 values 一個 video view relative 安裝 textview 排列
上篇文章介紹了界面Activity
的啓動方式和生命周期,本篇將繼續介紹在界面Activity
中的內容是如何繪制展示給用戶的。
在Android系統上運行新創建的界面Activtiy
,給用戶展示的是空白的。而得益于AndroidStudio的強大模板支持,新創建的界面Activity
會自動重寫onCreate()
方法,並在該方法內自動創建以下兩行類似默認代碼。
super.onCreate(savedInstanceState)
setContentView(R.layout.xxx)
顯然,setContentView()
方法就是加載當前界面Activity
的繪制內容,而名爲R.layout.xxx的參數中的xxx,代指文件名,被稱爲布局文件。在系列文章首篇有提到res目錄是存放應用資源的文件夾,該目錄下有個名爲layout的目錄,就是專門存放布局文件的。
在AndroidStudio中,只要在layout目錄下創建布局文件,就可以在java目錄下源代碼中通過調用R.layout
中與布局文件同名的常量來使用,而其中的類名爲R
的文件,是在java(generate)目錄的當前應用包名下自動生成的。
在AndroidStudio中新創建的布局文件默認生成如下模板,該文件符合xml文件格式,其中標簽名只能是Android系統定義或我們應用內自定義的控件名,而其屬性也只能使用已定義的屬性。
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
</android.support.constraint.ConstraintLayout>
View視圖,是Android系统绘制图形的基本单元类,也是系统与用户交互的基本单元类。所有的視圖类追踪其父类,都可以追溯到同一個父类android.view.View。
如果直接在布局文件中添加視圖使用,那么称这个視圖是靜態加載的。静态创建視圖需要使用大量布局文件,在应用程序打包时占用大量存储空间,但是当应用程序安裝之后,Android系统会更加快速的绘制这些視圖。
相反地,也可以在源代碼文件的當前界面Activity
中,直接调用視圖类的構造方法创建一個視圖,并加载到当前界面中,那么称该視圖是動態加載的。动态创建的視圖是写入到源代码中,所以应用程序打包时不会占用太多存储空间,只是在应用程序安裝运行后,Android系统需要更多时间去解析并绘制这些視圖。
上面两种視圖加载方式虽然有所差别,但是在不涉及大量視圖加载的轻量级应用中差别不是很大。一般界面中的視圖都是固定数量的,可以直接静态创建視圖的,这样可以借助AndroidStudio的布局预览插件实时预览当前界面布局效果;只有在根据不同数据加载不同視圖这种类似的动态改变大量界面时,可能動態加載視圖的方式会更方便一些。
視圖除了需要创建加载外,还可以修改其屬性以便于Android系统区分绘制,同样地,既可以在靜態加載时动态设置默认屬性值,也可以在源代码中动态设置屬性值。
注意:针对同一個屬性,动态设置结果会优先覆盖静态屬性值。
任何視圖在创建加载后,有两个屬性值是必须要指定的,那就是表示視圖宽度和高度的尺寸,在布局文件中,靜態加載的視圖必须以标签中的android:layout_width
和android:layout_height
屬性设置;在源代码中,動態加載的視圖默认宽度和高度都是LayoutParams.WRAP_CONTENT
,表示自适应内容尺寸,也可以调用視圖类中的.layoutParams.width
和.layoutParams.height
變量直接訪問或修改。
根据視圖负责的任务不同,可大致分为容器类視圖、展示类視圖、编辑类視圖三种类型。
android.widget.LinearLayout
,对子視圖使用相对位置绘制的相对布局android.widget.RelativeLayout
,集合上述两种布局优势更加灵活绘制子視圖相对位置的约束布局androidx.constraintlayout.widget.ConstraintLayout
等。android.widget.TextView
,展示圖片的android.widget.ImageView
,展示視頻的android.widget.VideoView
等。android.widget.EditText
,允許用戶選擇時間並展示的android.widget.TimePicker
,在用戶操作需要提示時展示的android.widget.Toast
等。正如上边举例的几个視圖,都是在AndroidSDK中定义的視圖,称为系统視圖。系统視圖都位于android.widget包下。
在日常开发中,只需要掌握如何使用系统視圖即可。这里以動態加載的方式介绍几个常用視圖案例。
首先是界面Activity
对应的布局文件,以上文中AndroidStudio自动生成的模板布局文件为例,为了在源代码中获取到这个布局文件的根視圖,在根視圖<android.support.constraint.ConstraintLayout>
標簽中增加android:id 屬性,屬性值以@+id/开头表示新增屬性值,可以定义任意值;而如果以@id/开头,只能使用已经定义过的屬性值。所有新增的屬性,都由AndroidStudio自动存储在前面提到的R
文件中,在源代碼中可以通過R.id.xxx
常量获取,其中xxx即定义的屬性值。
android:id="@+id/activity_main_root"
之後便可以在源代碼的界面Activity
中获取到该視圖,并操作该視圖例如增加子視圖。
val rootLayout = findViewById<ConstraintLayout>(R.id.activity_main_root)
val button1=Button(this)
button1.text="按钮"
button1.id=R.id.button_1
val textView1=TextView(this)
textView1.text="文本展示区"
val layoutParamsButton1 = ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
layoutParamsButton1.topMargin = 500
layoutParamsButton1.topToTop=rootLayout.id
layoutParamsButton1.leftToLeft=rootLayout.id
layoutParamsButton1.rightToRight=rootLayout.id
button1.layoutParams=layoutParamsButton1
val layoutParamsTextView1 = ConstraintLayout.LayoutParams(
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
)
layoutParamsTextView1.circleConstraint=button1.id
layoutParamsTextView1.circleAngle=30f
layoutParamsTextView1.circleRadius=300
textView1.layoutParams=layoutParamsTextView1
rootLayout.addView(button1)
rootLayout.addView(textView1)
在上邊代碼中有用到R.id.button1
变量,由于其绑定視圖并未在布局文件中靜態加載,所以该視圖对应的id值只能在资源文件中单独声明,可以在res资源目录下新建一個xml格式的资源文件,在其中增加如下代码以创建一個id供上边源代码中使用。
<resources>
<item name="button_1" type="id"></item>
</resources>
最終上述代碼的運行效果如下圖。
虽然AndroidSDK提供的系统視圖可以满足大部分常见场景,但是开发的乐趣在于自由绘制視圖及交互。Android系统同样允许开发者自由定义視圖以满足他们的特殊愛好需求。想必不需强调也能理解,这种自定义視圖只能在定义该視圖的所属modle模块中使用,或者在定义了自定义視圖的所属modle模块的被依赖子modle模块中使用。对于自定义視圖,其相关屬性可能因視圖而异,但是使用方式与系统視圖类似,所以主要掌握如何定义自定义視圖。这里以自定义的输入框为例简单说明。
自定义視圖首先要在源代码中定义一個視圖类,该类必须繼承自android.view.View
或其子类。在介绍視圖分类时可以发现,容器类視圖是另外两种視圖的父类。所以一般在编辑类視圖和展示类視圖均不满足自定义視圖的需求时,就直接选择容器类視圖作为自定义視圖的父类,而不是直接繼承android.view.View
。而如果自定义視圖的需求与某个编辑类視圖或展示类視圖的功能重合,也就可以直接在该視圖上修改,那么直接繼承这个编辑类視圖或展示类視圖即可。
在繼承視圖类之后,Java语言的话,需要重写自定义視圖的三个構造方法,而如果应用程序是运行在Android5.0及以上的系统上,还需要重写第四个構造方法。
Android版本号5.0,对应于Android API等级为21,对应Android版本简称为LOLLIPOP
public MyEditText(Context context) {
//動態加載視圖时调用该構造方法
this(context, null);
}
public MyEditText(Context context, AttributeSet attrs) {
//靜態加載視圖时调用该構造方法
this(context, attrs, 0);
}
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {
//确保其他構造方法都最终调用该構造方法
super(context, attrs, defStyleAttr);
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public MyEditText(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
而如果是Kotlin编写的话,只需要重写两个構造方法即可
@JvmOverloads
constructor(context: Context?, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(
context,
attrs,
defStyleAttr
) {
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
constructor(
context: Context?,
attrs: AttributeSet?,
defStyleAttr: Int,
defStyleRes: Int
) : super(context, attrs, defStyleAttr, defStyleRes) {
}
之後可根據需求重寫三個父類方法。
onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int)
方法,确保该自定义視圖在其父視圖的位置。onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int)
方法,确定该視圖在绘制时的尺寸。onDraw(canvas: Canvas)
方法,将该視圖中的屬性信息绘制到屏幕上。如果上述过程都没有问题,就可以像加载系统視圖一样的加载自定义視圖了。但是自定义視圖往往也需要新增一些屬性控制,如果简单的在该視圖类中增加一些getter、setter方法以访问相关屬性,这样就可以在源代码中像使用系统視圖一样的動態加載自定义視圖了。但是如果想在布局文件中靜態加載視圖,这就需要重写上述代码中的三参構造方法中了。
静态设置屬性值,首先就要先创建固定的屬性名,在res/values资源目录中创建xml格式的资源文件,并在其中定义屬性值如下所示
<declare-styleable name="StyleMyEditText">
<attr name="myDefaultText" format="string" />
</declare-styleable>
之后在上述重写構造方法中获取这些屬性值并赋予其实际意义即可。
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.StyleMyEditText)
val defaultText = typedArray.getString(R.styleable.StyleMyEditText_myDefaultText)
setText(defaultText)
typedArray.recycle() //回收代码不能少,否则容易内存泄漏
如此,就可以在靜態加載自定义視圖的布局文件中正常设置其屬性值了。
<com.kotlin.helloword.MyEditText
android:layout_width="200dp"
android:layout_height="100dp"
app:myDefaultText="默认显示内容"
/>
自定义屬性值通过app域使用,android域只能设置Android系统提供的固定屬性值
内容有限,視圖的简单使用先大致这些,详情案例可参考后续视频内容。而視圖作为系统与用户交互的基本单元,其使用功能更加多元,下一章将继续介绍視圖间的动画与交互。
Android系統編程入門系列之界面Activity繪制展示
標簽:xml文件 values 一個 video view relative 安裝 textview 排列
原文地址:https://www.cnblogs.com/BobGo/p/14978582.html