如今帶浮動標籤的輸入框也是一個很常見的東西了,在材料設計裏面有一個 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()); 這句不懂的話,看看下面這張圖就明白了:動畫
到這裏,你可能還有的一個疑問就是,向上移動的動畫呢?
縮放動畫是根據控件的基準座標來進行縮放的。也就是說,當咱們把基準座標設在控件上方時,縮放的時候也會有一個移動的效果。因此在佈局裏面用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)