WebView hoàn hảo theo pixel

Ngày xuất bản: 28 tháng 2 năm 2014

Bạn có thể sử dụng một số tuỳ chọn để tạo giao diện hoàn hảo cho WebView.

Đặt thẻ meta khung nhìn

Thẻ meta khung nhìn là một trong những thẻ quan trọng nhất cần thêm vào ứng dụng web. Nếu không có thẻ này, WebView có thể hoạt động như thể trang web của bạn được thiết kế cho trình duyệt trên máy tính. Điều này làm cho trang web của bạn có chiều rộng lớn hơn (thường là 980px) và điều chỉnh theo tỷ lệ để vừa với chiều rộng WebView. Trong hầu hết các trường hợp, điều này dẫn đến một phiên bản tổng quan nhỏ của trang yêu cầu người dùng kéo và thu phóng để thực sự đọc nội dung.

Nếu bạn muốn chiều rộng của trang web bằng 100% chiều rộng của WebView, hãy đặt thẻ meta khung nhìn:

<meta name="viewport" content="width=device-width, initial-scale=1">

Đặt chiều rộng thành giá trị đặc biệt device-width để có thêm quyền kiểm soát bố cục trang.

Theo mặc định, WebView đặt khung nhìn thành chiều rộng của thiết bị, thay vì mặc định là khung nhìn máy tính. Tuy nhiên, để có hành vi đáng tin cậy và được kiểm soát, bạn nên thêm thẻ meta khung nhìn.

Hiển thị trang web dành cho máy tính

Trong một số trường hợp, bạn có thể cần hiển thị nội dung không được thiết kế cho thiết bị di động. Ví dụ: bạn có thể hiển thị nội dung mà bạn không kiểm soát. Trong trường hợp này, bạn có thể buộc WebView sử dụng khung nhìn có kích thước máy tính:

Nếu bạn không đặt các phương thức này không chỉ định khung nhìn, thì WebView sẽ cố gắng đặt chiều rộng khung nhìn dựa trên kích thước nội dung.

Ngoài ra, bạn nên sử dụng thuật toán bố cục TEXT_AUTOSIZING để tăng kích thước phông chữ giúp dễ đọc hơn trên thiết bị di động. Xem setLayoutAlgorithm.

Sử dụng thiết kế thích ứng

Thiết kế thích ứng là một phương pháp thiết kế giao diện thay đổi dựa trên kích thước màn hình.

Có một số cách để triển khai thiết kế thích ứng. Một trong những truy vấn phổ biến nhất là truy vấn @media. Truy vấn này áp dụng CSS cho các phần tử dựa trên đặc điểm của thiết bị.

Ví dụ: giả sử bạn muốn chuyển từ bố cục dọc sang bố cục ngang dựa trên hướng. Đặt thuộc tính CSS thành mặc định là dọc:

.page-container {
    display: -webkit-box;
    display: flex;

    -webkit-box-orient: vertical;
    flex-direction: column;

    padding: 20px;
    box-sizing: border-box;
}

Để chuyển sang bố cục ngang, hãy chuyển đổi thuộc tính flex-direction dựa trên hướng:

@media screen and (orientation: landscape) {
  .page-container.notification-opened {
    -webkit-box-orient: horizontal;
    flex-direction: row;
  }

  .page-container.notification-opened > .notification-arrow {
    margin-right: 20px;
  }
}

Bạn cũng có thể thay đổi bố cục dựa trên chiều rộng màn hình.

Ví dụ: điều chỉnh kích thước chiều rộng của nút từ 100% thành kích thước nhỏ hơn khi kích thước màn hình thực tế lớn hơn.

button {
  display: block;
  width: 100%;
  ...
}

@media screen and (min-width: 500px) {
  button {
    width: 60%;
  }
}

@media screen and (min-width: 750px) {
  button {
    width: 40%;
    max-width: 400px;
  }
}

Đây là những thay đổi nhỏ, nhưng tuỳ thuộc vào giao diện người dùng, truy vấn nội dung đa phương tiện có thể giúp bạn thực hiện những thay đổi lớn hơn về giao diện của ứng dụng, trong khi vẫn giữ nguyên HTML.

Hình ảnh sắc nét và rõ ràng

