Android TV控制元件獲得焦點的掃光效果

2020-10-01 16:00:41

目錄

 

前言

效果展示

實現思路

使用方法

完成的原始碼和demo


前言

Android TV開發與手機開發最大的不同點就是焦點,TV常用的操作方式是遙控器,所以給使用者一個醒目美觀的焦點是至關重要的。很多產品經理在設計焦點的時候都會選擇掃光的效果,比如小牧電視的控制元件選中效果。今天就給大家介紹一款自定義的掃光效果控制元件。

效果展示

1、海報掃光效果

2、帶圓角的控制元件掃光效果,光效不會超過圓角的位置

3、掃光容器,可以在掃光容器中放子控制元件,目前僅實現了LinearLayout

4、圖片掃光效果,光效與圖片中不透明內容交融的一種效果

實現思路

這一組控制元件的實現思路,其實很簡單,就是光效bitmap的移動,可以是移動畫布,也可以是移動bitmap,兩種思路都可以實現。當然其中在實現圓角掃光、光效與圖片內容交融等效果時,用到一個比較重要的知識點,就是PorterDuffXfermode。具體介紹Xfermode或者PorterDuffXfermode的文章可以去網上搜一下,有很多。簡單講PorterDuffXfermode是一個非常強大的轉換模式,使用它,可以使用影象合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas影象進行互動。

PorterDuffXfermode的風格就是上面的16中,我們可以簡單的理解為一個SRC圖形與DST圖形的交集,並集類似的效果,在我們這組控制元件中,主要用到了DST_ATOP、DST_IN。詳細使用方法可參考控制元件原始碼。

使用方法

首先需要引入library:

implementation 'com.beauney.scanning:scanning-view:1.0.1'

1、海報斜向的掃光效果控制元件使用

xml中使用控制元件:

    <FrameLayout
        android:layout_width="283dp"
        android:layout_height="159dp"
        android:layout_marginStart="20dp"
        android:layout_marginTop="20dp"
        android:focusable="true"
        android:focusableInTouchMode="true">

        <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/temp_demand_3" />

        <com.beauney.scanning.library.ScanningView
            android:tag="scanning_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="#66000000"/>
    </FrameLayout>

java程式碼中呼叫start()、stop()方法:

        RelativeLayout container = findViewById(R.id.container);

        for (int i = 0; i < container.getChildCount(); i++) {
            container.getChildAt(i).setOnFocusChangeListener(new View.OnFocusChangeListener() {
                @Override
                public void onFocusChange(View view, boolean b) {
                    ScanningView scanningView = view.findViewWithTag("scanning_view");
                    if (b) {
                        AnimatorUtil.scaleBigAnimator(view);
                        scanningView.start();
                    } else {
                        AnimatorUtil.scaleSmallAnimator(view);
                        scanningView.stop();
                    }
                }
            });
        }

該控制元件提供了自定義屬性lightImage,可以自定義更換光效圖片:

        <com.beauney.scanning.library.ScanningView
            android:tag="scanning_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:lightImage="@drawable/scanning_view_light"
            android:background="#66000000"/>

圖片製作參考預設掃光圖片

2、帶圓角的豎向掃光效果控制元件使用

xml中使用控制元件:

    <FrameLayout
        android:id="@+id/next_text_container"
        android:layout_width="334dp"
        android:layout_height="73dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp">

        <View
            android:id="@+id/next_text_bg"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@drawable/ad_text_bg_shape" />

        <TextView
            android:id="@+id/next_text"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="center_horizontal"
            android:layout_marginTop="18dp"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:text="按OK鍵進入下一步"
            android:textColor="#dddddd"
            android:textSize="18sp" />

        <ProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/video_progress_bar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="294dp"
            android:layout_height="10dp"
            android:layout_gravity="bottom"
            android:layout_marginBottom="14dp"
            android:layout_marginStart="20dp"
            android:background="@null"
            android:progress="100"
            android:progressDrawable="@drawable/ad_progress_selector"/>

        <com.beauney.scanning.library.ScanningRoundView
            android:id="@+id/scanning_round_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </FrameLayout>

java程式碼中呼叫start()、stop()方法:

mScanningRoundView.start();

mScanningRoundView.stop();

該控制元件提供了兩個自定義屬性,用於修改光效圖片和圓角角度,參考如下程式碼:

        <com.beauney.scanning.library.ScanningRoundView
            android:id="@+id/scanning_round_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:roundRadius="10dp"
            app:roundLightImage="@drawable/round_light"/>

圖片製作參考預設掃光圖片,這裡沒有采用9patch的圖片,所以控制元件高度要和光效圖片的高度一致。

3、帶圓角的掃光容器使用

xml中使用控制元件:

    <com.beauney.scanning.library.ScanningLinearLayout
        android:id="@+id/scanning_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp">

        <TextView
            android:id="@+id/language_cn_btn"
            android:layout_width="127dp"
            android:layout_height="27dp"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center"
            android:text="中文"
            android:textColor="#999999"
            android:background="@drawable/language_cn_nor"
            android:textSize="18sp" />

        <TextView
            android:id="@+id/language_en_btn"
            android:layout_width="127dp"
            android:layout_height="27dp"
            android:clickable="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:gravity="center"
            android:text="English"
            android:background="@drawable/language_en_sel"
            android:textColor="#ffffff"
            android:textSize="18sp" />
    </com.beauney.scanning.library.ScanningLinearLayout>

 java程式碼中呼叫start()、stop()方法:

mScanningLayout.start();
mScanningLayout.stop();

 同樣提供了兩個自定義屬性,用於修改光效圖片和圓角角度,參考如下程式碼:

    <com.beauney.scanning.library.ScanningLinearLayout
        android:id="@+id/scanning_container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layoutRadius="10dp"
        app:layoutLightImage="@drawable/layount_light"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="30dp">
    </com.beauney.scanning.library.ScanningLinearLayout>

 圖片製作參考預設掃光圖片,這裡沒有采用9patch的圖片,所以控制元件高度要和光效圖片的高度一致。

4、圖片掃光效果控制元件使用

xml中使用控制元件:

    <FrameLayout
        android:layout_width="83dp"
        android:layout_height="63dp"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="60dp"
        android:layout_gravity="center_horizontal">

        <ImageView
            android:id="@+id/icon_img"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:contentDescription="aaaa"
            android:src="@drawable/icon_choose_sel" />

        <com.beauney.scanning.library.ScanningImageView
            android:id="@+id/scanning_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    </FrameLayout>

java程式碼中呼叫相關方法

    public void startScanning(View view) {
        //啟動控制元件動效之前需要將原始的圖片傳入
        if (mScanningImageView.getSrcBitmap() == null) {
            mScanningImageView.setSrcBitmap(ScreenCapture.captureWidget(mIconImg));
        }
        mScanningImageView.start();
    }

    public void stopScanning(View view) {
        mScanningImageView.stop();
    }

該控制元件提供了一個自定義屬性,用於修改光效顏色,參考如下程式碼:

        <com.beauney.scanning.library.ScanningImageView
            android:id="@+id/scanning_view"
            android:layout_width="match_parent"
            android:layout_height="match_parent" 
            app:lightColor="@color/colorAccent"/>

完成的原始碼和demo

Github地址