第二行程式碼學習筆記——第三章:軟體也要拼臉蛋——UI開發的點點滴滴
本章要點
使用Android提供的UI來編寫程式介面。本章的內容就是學習UI方面的知識。
3.1 如何編寫程式介面
Android種編寫程式介面的方式:
1. 視覺化編輯器(不推薦)
2. 編寫XML程式碼(推薦)
3.2 常用控制元件的使用方法
建立一個UIWidgetTest專案
3.2.1 TextView
TextView的用法:
修改activity_main.xm中的程式碼,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="This is TextView"
android:textColor="#00ff00"
android:textSize="24sp" />
</LinearLayout>
屬性:
android:id 當前控制元件唯一標識
android:layout_width和android:layout_height 控制元件的寬度和高度(match_parent(fill_parent不推薦),wrap_content)
android:text 顯示的文字內容
android:gravity 指定文字的對齊方式(center,top,bottom,right,left)可以用”|“同時指定多個值。center同等於center_vertical|center_horizontal垂直和水平方向都居中對齊
android:textSize 指文字的大小(sp)
android:textColor 指文字的顏色
效果圖:
3.2.2 Button
在activity_main.xml中加入Button:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
...
<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
android:textAllCaps="false" />
</LinearLayout>
屬性:
android:textAllCaps true(大)/false(小) 預設true,英文字母大小寫轉換
MainActivity中為Button的點選事件註冊一個監聽器:
public class MainActivity extends AppCompatActivity {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//新增邏輯程式碼
}
});
}
使用介面的方式來進行註冊,如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
//新增邏輯程式碼
break;
default:
break;
}
}
}
3.2.3 EditText
EditText是程式與使用者互動,允許在控制元件裡輸入和編輯內容,並作相應的處理。
EditText應用場景非常普遍,發簡訊,發微博,聊QQ等等……
在activity_main.xml中加入EditText,如下:
<EditText
android:id="@+id/et"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type something here"
android:maxLines="2" />
屬性:
android:hint 指定提示性文字
android:maxLines 指定最大行數
接下來我們通過點選按鈕獲取EditText中輸入的內容,修改MainActivity中的程式碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn;
private EditText et;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
et= (EditText) findViewById(R.id.et);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
String inputText = et.getText().toString();
Toast.makeText(this, inputText, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
效果圖:
3.2.4 ImageView
ImageView在介面展示圖片的控制元件。”drawable“開頭的目錄下放圖片,這個目錄沒有指定解析度,所以不使用它來放圖片。新建drawable-xhdpi目錄來放圖片。
我們把準備好的兩張美女圖片放進新建的drawable-xhdpi目錄下。
在activity_main.xml中新增ImageView:
<ImageView
android:id="@+id/iv"
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@drawable/img_1" />
屬性:
android:src 指定ImageView的圖片
通過程式碼動態的修改ImageView中的圖片,修改MainActivity中的程式碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn;
private EditText et;
private ImageView iv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
et= (EditText) findViewById(R.id.et);
iv= (ImageView) findViewById(R.id.iv);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
iv.setImageResource(R.drawable.img_2);
break;
default:
break;
}
}
}
效果圖:
3.2.5 ProgressBar
ProgressBar顯示進度條,表示正在載入資料。
在activity_main.xml中的程式碼新增ProgressBar:
<ProgressBar
android:id="@+id/pb"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
效果圖:
可見屬性:
android:visibility (visible可見,預設值,invisible不可見,佔位,gone,不可見,不佔位)
程式碼控制可見性,setVisibility()。
按鈕點選切換顯示隱藏進度條,修改MainActivity中的程式碼如下所示:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn;
private EditText et;
private ImageView iv;
private ProgressBar pb;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn= (Button) findViewById(R.id.btn);
et= (EditText) findViewById(R.id.et);
iv= (ImageView) findViewById(R.id.iv);
pb= (ProgressBar) findViewById(R.id.pb);
btn.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
if (pb.getVisibility()==View.GONE){
pb.setVisibility(View.VISIBLE);
}else{
pb.setVisibility(View.GONE);
}
break;
default:
break;
}
}
}
效果圖:
給ProgressBar指定不同樣式,修改activity_main.xml中的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:orientation="vertical">
......
<ProgressBar
android:id="@+id/pb"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100" />
</LinearLayout>
屬性:
style 設定進度條的樣式
android:max 設定進度條最大的
點選按鈕動態更新進度條,修改MainActivity中的程式碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
......
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
int progress = pb.getProgress();
progress=progress+10;
pb.setProgress(progress);
break;
default:
break;
}
}
}
效果圖:
3.2.6 AlertDialog
AlertDialog彈出一個對話方塊,提示一些非常重要內容或者警告資訊。
修改MainActivity中的程式碼:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
......
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
AlertDialog.Builder dialog=new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("This is Dialog");
dialog.setMessage("Something imporent.");
dialog.setCancelable(false);
dialog.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
}
});
dialog.show();
break;
default:
break;
}
}
}
通過AlertDialog.Builder建立AlertDialog的例項,設定標題,內容,等屬性……
setPositiveButton() 確定按鈕的點選事件
setNegativeButton() 取消按鈕的點選
show() 顯示對話方塊
效果圖:
3.2.7 ProgressDialog
ProgressDialog與AlertDialog不同的是:ProgressDialog會在對話方塊顯示進度條。表示耗時操作,讓使用者等待。
修改MainActivity中的程式碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
......
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn:
ProgressDialog progressDialog=new ProgressDialog(MainActivity.this);
progressDialog.setTitle("This is a ProgressDialog");
progressDialog.setMessage("Something imporent");
progressDialog.setCancelable(true);
progressDialog.show();
break;
default:
break;
}
}
}
setCancelable true/false (可以通過Back鍵返回)/(不可以返回,載入完必須呼叫dismiss()來關閉對話方塊,ProgressDialog會一直存在)
效果圖:
3.3 詳解4種基本佈局
佈局是一種可用用放很多控制元件,同時也可以巢狀佈局的使用,來完成一些複雜的佈局。
佈局和控制元件的關係:
新建UILayoutTest專案。
3.3.1 線性佈局
LinearLayout稱線性佈局,將它所包含的線上性方向上依此排列。
android:orientation 指定排列方向,vertical(垂直方向排列),horizontal(水平方向排列)
修改activity_main.xml中的程式碼如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/btn_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="@+id/btn_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
<Button
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3" />
</LinearLayout>
效果圖:
修改activity_main.xml中的屬性程式碼如下:
android:orientation="horizontal"
效果圖:
android:gravity和android:layout_gravity區別:
android:gravity 指文字在元件中的對齊方式
android:layout_gravity 指控制元件在佈局中對齊方式
當排列方向為horizontal時,只有垂直方向對齊方式會生效。當為vertical時,只有水平方向對齊方式才會生效。
修改activity_main中的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<Button
android:id="@+id/btn_1"
android:layout_gravity="top"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="@+id/btn_2"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
<Button
android:id="@+id/btn_3"
android:layout_gravity="bottom"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3" />
</LinearLayout>
效果圖:
android:layout_weight 比例方式控制組件的大小 。我們來編寫訊息傳送介面,修改activity_main中的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<EditText
android:id="@+id/et"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn"
android:text="Send"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
效果圖:
3.3.2 相對佈局
RelativeLayout稱相對佈局,通過相對定位讓控制元件出現在佈局的任何位置。
相對於父佈局進行定位,修改activity_main.xml中的程式碼如下所示:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_1"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="@+id/btn_2"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
<Button
android:layout_centerInParent="true"
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3" />
<Button
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:id="@+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button4" />
<Button
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:id="@+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button5" />
</RelativeLayout>
屬性:
layout_alignParentRight 該控制元件與父佈局控制元件的右對齊嗎?
layout_alignParentLeft 該控制元件與父佈局控制元件的左對齊嗎?
layout_alignParentTop 該控制元件與父佈局控制元件的頂端對齊嗎?
layout_alignParentBottom 該控制元件與父佈局控制元件的底部對齊嗎?
layout_centerInParent 該控制元件位於父佈局控制元件的中心位置嗎?
layout_centerVertical 該控制元件位於父佈局控制元件的垂直中心位置嗎?
layout_centerHorizontal 該控制元件位於父佈局控制元件的水平中心位置嗎?
效果圖:
相對於控制元件進行定位(1),修改activity_main.xml中的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_centerInParent="true"
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3" />
<Button
android:id="@+id/btn_1"
android:layout_above="@id/btn_3"
android:layout_toLeftOf="@id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="@+id/btn_2"
android:layout_toRightOf="@id/btn_3"
android:layout_above="@id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
<Button
android:layout_toLeftOf="@id/btn_3"
android:layout_below="@id/btn_3"
android:id="@+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button4" />
<Button
android:layout_toRightOf="@id/btn_3"
android:layout_below="@id/btn_3"
android:id="@+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button5" />
</RelativeLayout>
屬性:
layout_toRightOf 該控制元件在哪個控制元件的右側
layout_toLeftOf 該控制元件在哪個控制元件的左側
layout_above 該控制元件在哪個控制元件的上側
layout_below 該控制元件在哪個控制元件的下側
效果圖:
相對於控制元件定位(2),修改activity_main.xml中的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_centerInParent="true"
android:id="@+id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button3" />
<Button
android:id="@+id/btn_1"
android:layout_alignLeft="@id/btn_3"
android:layout_above="@id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1" />
<Button
android:id="@+id/btn_2"
android:layout_alignTop="@id/btn_3"
android:layout_toRightOf="@id/btn_3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2" />
<Button
android:layout_alignBottom="@id/btn_3"
android:layout_toLeftOf="@id/btn_3"
android:id="@+id/btn_4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button4" />
<Button
android:layout_alignRight="@id/btn_3"
android:layout_below="@id/btn_3"
android:id="@+id/btn_5"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button5" />
</RelativeLayout>
屬性:
layout_alignRight 該控制元件與哪個控制元件的右對齊
layout_alignLeft 該控制元件與哪個控制元件的左對齊
layout_alignTop 該控制元件與哪個控制元件的頂對齊
layout_alignBottom 該控制元件與哪個控制元件的底對齊
效果圖:
3.3.3 幀佈局
FrameLayout稱幀佈局(簡單佈局)。沒有定位方式,所以控制元件預設擺放左上角。
接下來我們來修改activity_main.xml中的檔案如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:text="This is TextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv"
android:src="@mipmap/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
效果圖:
文字和圖片都位於左上角,ImageView在TextView後,因此圖片壓在文字上面。
使用 android:layout_gravity 屬性指定控制元件在佈局中的對齊方式。修改activity_main中的程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/tv"
android:text="This is TextView"
android:layout_gravity="left"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/iv"
android:layout_gravity="right"
android:src="@mipmap/ic_launcher"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</FrameLayout>
效果圖:
3.3.4 百分比佈局
百分比佈局屬性新增佈局,提供了PercentFrameLayout和PercentRelativeLayout兩種全新的佈局,它倆是FrameLayout和RelativeLayout的功能,繼承了所有的屬性。
百分比佈局的使用:
新增依賴
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:24.2.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
testCompile 'junit:junit:4.12'
compile 'com.android.support:percent:24.2.1'
}
修改activity_main中的佈局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<Button
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:layout_gravity="left|top"
android:id="@+id/btn_1"
android:text="Button1" />
<Button
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:layout_gravity="right|top"
android:id="@+id/btn_2"
android:text="Button2" />
<Button
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:layout_gravity="left|bottom"
android:id="@+id/btn_3"
android:text="Button3" />
<Button
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
android:layout_gravity="right|bottom"
android:id="@+id/btn_4"
android:text="Button4" />
</android.support.percent.PercentFrameLayout>
效果圖:
PercentRelativeLayout 用法非常相似,繼承了RelativeLayout的所有屬性。
Android 中還有AbsoluteLayout,TableLayout等屬性(幾乎不用)
3.4 系統控制元件不夠用?建立自定義控制元件
常用控制元件和佈局的繼承結構:
新建UICustomViews專案。
3.4.1 引入佈局
標題欄,引入佈局。新建title_layout.xml程式碼如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#c2c2c2">
<Button
android:text="Back"
android:textColor="#FFFFFF"
android:layout_gravity="center"
android:layout_margin="5dp"
android:id="@+id/btn_back"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:textSize="24sp"
android:layout_gravity="center"
android:text="This is Title"
android:gravity="center"
android:textColor="#FFFFFF"
android:id="@+id/tv_title"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content" />
<Button
android:text="Edit"
android:layout_margin="5dp"
android:textColor="#FFFFFF"
android:layout_gravity="center"
android:id="@+id/btn_edit"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
修改activity_main.xml中的程式碼:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<