[Android] Hướng dẫn tạo Dialog với hiệu ứng Circular Reveal

0
39

Đã lâu rồi mình mới có thời gian rảnh để ngồi viết bài và bình luận với các bạn. Nhân tiện mấy hôm nay cả nước đang tràn ngập trong niềm vui sướng khi lần đầu U23 Việt Nam vào tứ kết (bây giờ thì đã là chung kết rồi :D), mình sẽ viết một chia sẻ ngắn làm thế nào tạo được một dialog “đẹp xinh” và có animation uyển chuyển.  Các bạn xem ảnh demo bên dưới để biết kết quả sau khi thực hiện nhé!

[Android] Hướng dẫn tạo Dialog với hiệu ứng Circular Reveal

Note:  Các bạn chú ý nhé, animation này yêu cầu  tối thiểu SDK version là 21.

Bước 1: Tạo các file layout xml cho dialog và cho MainActivity

<?xml version=”1.0" encoding=”utf-8"?>
<RelativeLayout
     xmlns:android=”http://schemas.android.com/apk/res/android"
     android:orientation=”vertical”
     android:layout_width=”match_parent”
     android:id=”@+id/dialog”
     android:layout_height=”match_parent”
     android:background=”@color/colorAccent”>
    <ImageView
        android:id=”@+id/closeDialogImg”
        android:layout_width=”30dp”
        android:layout_height=”30dp”
        android:layout_margin=”10dp”
        android:src=”@drawable/ic_close_black_24dp”
        android:tint=”#fff”/>
    <RelativeLayout
        android:layout_width=”match_parent”
        android:layout_height=”150dp”
        android:background=”#FFF”
        android:layout_centerInParent=”true”
        android:layout_marginEnd=”20dp”
        android:layout_marginStart=”20dp”
        android:orientation=”vertical”>
   <TextView
        android:layout_width=”wrap_content”
        android:layout_height=”wrap_content”
        android:layout_centerInParent=”true”
        android:text=”This is my Dialog”
        android:textSize=”24dp”/>
   </RelativeLayout>
</RelativeLayout>
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/activity_main"
    tools:context="beaststudio.in.revealanimation.MainActivity">


    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="56dp"
        android:layout_height="56dp"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        android:layout_margin="24dp"
        android:src="@drawable/ic_add_black_24dp"
        android:tint="#fff"
        />

</RelativeLayout>

Bước 2: Sau khi đã có layout ngon lành cành đào rồi thì mình sẽ thực hiện code logic trong file Java. Phần logic này sẽ xử lý việc hiển thị dialog khi click vào floating button.

FloatingActionButton fab;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        fab = (FloatingActionButton)findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                showDiag();
            }
        });
}

Như các bạn thấy đoạn code ở trên, chúng ta bắt sự kiện click/touch của người dùng bằng API setOnClickListener. Trong đoạn xử lý sự kiện này mình có viết sẵn một hàm showDiag() để hiển thị dialog.

Trong hàm hiển thị dialog này thì mình lưu ý đến một API quan trọng –  revealShow(dialogView, true, dialog) – hàm này được dùng để tạo animation hình tròn khi hiển thị dialog.

Hàm này có 3 tham số cần truyền vào:

  • dialogView: Chính là view mà bạn nhồi vào layout xml đã tạo ở bước 1.
  • boolean: Nếu bạn muốn hiển thị dialog thì truyển TRUE, muốn ẩn dialog thì truyền FALSE.
  • dialog: Tham số này bạn chỉ cần truyền dialog object vào là được.

Code hoàn chỉnh cho hàm showDiag() như bên dưới nhé!

private void showDiag() {

    final View dialogView = View.inflate(this,R.layout.dialog,null);

    final Dialog dialog = new Dialog(this,R.style.MyAlertDialogStyle);
    dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
    dialog.setContentView(dialogView);

    ImageView imageView = (ImageView)dialog.findViewById(R.id.closeDialogImg);
    imageView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            revealShow(dialogView, false, dialog);
        }
    });

    dialog.setOnShowListener(new DialogInterface.OnShowListener() {
        @Override
        public void onShow(DialogInterface dialogInterface) {
            revealShow(dialogView, true, null);
        }
    });

    dialog.setOnKeyListener(new DialogInterface.OnKeyListener() {
        @Override
        public boolean onKey(DialogInterface dialogInterface, int i, KeyEvent keyEvent) {
            if (i == KeyEvent.KEYCODE_BACK){

                revealShow(dialogView, false, dialog);
                return true;
            }

            return false;
        }
    });



    dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));

    dialog.show();
}

Và đây là đoạn mã của hàm revelShow().

private void revealShow(View dialogView, boolean b, final Dialog dialog) {

    final View view = dialogView.findViewById(R.id.dialog);

    int w = view.getWidth();
    int h = view.getHeight();

    int endRadius = (int) Math.hypot(w, h);

    int cx = (int) (fab.getX() + (fab.getWidth()/2));
    int cy = (int) (fab.getY())+ fab.getHeight() + 56;


    if(b){
        Animator revealAnimator = ViewAnimationUtils.createCircularReveal(view, cx,cy, 0, endRadius);

        view.setVisibility(View.VISIBLE);
        revealAnimator.setDuration(700);
        revealAnimator.start();

    } else {

        Animator anim =
                ViewAnimationUtils.createCircularReveal(view, cx, cy, endRadius, 0);

        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                dialog.dismiss();
                view.setVisibility(View.INVISIBLE);

            }
        });
        anim.setDuration(700);
        anim.start();
    }

}

Bước 3: Bây giờ đến phần chúng ta chỉnh sửa file style.xml.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="MyAlertDialogStyle" parent="Theme.AppCompat.Light.Dialog.Alert">

        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:windowIsFloating">false</item>
        <item name="android:windowBackground">@color/colorAccent</item>
    </style>
</resources>

Cuối cùng là toàn bộ source code cho bài viết hướng dẫn này: https://github.com/divyanshub024/RevealAnimation

Nếu bạn có bất cứ câu hỏi nào thì comment bên dưới nhé!

Đừng quên like và share nữa nha!

BÌNH LUẬN

Please enter your comment!
Please enter your name here