Sự đa dạng về kích thước và mật độ màn hình cũng gây ra nhiều thách thức cho hình ảnh. Hình ảnh nhỏ hơn cần ít bộ nhớ hơn và tải nhanh hơn, nhưng sẽ bị mờ nếu bạn tăng tỷ lệ.

Dưới đây là một số mẹo và thủ thuật để đảm bảo hình ảnh của bạn trông sắc nét và rõ ràng trên mọi màn hình:

  • Sử dụng CSS cho các hiệu ứng có thể mở rộng.
  • Sử dụng đồ hoạ vectơ.
  • Cung cấp ảnh có độ phân giải cao.

Sử dụng CSS cho các hiệu ứng có thể mở rộng

Sử dụng CSS bất cứ khi nào có thể thay vì hình ảnh. Có thể một số tổ hợp thuộc tính CSS có thể tốn kém để hiển thị. Luôn kiểm thử các tổ hợp cụ thể mà bạn đang sử dụng.

Tìm hiểu thêm về Hiển thị nội dung đầu tiên (FCP). Chỉ số này đo lường thời gian từ khi người dùng truy cập vào trang lần đầu tiên cho đến khi bất kỳ phần nào của nội dung trang được hiển thị trên màn hình. "Nội dung" đề cập đến văn bản, hình ảnh (bao gồm cả hình nền), phần tử <svg> và phần tử <canvas> không phải màu trắng.

Sử dụng đồ hoạ vectơ

Đồ hoạ vectơ có thể mở rộng (SVG) là một cách tuyệt vời để cung cấp hình ảnh có thể mở rộng. Đối với những hình ảnh phù hợp với đồ hoạ vectơ, SVG cung cấp hình ảnh chất lượng cao với kích thước tệp rất nhỏ.

Cung cấp ảnh có độ phân giải cao

Sử dụng ảnh phù hợp với thiết bị có DPI cao và điều chỉnh tỷ lệ hình ảnh bằng CSS. Bằng cách này, hình ảnh có thể hiển thị ở chất lượng cao trên các thiết bị. Nếu sử dụng chế độ nén cao (chế độ cài đặt chất lượng thấp) khi tạo hình ảnh, bạn có thể đạt được kết quả hình ảnh tốt với kích thước tệp hợp lý.

Phương pháp này có một số nhược điểm tiềm ẩn: hình ảnh được nén nhiều có thể hiển thị một số hiện tượng hình ảnh, vì vậy, bạn cần thử nghiệm để xác định mức độ nén mà bạn cho là chấp nhận được. Việc đổi kích thước hình ảnh trong CSS có thể là một thao tác tốn kém.

Nếu phương thức nén cao không phù hợp với nhu cầu của bạn, hãy thử định dạng WebP. Định dạng này cung cấp hình ảnh chất lượng cao với kích thước tệp tương đối nhỏ. Hãy nhớ cung cấp phương án dự phòng cho các phiên bản Android không hỗ trợ WebP.

Kiểm soát chi tiết

Trong nhiều trường hợp, bạn không thể sử dụng một hình ảnh cho tất cả thiết bị. Trong trường hợp này, bạn có thể chọn nhiều hình ảnh dựa trên kích thước và mật độ màn hình. Sử dụng truy vấn nội dung đa phương tiện để chọn hình nền theo kích thước và mật độ màn hình.

Bạn có thể sử dụng JavaScript để kiểm soát cách tải hình ảnh, nhưng điều này sẽ làm tăng độ phức tạp.

Truy vấn nội dung nghe nhìn và mật độ màn hình

Để chọn hình ảnh dựa trên mật độ màn hình, bạn cần sử dụng đơn vị dpi hoặc dppx trong truy vấn nội dung nghe nhìn. Đơn vị dpi biểu thị số điểm trên mỗi inch CSS và dppx biểu thị số điểm trên mỗi pixel CSS.

Trong bảng sau, bạn có thể thấy mối quan hệ giữa dpidppx.

Tỷ lệ pixel của thiết bị Mật độ màn hình tổng quát Số điểm trên mỗi inch CSS (dpi) Số chấm trên mỗi pixel CSS (dppx)
1x MDPI 96dpi 1dppx
Gấp 1,5 lần HDPI 144dpi 1,5dppx
2 XHDPI 192dpi 2dppx

