雖然Android Studio提供了可視化編輯工具來(lái)讓你通過(guò)拖拽的方式進(jìn)行頁(yè)面布局,但是這不利于真正了解界面背后的實(shí)現(xiàn)原理且適配性很差,當(dāng)編寫(xiě)復(fù)雜界面的時(shí)候也會(huì)束手無(wú)策,因此推薦通過(guò)最基本的方式也就是編寫(xiě)XML代碼來(lái)實(shí)現(xiàn)UI的布局
常用控件的使用
新建一個(gè)名為UIWidgetTest工程
TextView
修改activity_main.xml中的代碼,創(chuàng)建一個(gè)TextView并且設(shè)置相關(guān)屬性
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="This is TextView"
android:gravity="center"
android:textSize="24sp"
android:textColor="#00ff00"
/>
</LinearLayout>
使用android:gravity來(lái)指定文字的對(duì)齊方式,可選值有top、bottom、left、right、center等,可以使用“|”來(lái)同時(shí)指定多個(gè)值,這里指定的center,效果等同于center_vertical | center_horizonal,表示文字在垂直和水平方向都居中對(duì)齊。通過(guò)android:textSize屬性可以設(shè)置文字的大小,Android中字體大小使用sp作為單位,android:textColor屬性指定文字顏色。
Button
添加Button控件,并且設(shè)置相關(guān)屬性:
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button"
android:textAllCaps="false"
/>
當(dāng)你設(shè)置Button的文字內(nèi)容是“Button”的時(shí)候,運(yùn)行結(jié)果會(huì)顯示“BUTTON”,這是因?yàn)橄到y(tǒng)會(huì)對(duì)Button中的所有英文字母自動(dòng)進(jìn)行大寫(xiě)轉(zhuǎn)換,這并不是我們需要的,因此設(shè)置屬性android:textAllCaps為false來(lái)禁用這一默認(rèn)特性,這樣就可以正常顯示出我們希望的文字內(nèi)容“Button”。
點(diǎn)擊按鈕時(shí)注冊(cè)監(jiān)聽(tīng)事件
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 此處添加邏輯
Toast.makeText(MainActivity.this, "Button Clicked", Toast.LENGTH_SHORT).show();
}
});
}
如果不喜歡使用匿名類的方式注冊(cè)監(jiān)聽(tīng),也可以使用實(shí)現(xiàn)接口的方式來(lái)進(jìn)行注冊(cè),代碼修改為:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
Toast.makeText(MainActivity.this, "Button Clicked", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
這兩種方式均可以實(shí)現(xiàn)對(duì)按鈕點(diǎn)擊事件的監(jiān)聽(tīng),至于使用哪一種看個(gè)人喜好
EditText
EditText是程序用于和用戶進(jìn)行交互的重要空間,允許在控件里輸入和編輯內(nèi)容,并可以在程序中對(duì)這些內(nèi)容進(jìn)行處理。
添加TextView空間:
<EditText
android:id="@+id/edit_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Type something here"
android:maxLines="2"
/>
android:hint屬性用來(lái)設(shè)置提示性文字,由于隨著輸入內(nèi)容的增多,EditText會(huì)被不斷拉長(zhǎng),這時(shí)由于EditText的高度指定的是wrap_content,因此它總能包住往里面的內(nèi)容,但是輸入過(guò)長(zhǎng)的話,界面就比較難看,因此可以使用android:maxLines屬性用來(lái)設(shè)置最大行數(shù)
結(jié)合使用EditText和Button完成通過(guò)按鈕來(lái)獲取EditText中輸入的內(nèi)容。在MainActivity中修改代碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
editText = (EditText)findViewById(R.id.edit_text);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
String inputText = editText.getText().toString();
Toast.makeText(MainActivity.this, inputText, Toast.LENGTH_SHORT).show();
break;
default:
break;
}
}
}
調(diào)用EditText的getText()方法獲取輸入的內(nèi)容,再調(diào)用toString()方法轉(zhuǎn)換成字符串,最后用Toast將輸入的內(nèi)容顯示出來(lái)。
ImageView
ImageView控件用于展示圖片,圖片通常都是放在“drawable”開(kāi)頭的目錄下的,目前有一個(gè)空的drawable目錄,不過(guò)由于這個(gè)目錄沒(méi)有指定具體的分辨率,所以一般不使用它來(lái)放置圖片。在res目錄下新建一個(gè)drawable-xhdpi目錄,將準(zhǔn)備好的圖片復(fù)制到這個(gè)目錄下。
接下來(lái)添加ImageView控件:
<ImageView
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/android"
/>
使用android:src屬性給ImageView指定了一張圖片。由于圖片的寬和高都未知,所以制定寬和高都是“wrap_content”,這樣就不管圖片的尺寸是多少都可以完整的展現(xiàn)出來(lái)。
還可以通過(guò)代碼動(dòng)態(tài)的更改ImageView中的圖片,修改MainActivity中的代碼如下:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editText;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
editText = (EditText)findViewById(R.id.edit_text);
imageView = (ImageView)findViewById(R.id.image_view);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
imageView.setImageResource(R.drawable.bootscrapt);
break;
default:
break;
}
}
}
在按鈕點(diǎn)擊事件里,調(diào)用ImageView的setImageResource()方法將顯示的圖片改成“bootscrapt”,這樣點(diǎn)擊按鈕后就可以實(shí)現(xiàn)圖片切換的功能。
ProgressBar
ProgressBar用于在界面上顯示一個(gè)進(jìn)度條,表示程序正在加載一些數(shù)據(jù)。
添加ProgressBar控件:
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="?android:attr/progressBarStyleHorizontal"
android:max="100"
/>
不設(shè)置style屬性的話會(huì)看到屏幕中有一個(gè)圓形進(jìn)度條在旋轉(zhuǎn)。所有Android控件都有一個(gè)是否可見(jiàn)的屬性,這個(gè)屬性是通過(guò)android:visibility進(jìn)行指定,可選值有3個(gè):visible、invisible和gone。visible表示控件可見(jiàn),這個(gè)值是默認(rèn)值,不指定可見(jiàn)屬性的時(shí)候,控件都是可見(jiàn)的。invisible表示控件不可見(jiàn),但是仍占據(jù)著原來(lái)的位置和大小,可以理解為控件變成了透明的狀態(tài)了。gone則表示控件不僅不可見(jiàn),而且不占用任何屏幕空間。可以通過(guò)代碼設(shè)置控件的可見(jiàn)性,使用setVisibility()方法,可以傳入View.VISIBLE、View.INVISIBLE和View.GONE這3種值。
接下來(lái)實(shí)現(xiàn)點(diǎn)擊按鈕讓進(jìn)度條消失,再點(diǎn)擊進(jìn)度條出現(xiàn),在顯示和隱藏之間來(lái)回切換的功能:
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private EditText editText;
private ImageView imageView;
private ProgressBar progressBar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = (Button)findViewById(R.id.button);
button.setOnClickListener(this);
editText = (EditText)findViewById(R.id.edit_text);
imageView = (ImageView)findViewById(R.id.image_view);
progressBar = (ProgressBar)findViewById(R.id.progress_bar);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
if (progressBar.getVisibility() == View.GONE) {
progressBar.setVisibility(View.VISIBLE);
} else {
progressBar.setVisibility(View.GONE);
}
break;
default:
break;
}
}
}
通過(guò)getVisibility()方法來(lái)判斷ProgressBar是否可見(jiàn),若可見(jiàn)則隱藏,若隱藏則可見(jiàn)
還可以給ProgressBar指定不同的樣式,剛剛是圓形進(jìn)度條,通過(guò)style屬性將它指定城水平進(jìn)度條:style="?android:attr/progressBarStyleHorizontal"
,之后還可以通過(guò)android:max屬性給進(jìn)度條設(shè)置一個(gè)最大值,然后再代碼中動(dòng)態(tài)改變進(jìn)度條的進(jìn)度,代碼如下:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
int progress = progressBar.getProgress();
progress = progress + 10;
progressBar.setProgress(progress);
break;
default:
break;
}
}
這樣就實(shí)現(xiàn)了每點(diǎn)擊一次按鈕,進(jìn)度條獲取當(dāng)前進(jìn)度,然后再現(xiàn)有的進(jìn)度之上加10作為更新后的進(jìn)度。
AlertDialog
AlertDialog可以在當(dāng)前的界面彈出一個(gè)對(duì)話框,這個(gè)對(duì)話框置頂于所有界面元素之上,能夠屏蔽掉其他控件的交互能力,因此AlertDialog一般都是用于提示一些非常重要的內(nèi)容或者警告信息。比如為了防止用戶誤刪除重要內(nèi)容,再刪除之前彈出一個(gè)確認(rèn)對(duì)話框等。
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
AlertDialog.Builder dialog = new AlertDialog.Builder(MainActivity.this);
dialog.setTitle("This is a Dialog");
dialog.setMessage("Something important.");
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;
}
}
首先通過(guò)AlertDialog.Builder創(chuàng)建了一個(gè)AlertDialog的實(shí)例,然后可以為這個(gè)對(duì)話框設(shè)置標(biāo)題、內(nèi)容、可否取消等屬性,接下來(lái)調(diào)用setPositiveButton()方法為對(duì)話框設(shè)置確定按鈕的點(diǎn)擊事件,調(diào)用setNegativeButton()方法為對(duì)話框設(shè)置取消按鈕的點(diǎn)擊事件,最后調(diào)用show()方法將對(duì)話框顯示出來(lái)。
ProgressDialog
ProgressDialog和AlertDialog有點(diǎn)類似,都可以在界面上彈出一個(gè)對(duì)話框,能夠屏蔽掉其他控件的交互能力,不同的是,ProgressDialog會(huì)在對(duì)話框中顯示一個(gè)進(jìn)度條,一般用于表示當(dāng)前操作比較耗時(shí),讓用戶耐心等待。看一下它的用法:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button:
// 在此處添加邏輯
ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("This is ProgressDialog");
progressDialog.setMessage("Loading...");
progressDialog.setCancelable(true);
progressDialog.show();
break;
default:
break;
}
}
這里先構(gòu)建出一個(gè)ProgressDialog對(duì)象,然后同樣可以設(shè)置標(biāo)題、內(nèi)容、可否取消等屬性,最后調(diào)用show()方法將ProgressDialog顯示出來(lái)。
需要注意的是,如果在setCancelable()中傳入了false,表示ProgressDialog是不能通過(guò)Back鍵取消的,這時(shí)需要在代碼中做好控制,但數(shù)據(jù)加載完成后,需要調(diào)用ProgressDialog的dismiss()方法來(lái)關(guān)閉對(duì)話框,否則ProgressDialog將會(huì)一直存在。
添加AlertDialog控件: