Bố cục trong khung hiển thị
Bố cục xác định cấu trúc của giao diện người dùng trong ứng dụng, chẳng hạn như trong
một
hoạt động. Tất cả các phần tử trong
bằng cách sử dụng hệ thống phân cấp
View
và
ViewGroup
. View
thường minh hoạ nội dung mà người dùng có thể nhìn thấy và
tương tác với. ViewGroup
là một vùng chứa vô hình xác định
cấu trúc bố cục cho View
và ViewGroup
khác
như được minh hoạ trong Hình 1.
Đối tượng View
thường được gọi là tiện ích và có thể là một trong
nhiều lớp con, chẳng hạn như
Button
hoặc
TextView
. Chiến lược phát hành đĩa đơn
Các đối tượng ViewGroup
thường được gọi là bố cục và có thể là một
nhiều loại cung cấp một cấu trúc bố cục khác nhau, chẳng hạn như
LinearLayout
hoặc
ConstraintLayout
.
Bạn có thể khai báo một bố cục theo 2 cách:
- Khai báo các thành phần trên giao diện người dùng ở định dạng XML. Android cung cấp một XML đơn giản
từ vựng tương ứng với các lớp và lớp con
View
, chẳng hạn như tiện ích con và bố cục. Bạn cũng có thể sử dụng Layout Editor để tạo tệp XML của bạn bằng giao diện kéo và thả. - Tạo thực thể cho các phần tử bố cục trong thời gian chạy. Ứng dụng của bạn có thể tạo
Các đối tượng
View
vàViewGroup
cũng như thao tác với các đối tượng này các thuộc tính theo phương thức lập trình.
Việc khai báo giao diện người dùng trong XML cho phép bạn tách bản trình bày của ứng dụng khỏi mã kiểm soát hành vi của nó. Việc sử dụng các tệp XML cũng giúp bạn dễ dàng cung cấp các bố cục khác nhau cho nhiều hướng và kích thước màn hình. Đây là sẽ được thảo luận thêm trong Hỗ trợ nhiều màn hình kích thước.
Khung Android mang đến cho bạn sự linh hoạt khi sử dụng một hoặc cả hai các phương pháp này để tạo giao diện người dùng của ứng dụng. Ví dụ: bạn có thể khai báo bố cục mặc định trong XML rồi sửa đổi bố cục trong thời gian chạy.
Ghi XML
Bằng cách sử dụng từ vựng XML của Android, bạn có thể nhanh chóng thiết kế bố cục giao diện người dùng và các phần tử màn hình mà chúng chứa, giống như cách bạn tạo các trang web trong HTML bằng một loạt các phần tử lồng nhau.
Mỗi tệp bố cục phải chứa đúng một phần tử gốc và phần tử đó phải là
Đối tượng View
hoặc ViewGroup
. Sau khi bạn xác định thư mục gốc
, bạn có thể thêm các đối tượng bố cục hoặc tiện ích khác làm phần tử con để
xây dựng dần một hệ phân cấp View
xác định bố cục của bạn. Cho
ví dụ: dưới đây là bố cục XML sử dụng LinearLayout
dọc để
giữ một TextView
và một Button
:
<?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" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Hello, I am a Button" /> </LinearLayout>
Sau khi bạn khai báo bố cục trong XML, hãy lưu tệp bằng
Tiện ích .xml
trong res/layout/
của dự án Android
để thư mục biên dịch đúng cách.
Để biết thêm thông tin về cú pháp cho tệp XML bố cục, hãy xem Tài nguyên bố cục.
Tải tài nguyên XML
Khi bạn biên dịch ứng dụng, mỗi tệp bố cục XML sẽ được biên dịch thành
tài nguyên View
. Tải tài nguyên bố cục trong
Activity.onCreate()
lệnh gọi lại. Thực hiện điều này bằng cách gọi
setContentView()
,
truyền tham chiếu đến tài nguyên bố cục trong biểu mẫu:
R.layout.layout_file_name
Ví dụ: nếu mã XML của bạn
bố cục được lưu dưới dạng main_layout.xml
, hãy tải bố cục này cho
Activity
như sau:
Kotlin
fun onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) setContentView(R.layout.main_layout) }
Java
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_layout); }
Khung Android gọi phương thức gọi lại onCreate()
trong
Activity
của bạn khi Activity
khởi chạy. Để biết thêm
thông tin về vòng đời hoạt động, xem
Giới thiệu về
hoạt động.
Thuộc tính
Mỗi đối tượng View
và ViewGroup
đều hỗ trợ đối tượng riêng
các thuộc tính XML khác nhau. Có một số thuộc tính dành riêng cho View
. Ví dụ: TextView
hỗ trợ textSize
. Tuy nhiên, mọi View
cũng kế thừa những thuộc tính này
các đối tượng mở rộng lớp này. Một số lỗi phổ biến đối với tất cả View
vì các đối tượng này được kế thừa từ lớp View
gốc, chẳng hạn như
thuộc tính id
. Các thuộc tính khác được coi là bố cục
tham số, là những thuộc tính mô tả một số hướng bố cục nhất định
của đối tượng View
, như được xác định bởi phần tử mẹ của đối tượng đó
Đối tượng ViewGroup
.
ID
Mọi đối tượng View
đều có thể được liên kết với một mã nhận dạng bằng số nguyên để
xác định duy nhất View
trong cây. Khi ứng dụng
được biên dịch, mã nhận dạng này được tham chiếu dưới dạng số nguyên, nhưng mã này thường được chỉ định
trong tệp XML bố cục dưới dạng một chuỗi trong thuộc tính id
. Đây là một
Thuộc tính XML chung cho mọi đối tượng View
và được xác định bằng
Lớp View
. Bạn sử dụng mã này rất thường xuyên. Cú pháp cho một mã nhận dạng bên trong một
Thẻ XML như sau:
android:id="@+id/my_button"
Ký hiệu at (@) ở đầu chuỗi cho biết rằng
trình phân tích cú pháp XML sẽ phân tích cú pháp và mở rộng phần còn lại của chuỗi mã nhận dạng, đồng thời xác định chuỗi đó là
tài nguyên mã nhận dạng. Dấu dấu cộng (+) có nghĩa là đây là tên tài nguyên mới
phải được tạo và thêm vào tài nguyên của bạn trong R.java
.
Khung Android cung cấp nhiều tài nguyên mã nhận dạng khác. Khi tham chiếu một
Mã nhận dạng tài nguyên Android, bạn không cần phải có biểu tượng dấu cộng, nhưng bạn phải thêm
Không gian tên của gói android
như sau:
android:id="@android:id/empty"
Không gian tên gói android
cho biết bạn đang tham chiếu
một mã nhận dạng từ lớp tài nguyên android.R
chứ không phải từ lớp
tài nguyên.
Để tạo các khung hiển thị và tham chiếu đến các khung hiển thị đó từ ứng dụng của mình, bạn có thể sử dụng mẫu như sau:
- Xác định một thành phần hiển thị trong tệp bố cục và gán mã nhận dạng duy nhất cho thành phần hiển thị đó, như trong
ví dụ sau:
<Button android:id="@+id/my_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/my_button_text"/>
- Tạo một thực thể của đối tượng thành phần hiển thị và chụp đối tượng đó từ bố cục
thường trong
onCreate()
như được thể hiện trong ví dụ sau:Kotlin
val myButton: Button = findViewById(R.id.my_button)
Java
Button myButton = (Button) findViewById(R.id.my_button);
Việc xác định mã nhận dạng cho đối tượng khung hiển thị là rất quan trọng khi tạo
RelativeLayout
.
Trong bố cục tương đối, các khung hiển thị đồng cấp có thể xác định bố cục so với một bố cục khác
khung hiển thị đồng cấp được tham chiếu theo mã nhận dạng duy nhất.
Mã nhận dạng không nhất thiết phải là duy nhất trong toàn bộ cây, nhưng phải là duy nhất trong phần cây mà bạn tìm kiếm. Thường có thể là toàn bộ do đó tốt nhất nên tạo biểu trưng là duy nhất khi có thể.
Tham số bố cục
Thuộc tính bố cục XML có tên là layout_something
xác định
tham số bố cục cho View
phù hợp với
ViewGroup
chứa phần này.
Mỗi lớp ViewGroup
sẽ triển khai một lớp lồng ghép mở rộng
ViewGroup.LayoutParams
Lớp con này chứa các loại thuộc tính xác định kích thước và vị trí của mỗi loại
khung hiển thị con, cho phù hợp với nhóm khung hiển thị. Như trong hình 2, phần tử mẹ
nhóm khung hiển thị xác định các tham số bố cục cho mỗi khung hiển thị con, bao gồm cả khung hiển thị con
nhóm chế độ xem.
Mỗi lớp con LayoutParams
đều có cú pháp riêng để đặt chế độ cài đặt
giá trị. Mỗi phần tử con phải xác định một LayoutParams
phù hợp với cấp độ gốc, mặc dù mã này cũng có thể xác định một
LayoutParams
cho các phần tử con của chính nó.
Tất cả các nhóm chế độ xem đều có chiều rộng và chiều cao, sử dụng layout_width
và layout_height
. Mỗi thành phần hiển thị bắt buộc phải xác định các thuộc tính này. Nhiều
LayoutParams
bao gồm lề và đường viền không bắt buộc.
Bạn có thể chỉ định chiều rộng và chiều cao bằng các số đo chính xác, nhưng có thể không muốn làm điều này thường xuyên. Thông thường, bạn sử dụng một trong các hằng số này để đặt giá trị chiều rộng hoặc chiều cao:
wrap_content
: yêu cầu khung hiển thị tự định kích thước theo các kích thước cần thiết theo nội dung.match_parent
: yêu cầu thành phần hiển thị lớn bằng thành phần mẹ cho phép.
Nói chung, bạn không nên chỉ định chiều rộng và chiều cao bố cục bằng cách sử dụng
đơn vị tuyệt đối như pixel. Một phương pháp hiệu quả hơn là sử dụng các phép đo tương đối,
chẳng hạn như đơn vị pixel không phụ thuộc vào mật độ (dp), wrap_content
hoặc
match_parent
vì thành phần này giúp ứng dụng của bạn hiển thị đúng cách trên
nhiều kích thước màn hình thiết bị. Các loại đo lường được chấp nhận được xác định trong
Tài nguyên bố cục.
Vị trí bố cục
Một khung hiển thị có hình chữ nhật. Nó có vị trí, được biểu thị dưới dạng một cặp toạ độ trái và trên cùng, cùng hai kích thước, được biểu thị bằng chiều rộng và chiều cao. Đơn vị của vị trí và kích thước là pixel.
Bạn có thể truy xuất vị trí của một khung hiển thị bằng cách gọi các phương thức
getLeft()
và
getTop()
Phương thức thứ nhất trả về toạ độ bên trái (x) của hình chữ nhật biểu thị
chế độ xem. Phương thức sau trả về toạ độ đỉnh (y) của hình chữ nhật
biểu thị cho chế độ xem. Các phương thức này trả về vị trí của thành phần hiển thị so với
thành phần mẹ của nó. Ví dụ: khi getLeft()
trả về 20, điều này có nghĩa là
chế độ xem trực tiếp nằm cách cạnh bên trái 20 pixel về phía bên phải
cha mẹ.
Ngoài ra, còn có các phương thức thuận tiện để tránh các phép tính không cần thiết:
cụ thể là
getRight()
và
getBottom()
Các phương thức này trả về toạ độ của các cạnh bên phải và cạnh dưới của
hình chữ nhật biểu thị khung hiển thị. Ví dụ: gọi getRight()
là
tương tự như phép tính sau: getLeft() + getWidth()
.
Kích thước, khoảng đệm và lề
Kích thước của thành phần hiển thị được biểu thị bằng chiều rộng và chiều cao. Một thành phần hiển thị có 2 cặp gồm giá trị chiều rộng và chiều cao.
Cặp đầu tiên được gọi là chiều rộng đo được và
chiều cao đo được. Các kích thước này xác định kích thước mong muốn của một thành phần hiển thị
trong phần tử mẹ. Bạn có thể lấy kích thước đã đo bằng cách gọi
getMeasuredWidth()
và
getMeasuredHeight()
Cặp thứ hai được gọi là chiều rộng và chiều cao hoặc đôi khi
chiều rộng bản vẽ và chiều cao bản vẽ. Các phương diện này xác định
kích thước thực của thành phần hiển thị trên màn hình, tại thời điểm vẽ và sau khi bố cục. Các
các giá trị có thể, nhưng không nhất thiết, khác với chiều rộng và chiều cao đo được. Bạn
có thể lấy chiều rộng và chiều cao bằng cách gọi
getWidth()
và
getHeight()
Để đo các kích thước, thành phần hiển thị sẽ tính đến khoảng đệm. Khoảng đệm
được biểu thị bằng pixel cho các phần bên trái, trên cùng, bên phải và dưới cùng của chế độ xem.
Bạn có thể sử dụng khoảng đệm để bù trừ nội dung của thành phần hiển thị theo một số lượng cụ thể
điểm ảnh. Ví dụ: khoảng đệm bên trái là 2 sẽ đẩy nội dung của khung hiển thị lên 2 pixel
ở bên phải của cạnh trái. Bạn có thể đặt khoảng đệm bằng cách sử dụng
setPadding(int, int, int, int)
và truy vấn bằng cách gọi
getPaddingLeft()
,
getPaddingTop()
,
getPaddingRight()
,
và
getPaddingBottom()
.
Mặc dù thành phần hiển thị có thể xác định khoảng đệm, nhưng thành phần hiển thị này không hỗ trợ lề. Tuy nhiên,
các nhóm khung hiển thị có hỗ trợ lề. Xem
ViewGroup
và
ViewGroup.MarginLayoutParams
để biết thêm thông tin.
Để biết thêm thông tin về phương diện, hãy xem Kích thước.
Ngoài việc đặt lề và khoảng đệm theo phương thức lập trình, bạn cũng có thể đặt chúng trong bố cục XML của bạn, như trong ví dụ sau:
<?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" > <TextView android:id="@+id/text" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_margin="16dp" android:padding="8dp" android:text="Hello, I am a TextView" /> <Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="16dp" android:paddingBottom="4dp" android:paddingEnd="8dp" android:paddingStart="8dp" android:paddingTop="4dp" android:text="Hello, I am a Button" /> </LinearLayout>
Ví dụ trước cho thấy lề và khoảng đệm đang được áp dụng. Chiến lược phát hành đĩa đơn
TextView
có lề và khoảng đệm đồng nhất được áp dụng xung quanh và
Button
sẽ hướng dẫn bạn cách áp dụng độc lập từng xu hướng
cạnh.
Bố cục phổ biến
Mỗi lớp con của lớp ViewGroup
cung cấp một cách riêng để
hiển thị các chế độ xem mà bạn lồng vào đó. Loại bố cục linh hoạt nhất và
cung cấp các công cụ tốt nhất để duy trì
hệ phân cấp bố cục ở mức nông, là
ConstraintLayout
.
Sau đây là một số loại bố cục phổ biến được tích hợp vào Android chủ.
Sắp xếp các phần tử con thành một hàng ngang hoặc dọc và tạo một thanh cuộn nếu chiều dài cửa sổ vượt quá chiều dài màn hình.
Tạo danh sách động
Khi nội dung cho bố cục của bạn có tính động hoặc không được xác định trước, bạn có thể
sử dụng
RecyclerView
hoặc
một lớp con của
AdapterView
RecyclerView
thường là lựa chọn tốt hơn vì nó sử dụng bộ nhớ
hiệu quả hơn AdapterView
.
Có thể dùng các bố cục phổ biến với RecyclerView
và
AdapterView
bao gồm những lợi ích sau:
RecyclerView
mang đến nhiều khả năng hơn và
lựa chọn để
tạo một nhóm quảng cáo tuỳ chỉnh
trình quản lý bố cục.
Điền dữ liệu vào thành phần hiển thị bộ chuyển đổi
Bạn có thể điền sẵn
AdapterView
chẳng hạn như ListView
hoặc
GridView
bởi
liên kết thực thể AdapterView
với một
Adapter
,
Lệnh này truy xuất dữ liệu từ nguồn bên ngoài và tạo View
đại diện cho từng mục dữ liệu.
Android cung cấp một số lớp con của Adapter
rất hữu ích
để truy xuất các loại dữ liệu khác nhau và tạo chế độ xem cho
AdapterView
Hai trình chuyển đổi phổ biến nhất là:
ArrayAdapter
- Hãy dùng bộ chuyển đổi này khi nguồn dữ liệu của bạn là một mảng. Theo mặc định,
ArrayAdapter
tạo một khung hiển thị cho từng mục mảng bằng cách gọitoString()
trên từng mục và đặt nội dung trongTextView
.Ví dụ: nếu bạn có một mảng chuỗi mà bạn muốn hiển thị trong một
ListView
, hãy khởi chạy mộtArrayAdapter
mới bằng cách sử dụng hàm khởi tạo để chỉ định bố cục cho từng chuỗi và mảng chuỗi:Kotlin
val adapter = ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray)
Java
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, myStringArray);
Các đối số cho hàm khởi tạo này như sau:
- Ứng dụng của bạn
Context
- Bố cục chứa
TextView
cho mỗi chuỗi trong mảng - Mảng chuỗi
Sau đó gọi
setAdapter()
trênListView
của bạn:Kotlin
val listView: ListView = findViewById(R.id.listview) listView.adapter = adapter
Java
ListView listView = (ListView) findViewById(R.id.listview); listView.setAdapter(adapter);
Để tuỳ chỉnh giao diện của từng mục, bạn có thể ghi đè phương thức Phương thức
toString()
cho các đối tượng trong mảng của bạn. Hoặc để tạo một khung hiển thị cho mỗi mục không phải làTextView
—ví dụ: nếu bạn muốn mộtImageView
cho mỗi mục mảng – mở rộng lớpArrayAdapter
và ghi đègetView()
để trả về loại khung hiển thị bạn muốn cho mỗi mục. - Ứng dụng của bạn
SimpleCursorAdapter
- Sử dụng bộ chuyển đổi này khi dữ liệu của bạn được lấy từ
Cursor
Khi sử dụngSimpleCursorAdapter
, hãy chỉ định bố cục cần sử dụng cho mỗi hàng trongCursor
và cột nào trongCursor
bạn muốn chèn vào thành phần hiển thị của bố cục bạn muốn. Ví dụ: nếu bạn muốn tạo danh sách tên và số điện thoại của mọi người bạn có thể thực hiện truy vấn trả vềCursor
chứa một hàng cho mỗi người và các cột cho tên và số. Bạn sau đó tạo một mảng chuỗi chỉ định cột nào từCursor
mà bạn muốn trong bố cục cho mỗi kết quả và một số nguyên chỉ định các thành phần hiển thị tương ứng mà mỗi cột cần được đã đặt:Kotlin
val fromColumns = arrayOf(ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER) val toViews = intArrayOf(R.id.display_name, R.id.phone_number)
Java
String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}; int[] toViews = {R.id.display_name, R.id.phone_number};
Khi bạn tạo thực thể cho
SimpleCursorAdapter
, hãy truyền bố cục để sử dụng cho từng kết quả,Cursor
chứa kết quả và 2 mảng này:Kotlin
val adapter = SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0) val listView = getListView() listView.adapter = adapter
Java
SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.person_name_and_number, cursor, fromColumns, toViews, 0); ListView listView = getListView(); listView.setAdapter(adapter);
Sau đó,
SimpleCursorAdapter
sẽ tạo một chế độ xem cho từng hàng trongCursor
sử dụng bố cục được cung cấp bằng cách chèn mỗifromColumns
mục vàotoViews
tương ứng chế độ xem.
Nếu trong quá trình hoạt động của ứng dụng, bạn thay đổi dữ liệu cơ bản
được bộ chuyển đổi của bạn đọc, hãy gọi
notifyDataSetChanged()
.
Thao tác này sẽ thông báo cho khung hiển thị đính kèm rằng dữ liệu đã được thay đổi và dữ liệu sẽ được làm mới.
.
Xử lý các sự kiện nhấp chuột
Bạn có thể phản hồi các sự kiện nhấp chuột trên mỗi mục trong AdapterView
bằng cách triển khai
AdapterView.OnItemClickListener
. Ví dụ:
Kotlin
listView.onItemClickListener = AdapterView.OnItemClickListener { parent, view, position, id -> // Do something in response to the click. }
Java
// Create a message handling object as an anonymous class. private OnItemClickListener messageClickedHandler = new OnItemClickListener() { public void onItemClick(AdapterView parent, View v, int position, long id) { // Do something in response to the click. } }; listView.setOnItemClickListener(messageClickedHandler);
Tài nguyên khác
Xem cách bố cục được sử dụng trong Hoa hướng dương ứng dụng minh hoạ trên GitHub.