Cách Android thu hút lượt xem

Khi nhận được tiêu điểm, Activity sẽ được yêu cầu vẽ bố cục. Khung Android sẽ xử lý quy trình vẽ, nhưng Activity phải cung cấp nút gốc của hệ phân cấp bố cục.

Quá trình vẽ bắt đầu bằng nút gốc của bố cục. Nút này được yêu cầu để đo lường và vẽ cây bố cục. Quá trình vẽ được xử lý bằng cách đi theo từng phần của cây và kết xuất từng View giao với khu vực không hợp lệ. Đổi lại, mỗi ViewGroup chịu trách nhiệm yêu cầu vẽ từng phần tử con (bằng phương thức draw()) và mỗi View chịu trách nhiệm vẽ chính nó. Vì cây đã được sắp xếp sẵn theo kiểu tuyến dẫn, nghĩa là, phần tử mẹ sẽ được vẽ trước (tức là phía sau) phần tử con của mình, còn phần tử đồng cấp được vẽ theo thứ tự xuất hiện trên cây của các phần tử đó.

Lưu ý: Khung này không vẽ các đối tượng View không ở trong khu vực hợp lệ, đồng thời sẽ đảm nhiệm việc vẽ nền View giúp bạn.

Bạn có thể buộc View vẽ bằng cách gọi invalidate().

Vẽ bố cục là một quá trình gồm hai lượt: lượt đo lường và lượt bố cục.

Lượt đo lường

Lượt đo lường được triển khai trong measure(int, int) và được thực hiện từ trên xuống trên cây View. Mỗi View sẽ đẩy thông số kỹ thuật về kích thước xuống cây trong quá trình đệ quy. Khi kết thúc lượt đo lường, mọi View đều đã lưu trữ số đo của mình. Lượt thứ hai xảy ra trong layout(int, int, int, int) và cũng theo chiều từ trên xuống. Trong lượt này, mỗi phần tử mẹ chịu trách nhiệm xác định vị trí của tất cả các phần tử con tương ứng bằng cách sử dụng kích thước đã tính toán được trong lượt đo lường.

Khi phương thức measure() của đối tượng View được trả về, bạn phải đặt các giá trị getMeasuredWidth()getMeasuredHeight() của đối tượng đó, cùng với các giá trị này cho mọi phần tử con cháu của đối tượng View đó. Các giá trị chiều rộng đo được và chiều cao đo được của đối tượng View phải tuân theo quy tắc ràng buộc do phần tử mẹ của đối tượng View áp đặt. Điều này đảm bảo rằng, khi kết thúc lượt đo lường, mọi phần tử mẹ sẽ chấp nhận tất cả các số đo của phần tử con tương ứng. Phần tử mẹ View có thể gọi measure() nhiều lần ở phần tử con. Ví dụ: phần tử mẹ có thể đo lường mỗi phần tử con một lần bằng kích thước chưa xác định để tìm ra xem phần tử con muốn lớn đến mức nào rồi gọi lại measure() trên các phần tử con đó bằng con số thực tế nếu tổng kích thước không bị ràng buộc của tất cả phần tử con quá lớn hoặc quá nhỏ (nghĩa là nếu phần tử con không tự thống nhất với nhau về mức dung lượng mà mỗi phần tử con nhận được thì phần tử mẹ sẽ can thiệp và đặt ra quy tắc trong lượt thứ hai).

Lượt đo lường sử dụng hai lớp để truyền đạt các kích thước. Lớp ViewGroup.LayoutParams được đối tượng View sử dụng để cho phần tử mẹ biết cách đo lường và vị trí mong muốn. Lớp ViewGroup.LayoutParams cơ sở chỉ mô tả kích thước mong muốn của View cho cả chiều rộng và chiều cao. Đối với mỗi kích thước, lượt đo lường có thể xác định một trong các mục sau:

  • một số chính xác
  • MATCH_PARENT, nghĩa là View muốn lớn bằng phần tử mẹ (trừ đi khoảng đệm)
  • WRAP_CONTENT, nghĩa là View muốn vừa đủ lớn để chứa trọn nội dung của mình (cộng với khoảng đệm).

ViewGroup.LayoutParams có các lớp con tương ứng với nhiều lớp con của ViewGroup. Ví dụ: RelativeLayout có lớp con riêng là ViewGroup.LayoutParams có khả năng căn giữa các đối tượng con View theo chiều ngang và chiều dọc.

Các đối tượng MeasureSpec dùng để đẩy yêu cầu xuống cây theo chiều từ phần tử mẹ xuống phần tử con. MeasureSpec có thể ở một trong ba chế độ sau:

  • UNSPECIFIED: Được phần tử mẹ sử dụng để xác định kích thước mong muốn của phần tử con View. Ví dụ: LinearLayout có thể gọi measure() trên phần tử con với chiều cao được đặt là UNSPECIFIED và chiều rộng của EXACTLY là 240 để tìm hiểu xem phần tử con View muốn có chiều cao là bao nhiêu với chiều rộng là 240 pixel.
  • EXACTLY: Được phần tử mẹ sử dụng để áp đặt kích thước chính xác lên phần tử con. Phần tử con phải dùng kích thước này và đảm bảo rằng tất cả các phần tử con cháu của mình sẽ nằm vừa khít bên trong kích thước này.
  • AT MOST: Được phần tử mẹ sử dụng để áp đặt kích thước tối đa lên phần tử con. Phần tử con phải đảm bảo rằng bản thân và tất cả các phần tử con cháu của mình sẽ nằm vừa khít bên trong kích thước này.

Lượt bố cục

Để bắt đầu chạy bố cục, hãy gọi requestLayout(). Phương thức này thường được View gọi trên chính nó khi cho rằng không còn vừa bên trong các giới hạn hiện tại của nó nữa.