Các nhóm mật độ màn hình tổng quát do Android xác định và được sử dụng ở các nơi khác để thể hiện mật độ màn hình (ví dụ: https://screensiz.es).

Hình nền

Bạn có thể sử dụng truy vấn nội dung đa phương tiện để chỉ định hình nền cho các phần tử. Ví dụ: nếu có hình ảnh biểu trưng có kích thước 256px x 256px trên một thiết bị có tỷ lệ pixel là 1,0, bạn có thể sử dụng các quy tắc CSS sau:

.welcome-header > h1 {
  flex: 1;

  width: 100%;

  max-height: 256px;
  max-width: 256px;

  background-image: url('../images/html5_256x256.png');
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
}

Để hoán đổi hình ảnh này cho một hình ảnh lớn hơn trên các thiết bị có tỷ lệ pixel thiết bị là 1,5 (hdpi) và 2,0 (xhdpi), bạn có thể thêm các quy tắc sau:

@media screen and (min-resolution: 1.5dppx) {
  .welcome-header > h1{
    background-image: url('../images/html5_384x384.png');
  }
}

@media screen and (min-resolution: 2dppx) {
  .welcome-header > h1{
    background-image: url('../images/html5_512x512.png');
  }
}

Sau đó, bạn có thể hợp nhất kỹ thuật này với các truy vấn nội dung nghe nhìn khác, chẳng hạn như min-width. Điều này sẽ hữu ích khi bạn tính đến nhiều kiểu dáng thiết bị.

@media screen and (min-resolution: 2dppx) {
  .welcome-header > h1{
    background-image: url('../images/html5_512x512.png');
  }
}

@media screen and (min-resolution: 2dppx) and (min-width: 1000px) {
  .welcome-header > h1{
    background-image: url('../images/html5_1024x1024.png');

    max-height: 512px;
    max-width: 512px;
  }
}

Bạn có thể nhận thấy rằng max-heightmax-width được đặt thành 512px cho độ phân giải 2ddpx, với hình ảnh 1024x1024px. Điều này là do "pixel" CSS thực sự tính đến tỷ lệ pixel của thiết bị (512px * 2 = 1024px).

Còn <img/> thì sao?

Hiện nay, web không có giải pháp cho vấn đề này. Có một số đề xuất, nhưng các đề xuất này không có trong các trình duyệt hiện tại hoặc trong WebView.

Trong thời gian chờ đợi, nếu tạo DOM trong JavaScript, bạn có thể tạo nhiều tài nguyên hình ảnh trong một cấu trúc thư mục hợp lý:

images/
  mdpi/
    imagename.png
  hdpi/
    imagename.png
  xhdpi/
    imagename.png

Sau đó, hãy sử dụng tỷ lệ pixel để cố gắng lấy hình ảnh phù hợp nhất:

function getDensityDirectoryName() {
  if(!window.devicePixelRatio) {
    return 'mdpi';
  }

  if(window.devicePixelRatio > 1.5) {
    return 'xhdpi';
  } else if(window.devicePixelRatio > 1.0) {
    return 'hdpi';
  }

  return 'mdpi';
}

Ngoài ra, bạn có thể thay đổi URL cơ sở của trang để xác định các URL tương đối cho hình ảnh.

<!doctype html>
<html class="no-js">
<head>
  <script>
    function getDensityDirectoryName() {
      if(!window.devicePixelRatio) {
          return 'mdpi';
      }

      if(window.devicePixelRatio > 1.5) {
          return 'xhdpi';
      } else if(window.devicePixelRatio > 1.0) {
          return 'hdpi';
      }

      return 'mdpi';
    }

    var baseUrl =
        'file:///android_asset/www/img-js-diff/ratiores/'+getDensityDirectoryName()+'/';
    document.write('<base href="'+baseUrl+'">');
  </script>

    ...
</head>
<body>
    ...
</body>
</html>

Phương pháp này chặn việc tải trang và buộc sử dụng đường dẫn tuyệt đối cho tất cả tài nguyên, chẳng hạn như hình ảnh, tập lệnh và tệp CSS, vì URL cơ sở trỏ đến một thư mục dành riêng cho mật độ.