原帖地址:https://gist.github.com/chrisbanes/11247418

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();}@Overridepublic final void addView(View child, int index, ViewGroup.LayoutParams params) {if (child instanceof EditText) {// If we already have an EditText, throw an exceptionif (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 labelfinal 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 changedmEditText.addTextChangedListener(new TextWatcher() {@Overridepublic void afterTextChanged(Editable s) {if (TextUtils.isEmpty(s)) {// The text is empty, so hide the label if it is visibleif (mLabel.getVisibility() == View.VISIBLE) {hideLabel();}} else {// The text is not empty, so show the label if it is not visibleif (mLabel.getVisibility() != View.VISIBLE) {showLabel();}}}@Overridepublic void beforeTextChanged(CharSequence s, int start, int count, int after) {}@Overridepublic 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 labelmEditText.setOnFocusChangeListener(new OnFocusChangeListener() {@Overridepublic 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() {@Overridepublic 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());}
}

attrs.xml

<!-- Copyright (C) 2014 Chris BanesLicensed 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 athttp://www.apache.org/licenses/LICENSE-2.0Unless required by applicable law or agreed to in writing, softwaredistributed 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 andlimitations under the License.
--><?xml version="1.0" encoding="utf-8"?>
<resources><declare-styleable name="FloatLabelLayout"><attr name="floatLabelTextAppearance" format="reference" /><attr name="floatLabelSidePadding" format="reference|dimension" /></declare-styleable></resources>

example_colors-float_label.xml

<?xml version="1.0" encoding="utf-8"?><selector xmlns:android="http://schemas.android.com/apk/res/android"><!-- The color when activated/focused (usually your app's accent color) --><item android:color="..." android:state_activated="true" /><!-- The color when not activated/focused (usually grey) --><item android:color="..." /></selector>

example_layout.xml

<?xml version="1.0" encoding="utf-8"?><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"><your.package.FloatLabelLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="16dp"app:floatLabelTextAppearance="@style/TextAppearance.YourApp.FloatLabel"><EditTextandroid: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" /></your.package.FloatLabelLayout><your.package.FloatLabelLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="16dp"app:floatLabelTextAppearance="@style/TextAppearance.YourApp.FloatLabel"><EditTextandroid: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" /></your.package.FloatLabelLayout></LinearLayout>

example_styles.xml

<?xml version="1.0" encoding="utf-8"?><resources><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></resources>

有个改版也不错,在原帖的评论里

https://gist.github.com/jromero/233cfd8ef22a8b8c29ea

android 自定义控件(FloatLabelLayout)相关推荐

  1. Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

    Android自定义控件NumberCircleProgressBar(圆形进度条)的实现

  2. android自定义view获取控件,android 自定义控件View在Activity中使用findByViewId得到结果为null...

    转载:http://blog.csdn.net/xiabing082/article/details/48781489 1.  大家常常自定义view,,然后在xml 中添加该view 组件..如果在 ...

  3. android里的editText怎么用,Android自定义控件EditText使用详解

    本文实例为大家分享了Android自定义控件EditText的具体代码,供大家参考,具体内容如下 自定义控件分三种: 1. 自绘控件 2. 组合控件 3. 继承控件 代码已上传到 github 以后的 ...

  4. android汽车之家顶部滑动菜单,Android自定义控件之仿汽车之家下拉刷新

    关于下拉刷新的实现原理我在上篇文章Android自定义控件之仿美团下拉刷新中已经详细介绍过了,这篇文章主要介绍表盘的动画实现原理 汽车之家的下拉刷新分为三个状态: 第一个状态为下拉刷新状态(pull ...

  5. Android 自定义控件打造史上最简单的侧滑菜单

    侧滑菜单在很多应用中都会见到,最近QQ5.0侧滑还玩了点花样~~对于侧滑菜单,一般大家都会自定义ViewGroup,然后隐藏菜单栏,当手指滑动时,通过Scroller或者不断的改变leftMargin ...

  6. Android绘制自定义控件,Android自定义控件绘制基本图形基础入门

    本文讲述绘制android自定义各种图形效果,为自定义控件的入门篇 相关视频链接: android自定义控件系列 android视频全系列 绘制点–这个控件只需要在布局中引用或者代码中new 即可,下 ...

  7. Android自定义控件之仿汽车之家下拉刷新

    感谢 阿拉灯神灯 的技术分享 .版权声明:原文来自http://blog.csdn.net/nugongahou110 关于下拉刷新的实现原理我在上篇文章Android自定义控件之仿美团下拉刷新中已经 ...

  8. Android自定义控件之自定义时钟

    Android自定义控件之自定义时钟 这个是我从别的开源项目中挖出来的,真心写的很不错,然后继续下来以便不时之需,直接上代码: WatcherBoard.java这个是自定义的时钟类 package ...

  9. 自定义控件android特效,Android自定义控件eBook实现翻书效果实例详解

    本文实例讲述了Android自定义控件eBook实现翻书效果的方法.分享给大家供大家参考,具体如下: 效果图: Book.java文件: package com.book; import androi ...

  10. Android.自定义控件的实现 (转载)

    尊重他人劳动成果,转载请注明出处. 转自:http://kandy0619.blog.163.com/blog/static/64344345201012325939280/ 可能是一直都在做Web的 ...

最新文章

  1. 教您如何查看MySQL用户权限
  2. 美国辛辛那堤儿童医学中心招生物信息博士, 博士后和访问学者——单细胞转录组和表观方向...
  3. 为什么要继承Serializable类?
  4. 解决WINCE500中INTEL编译器无法完全卸载的问题
  5. Java 必看的 Spring 知识汇总
  6. 1.Hello,Python
  7. 用async 解放你的大脑
  8. java 异常 检查型和非检查型
  9. ReviewBoard安装和配置札记
  10. WORD图片批量居中?
  11. C语言八字图标软件,ico图标编辑器(Greenfish Icon Editor)
  12. mqtt 多个订阅者 只允许一个接收_一文读懂物联网的灵魂MQTT
  13. SpringData JDBC
  14. 关于Adobe软件安装失败的各类错误代码BUG汇总!!
  15. 在cmd中对Python的一些操作(查版本,下载包等)
  16. Nmap扫描端口常用指令
  17. 2010年国家公务员考试行测真题WORD完整版
  18. HDU 1224 DFS
  19. 超分算法IPT:Pre-Trained Image Processing Transformer
  20. python 图表制作及功能化_Python实现从excel读取数据绘制成精美图像

热门文章

  1. docker harbor 域名_超详细的搭建docker私服Harbor教程
  2. html 整行选择状态,Layui表格选中指定行的radio单选框并滚动到该行的实现代码
  3. 一个程序来比较cuda/c在GPU/CPU的运行效率
  4. Linux C中内联汇编的语法格式及使用方法
  5. C++知识 interview
  6. 动态内存的基本功能和使用
  7. 如何QLayout内部的成员部件之间从左到右依次排列
  8. python3 的windows下文件操作注意问题
  9. C++之error: cannot bind non-const lvalue reference of type ‘myString’ to an rvalue of type ‘myString
  10. Java Jsoup库 实现天气爬取(附第三方库加载方式)