實現一個帶浮動標籤的輸入框

如今帶浮動標籤的輸入框也是一個很常見的東西了,在材料設計裏面有一個 TextInputLayout 的控件,咱們能夠用它實現這個效果。可是材料設計控件的樣式比較固定,並不能知足咱們產品設計的腦洞。這裏提供一個用屬性動畫實現的方法。php

仍是先看看效果吧:java

大概的思路是這樣的:android

  • 控件有兩層,一層是浮動的標籤,一層是輸入框。
  • 當點擊控件後,標籤同時執行一個橫向和縱向的縮放動畫,還有一個向上移動的動畫,讓輸入框獲取到焦點並彈出鍵盤。
  • 當輸入框失去焦點時,判斷是否有內容,若是沒有則讓標籤執行一個復原的動畫。

下面看看控件的佈局:bash

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/fl_content" android:layout_width="match_parent" android:layout_height="55dp" android:background="@color/white" android:orientation="vertical" android:paddingLeft="20dp">

    <EditText android:id="@+id/et_content_name" android:layout_width="match_parent" android:layout_height="30dp" android:layout_gravity="center_vertical" android:background="@color/white" android:textColor="@color/black" android:textCursorDrawable="@null" android:textSize="14sp" android:visibility="gone" />

    <TextView android:id="@+id/tv_content_hint" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:text="標題" android:textColor="@color/text_gray" android:textSize="14sp" android:transformPivotX="0dp" android:transformPivotY="-30dp" />

</FrameLayout>
複製代碼

因爲 EditText 會默認獲取到焦點,因此我先把它隱藏了。這裏面值得注意的是 transformPivotXY 這個參數,等下會講到。ide

而後咱們建立標籤向上縮放的方法,代碼以下:佈局

public void animationUp() {
    ObjectAnimator scaleX = ObjectAnimator.ofFloat(tvHint, "scaleX", 0.6f);
    ObjectAnimator scaleY = ObjectAnimator.ofFloat(tvHint, "scaleY", 0.6f);

    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.setDuration(100);
    animatorSet.setInterpolator(new DecelerateInterpolator());
    animatorSet.play(scaleX).with(scaleY); //兩個動畫同時開始
    animatorSet.start();

    animatorSet.addListener(new Animator.AnimatorListener() {
        @Override
        public void onAnimationStart(Animator animation) {
        }

        @Override
        public void onAnimationEnd(Animator animation) {
            etContent.setVisibility(View.VISIBLE);
            etContent.requestFocus();
            //彈出鍵盤
            InputMethodManager imm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
            imm.showSoftInput(etContent, 0);
        }

        @Override
        public void onAnimationCancel(Animator animation) {
        
        }

        @Override
        public void onAnimationRepeat(Animator animation) {

        }
    });
}

複製代碼

代碼不難理解,就是同時執行了橫向和縱向的縮放動畫,讓標籤縮小到 60%。動畫執行完後顯示EditText,讓它獲取到焦點並彈出鍵盤。若是 animatorSet.setInterpolator(new DecelerateInterpolator()); 這句不懂的話,看看下面這張圖就明白了:動畫

Interpolator.png

到這裏,你可能還有的一個疑問就是,向上移動的動畫呢?
縮放動畫是根據控件的基準座標來進行縮放的。也就是說,當咱們把基準座標設在控件上方時,縮放的時候也會有一個移動的效果。因此在佈局裏面用spa

android:transformPivotX="0dp"
android:transformPivotY="-30dp"
複製代碼

將標籤的基準點設爲 (0dp, -30dp),這樣咱們就省去了移動動畫。設計

至於復原的動畫,就更簡單了:code

public void animationDown() {
    etContent.setVisibility(View.GONE);

    ObjectAnimator scaleX = ObjectAnimator.ofFloat(tvHint, "scaleX", 1);
    ObjectAnimator scaleY = ObjectAnimator.ofFloat(tvHint, "scaleY", 1);

    AnimatorSet animatorSet = new AnimatorSet();
    animatorSet.setDuration(100);
    animatorSet.setInterpolator(new DecelerateInterpolator());
    animatorSet.play(scaleX).with(scaleY); //兩個動畫同時開始
    animatorSet.start();
}
複製代碼

爲了實現失去焦點,標籤復原,咱們須要監聽輸入框是否有焦點:

etContent.setOnFocusChangeListener(new OnFocusChangeListener() {
    @Override
    public void onFocusChange(View view, boolean b) {
        if (!b && TextUtils.isEmpty(etContent.getText())) {
            animationDown();
        }
    }
});
複製代碼

這樣就已經完成了一個帶浮動標籤的輸入框,妥妥的。

雖然實現一個這樣的控件不難,但我我的仍是但願能夠使用原生控件的,但願移動端的設計能多去了解一下材料設計吧。(T_T)

相關文章
相關標籤/搜索