+1

Android Square App Widget | Tiện ích vuông trong Android

I. App widget là gì?

Widget là những tiện ích nhỏ gọn được hiển thị trực tiếp trên màn hình chính hoặc màn hình khóa của điện thoại. Nó cung cấp cho người dùng quyền truy cập nhanh chóng vào chức năng nhất định của ứng dụng mà không cần phải mở toàn bộ ứng dụng. Ngoài ra, widget cũng cung cấp những thông tin quan trọng, chức năng chính của ứng dụng đến người dùng.

II. Lợi ích

  • Trang trí màn hình chính của điện thoại.
  • Widget mang lại sự tiện lợi cho người dùng bằng cách đưa các tính năng thường dùng của các ứng dụng yêu thích ngay trong tầm tay.
  • Nhờ widget, bạn không cần phải mở ứng dụng mỗi khi cần sử dụng một chức năng nào đó, giúp tiết kiệm thời gian và công sức.
  • Người dùng có thể di chuyển widget trên các trang màn hình chính và thay đổi kích thước của chúng để phù hợp với sở thích và nhu cầu của họ.

III. Square Widget (widget vuông)

1. Cách Android hiển thị Widget trên màn hình

Android sử dụng một hệ thống gọi là grid layout để hiển thị các widget trên màn hình chính. Hệ thống này chia màn hình thành các ô nhỏ, được gọi là cell. Mỗi widget được gán cho một số lượng cell nhất định, xác định kích thước của widget. Khi bạn thêm widget vào màn hình chính, Android sẽ tự động sắp xếp widget dựa trên kích thước của chúng và số lượng cell có sẵn. Bạn cũng có thể di chuyển và thay đổi kích thước widget thủ công.

Một số lưu ý về cell

  • Số lượng cell trên màn hình chính có thể thay đổi tùy thuộc vào thiết bị: Một số thiết bị có nhiều cell hơn các thiết bị khác.
  • Một số widget có thể chiếm nhiều cell hơn: Một số widget có thể chiếm nhiều cell theo chiều ngang hoặc chiều dọc.
  • Bạn có thể thay đổi kích thước mặc định của cell: Bạn có thể thay đổi kích thước mặc định của cell trong cài đặt của thiết bị.

Có một yếu tố đặc biệt là chiều dài và chiều rộng của 1 cell không hẳn sẽ bằng nhau

Vì vậy, trong khi bạn làm Android widget, nếu bạn nghĩ là nếu mình set size cho Widget là 2x2 hay 3x3 sẽ tạo được một widget hình vuông thì điều đó hoàn toàn sai vì như đã nói ở trên, số lượng và kích thước cell sẽ phụ thuộc vào từng loại điện thoại khác nhau.

2. Những cách tiếp cận nhưng không thành công

Ở phần này mình muốn trình bày cho mọi người thấy một số cách tiếp cận mà mình đã thử nhưng không thành công. Sở dĩ mình nêu ra những cách này vì có thể nó sẽ được áp dụng trong một số trường hợp khác mà bạn có thể cần.

Nếu bạn muốn đến trực tiếp tới phần tạo Widget vuông như thế nào bạn có thể xem phần tiếp theo nha.

- Sử dụng thuộc tính của Layout:

Nếu bạn đã biết về css có lẽ bạn sẽ biết thuộc tính aspectRatio được sử dụng để xác định tỷ lệ giữa chiều rộng và chiều cao của một phần tử. Nó cho phép bạn đảm bảo rằng phần tử sẽ giữ nguyên tỷ lệ này khi thay đổi kích thước (nghĩa là khi aspectRatio là 1 thì tỉ lệ giữa chiều rộng và chiều dài là bằng nhau - hình vuông).

Dựa vào điều này, mình đã thử áp dụng nó cho root Layout của widget nhưng thuộc tính layout_constraintRatio chỉ có trong ConstraintLayout tuy nhiên Widget Layout dựa trên RemoteViews, không hỗ trợ tất cả loại Layout, custom Layout,...

Vì vậy nên cách sử dụng ConstraintLayout cùng với thuộc tính aspectRatio không khả thi trong trường hợp này

- Sử dụng custom Layout

public class CustomSquareFrameLayout extends FrameLayout {

    public CustomSquareFrameLayout(Context context) {
        super(context);
    }

    public CustomSquareFrameLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomSquareFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    
        // Ensure the widget is always square
        int size = Math.min(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
        setMeasuredDimension(size, size);
    }
}

onMeasure cung cấp một cách để bạn điều chỉnh chiều rộng và chiều cao của layout. Nếu bạn không override hàm này, layout g theo cách tương tự khi match_parent và wrap_content được sử dụng để xác định kích thước của nó.

Chi tiết hơn về onMeasure() các bạn có thể xem tại đây.

Nhưng cũng giống như mình đã giải thích ở trên, Widget không thể sử dụng những Custom view hay subclasses.

Mặc dù 2 cách này mình không áp dụng thành công để xây dựng một Widget hình vuông trong Android nhưng mình mong rằng nó có thể giúp mọi người hiểu thêm về ConstraintLayout và Custom Layout để có thể áp dụng trong những trường hợp khác.

Tiếp theo mình cùng đến với phần chính của bài viết này nhé

3. Square Widget

Gần giống như cách mình sử dụng CustomLayout, mình sẽ lấy giá trị của chiều ngang sau đó set chiều dài bằng với chiều ngang của widget layout thông qua những hàm có sẵn của RemoteViews.

static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
                                int appWidgetId) {
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.i_mental_widget);

            Bundle options = appWidgetManager.getAppWidgetOptions(appWidgetId);

            int size = options.getInt(appWidgetManager.OPTION_APPWIDGET_MIN_WIDTH);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
                views.setViewLayoutHeight(R.id.widgetView, size, TypedValue.COMPLEX_UNIT_DIP);
            }
            appWidgetManager.updateAppWidget(appWidgetId, views);
}

Trong đó

  • options: Thông tin được truy xuất từ việc yêu cầu hệ thống Android cung cấp thông tin về một phiên bản widget cụ thể được xác định bởi appWidgetId của nó.
  • size: Lấy thông tin chiều dài của widget thông qua hàm getInt(appWidgetManager.OPTIONAPPWIDGETMINWIDTH)
  • R.id.widgetView: Đây là id của rootLayout trong file UI (xml) của widget
  • TypedValue.COMPLEX_UNIT_DIP: Đơn vị mà mình muốn set (ở đây là dp) Cuối cùng, bạn phải gọi appWidgetManager.updateAppWidget(appWidgetId, views) để Widget được update nhé.

Có một điều cần lưu ý ở đây là setViewLayoutHeight chỉ có từ phiên bản Android S (Android 12) trở lên. Nếu người dùng sử dụng Android phiên bản dưới 12 thì không thể tạo ra Square Widget.

Hình bên dưới là square widget sau khi hoàn thành, mặc dù với kích thước là 2x2 cell nhưng phần hiển thị của widget sẽ là hình vuông và chiều dài sẽ được gán dựa trên chiều rộng.

image.png

Những nội dung trên được mình tìm hiểu trong lúc thực hiện, nên có thể có nhiều sai sót hoặc hiểu chưa đúng. Mình mong rằng mọi người có thể góp ý, chia sẻ thêm.

Xin cảm ơn tất cả mọi người đã đọc, nếu có bất cứ thắc mắc hoặc cần gì mọi người có thể liên hệ với mình nha

#widget #androidwidget #squarewidget


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí