FloatLabel介绍——Android(安卓)EditText的一种交互实现
16lz
2022-01-12
这里介绍一种EditText的交互实现,这里是最初的设计->https://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction,这里是之后在Android上的实现->https://gist.github.com/chrisbanes/11247418#file-attrs-xml,看了下作者的其他项目,就是Andorid—PullDownToRefresh的作者。
原理很简单,对EditText包裹了一个容器FrameLayout,并在layout里自动添加一个对应的TextView,当EditText有输入的时候对TextView做动画显示出来。下面是具体的使用过程:
1、布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <com.example.floatlabeldemo.FloatLabelLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" app:floatLabelTextAppearance="@style/TextAppearance.YourApp.FloatLabel"> <EditText android:id="@+id/edit_username" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/account_username_hint" android:singleLine="true" android:inputType="textNoSuggestions" android:imeOptions="actionNext" android:nextFocusDown="@+id/edit_password" /> </com.example.floatlabeldemo.FloatLabelLayout> <com.example.floatlabeldemo.FloatLabelLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="16dp" app:floatLabelTextAppearance="@style/TextAppearance.YourApp.FloatLabel"> <EditText android:id="@+id/edit_password" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="@string/account_password_hint" android:singleLine="true" android:inputType="textNoSuggestions" android:imeOptions="actionDone" /> </com.example.floatlabeldemo.FloatLabelLayout> </LinearLayout>
tips:每个FloatLabelLayout里只能添加一个EditText
下面是FloatLabelLayout里的自定义参数 attrs.xml
<resources> <declare-styleable name="FloatLabelLayout"> <attr name="floatLabelTextAppearance" format="reference" /> <attr name="floatLabelSidePadding" format="reference|dimension" /> </declare-styleable> </resources>
其中的floatLabelTextAppearance是对TextView显示的一些设置,如下styles.xml
<style name="TextAppearance.YourApp.FloatLabel" parent="android:TextAppearance.Small"> <item name="android:textColor">@color/float_label</item> <item name="android:textSize">11sp</item> <item name="android:textStyle">bold</item> </style>
有上面这些就可以demo显示了,效果如下
下面是FloatLabelLayout的具体实现
/* * Copyright (C) 2014 Chris Banes * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import android.animation.Animator;import android.animation.AnimatorListenerAdapter;import android.content.Context;import android.content.res.TypedArray;import android.text.Editable;import android.text.TextUtils;import android.text.TextWatcher;import android.util.AttributeSet;import android.util.TypedValue;import android.view.Gravity;import android.view.View;import android.view.ViewGroup;import android.widget.EditText;import android.widget.FrameLayout;import android.widget.TextView; /** * Layout which an {@link android.widget.EditText} to show a floating label when the hint is hidden * due to the user inputting text. * * @see <a href="https://dribbble.com/shots/1254439--GIF-Mobile-Form-Interaction">Matt D. Smith on Dribble</a> * @see <a href="http://bradfrostweb.com/blog/post/float-label-pattern/">Brad Frost's blog post</a> */public final class FloatLabelLayout extends FrameLayout { private static final long ANIMATION_DURATION = 150; private static final float DEFAULT_PADDING_LEFT_RIGHT_DP = 12f; private EditText mEditText; private TextView mLabel; public FloatLabelLayout(Context context) { this(context, null); } public FloatLabelLayout(Context context, AttributeSet attrs) { this(context, attrs, 0); } public FloatLabelLayout(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); final TypedArray a = context .obtainStyledAttributes(attrs, R.styleable.FloatLabelLayout); final int sidePadding = a.getDimensionPixelSize( R.styleable.FloatLabelLayout_floatLabelSidePadding, dipsToPix(DEFAULT_PADDING_LEFT_RIGHT_DP)); mLabel = new TextView(context); mLabel.setPadding(sidePadding, 0, sidePadding, 0); mLabel.setVisibility(INVISIBLE); mLabel.setTextAppearance(context, a.getResourceId(R.styleable.FloatLabelLayout_floatLabelTextAppearance, android.R.style.TextAppearance_Small)); addView(mLabel, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); a.recycle(); } @Override public final void addView(View child, int index, ViewGroup.LayoutParams params) { if (child instanceof EditText) { // If we already have an EditText, throw an exception if (mEditText != null) { throw new IllegalArgumentException("We already have an EditText, can only have one"); } // Update the layout params so that the EditText is at the bottom, with enough top // margin to show the label final LayoutParams lp = new LayoutParams(params); lp.gravity = Gravity.BOTTOM; lp.topMargin = (int) mLabel.getTextSize(); params = lp; setEditText((EditText) child); } // Carry on adding the View... super.addView(child, index, params); } private void setEditText(EditText editText) { mEditText = editText; // Add a TextWatcher so that we know when the text input has changed mEditText.addTextChangedListener(new TextWatcher() { @Override public void afterTextChanged(Editable s) { if (TextUtils.isEmpty(s)) { // The text is empty, so hide the label if it is visible if (mLabel.getVisibility() == View.VISIBLE) { hideLabel(); } } else { // The text is not empty, so show the label if it is not visible if (mLabel.getVisibility() != View.VISIBLE) { showLabel(); } } } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } }); // Add focus listener to the EditText so that we can notify the label that it is activated. // Allows the use of a ColorStateList for the text color on the label mEditText.setOnFocusChangeListener(new OnFocusChangeListener() { @Override public void onFocusChange(View view, boolean focused) { mLabel.setActivated(focused); } }); mLabel.setText(mEditText.getHint()); } /** * @return the {@link android.widget.EditText} text input */ public EditText getEditText() { return mEditText; } /** * @return the {@link android.widget.TextView} label */ public TextView getLabel() { return mLabel; } /** * Show the label using an animation */ private void showLabel() { mLabel.setVisibility(View.VISIBLE); mLabel.setAlpha(0f); mLabel.setTranslationY(mLabel.getHeight()); mLabel.animate() .alpha(1f) .translationY(0f) .setDuration(ANIMATION_DURATION) .setListener(null).start(); } /** * Hide the label using an animation */ private void hideLabel() { mLabel.setAlpha(1f); mLabel.setTranslationY(0f); mLabel.animate() .alpha(0f) .translationY(mLabel.getHeight()) .setDuration(ANIMATION_DURATION) .setListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { mLabel.setVisibility(View.GONE); } }).start(); } /** * Helper method to convert dips to pixels. */ private int dipsToPix(float dps) { return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dps, getResources().getDisplayMetrics()); }}
在初始化的时候就会添加一个TextView,然后对EditText的输入进行监听,做相应的动画交互。因为使用了版本的api,所以在level11以前使用需要将动画效果用View Animation来实现。
更多相关文章
- Android(安卓)开关机动画
- Android图片堆叠效果实现
- Android中自定义控件之飞入飞出布局及随机布局实现方式
- 基于TCP和多线程实现无线鼠标键盘-Socket(2)
- android实现页面下方的Tab效果
- Android实现开机自启动无效问题
- Android屏幕中隐藏标题栏
- android 动态向Gallery中添加图片及倒影&&3D效果
- 浅谈Java中Collections.sort对List排序的两种方法
随机推荐
- JavaScript 通过native.js 调用Android原
- android 反汇编,修改,重新打包
- android常用控件应用之文本框(TextView)特
- Android(安卓)Studio运行程序出现Session
- Android Gradle manifestPlaceholders 占
- Android Studio 默认keystore 以及自定义
- Android API 中文 (55) ―― ListAdapter
- android中ActionBar以及其与Action Butto
- Android中http请求(C# MVC接收)
- [Android] 获取Android设备的唯一识别码|