最近在学习中用到了;浮动提示在EditText上的功能; 找了一圈;发现了 一个好用的 效果…..在这里记录下;
简单的实现浮动标签EditText:Android视图使用EditText之上,并提示EditText时填充文本。
参考项目地址:https://github.com/wrapp/floatlabelededittext
下面直接使用方式:
在app–>build.gradle 的 dependencies中直接添加:
dependencies {
//--部分略
//TJ:添加应用库-----
//TJ:EditText:文本框编辑的浮动提示
compile 'com.wrapp.floatlabelededittext:library:0.0.6'
}
然后 Sync Now…后 即可使用了 。 简单粗暴。
然后在要使用的地方:添加如下类似的操作代码即可:
完整的一个布局内容如:个人添加了四个选项功能
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:float="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fletPaddingLeft="120dp"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="This is a test" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:id="@+id/floatEdit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPadding="10dp"
>
<EditText
android:id="@+id/edit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPaddingBottom="10dp"
float:fletTextAppearance="@style/floatlabelededittext">
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPaddingBottom="10dp"
float:fletTextAppearance="@style/floatlabelededittext"
>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="PassWord Again"
android:inputType="textPassword" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
LinearLayout>
说明:
float:fletTextAppearance="@style/floatlabelededittext"
这个样式是定义文本的属性样式:
在value下的styles.xml 中:
OK ;使用完结;是不是很简单? but…
简单是简单了;但是功能很有限啊
比如希望 定制悬浮显示的文体 这个应该如何改呢 ?
OK 我们来看看这个库的源码——-
下载源码library: library
用过Android Studio的应该都知道了。所以下面的可以不看。
添加到项目中:
依赖:File–>Project Structure … –>选择Modules下面的app –>
Dependencies–>在右边“+” 加号选项中选择–Module dependency–>选择下载的库–>OK ;
然后这个时候:库 已经出现在Dependencies中 选中–>OK 即可。
如下图操作:
我们来简单的看一下源码:很简单 就这一个类
public class FloatLabeledEditText extends FrameLayout {
private static final int DEFAULT_PADDING_LEFT= 2;//TJ:文本距离 左侧的间距
private TextView mHintTextView;
private EditText mEditText;
private Context mContext;
public FloatLabeledEditText(Context context) {
super(context);
mContext = context;
}
public FloatLabeledEditText(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
setAttributes(attrs);
}
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
public FloatLabeledEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
mContext = context;
setAttributes(attrs);
}
private void setAttributes(AttributeSet attrs) {//TJ:获取属性 并设置属性显示
mHintTextView = new TextView(mContext);
final TypedArray a = mContext.obtainStyledAttributes(attrs, R.styleable.FloatLabeledEditText);
final int padding = a.getDimensionPixelSize(R.styleable.FloatLabeledEditText_fletPadding, 0);
final int defaultPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, DEFAULT_PADDING_LEFT, getResources().getDisplayMetrics());
final int paddingLeft = a.getDimensionPixelSize(R.styleable.FloatLabeledEditText_fletPaddingLeft, defaultPadding);
final int paddingTop = a.getDimensionPixelSize(R.styleable.FloatLabeledEditText_fletPaddingTop, 0);
final int paddingRight = a.getDimensionPixelSize(R.styleable.FloatLabeledEditText_fletPaddingRight, 0);
final int paddingBottom = a.getDimensionPixelSize(R.styleable.FloatLabeledEditText_fletPaddingBottom, 0);
Drawable background = a.getDrawable(R.styleable.FloatLabeledEditText_fletBackground);
if (padding != 0) {
mHintTextView.setPadding(padding, padding, padding, padding);
} else {
mHintTextView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom);
}
if (background != null) {
setHintBackground(background);
}
mHintTextView.setTextAppearance(mContext, a.getResourceId(R.styleable.FloatLabeledEditText_fletTextAppearance, android.R.style.TextAppearance_Small));
//Start hidden
mHintTextView.setVisibility(INVISIBLE);
AnimatorProxy.wrap(mHintTextView).setAlpha(0);
addView(mHintTextView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
a.recycle();
}
@SuppressLint("NewApi")
private void setHintBackground(Drawable background) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
mHintTextView.setBackground(background);
} else {
mHintTextView.setBackgroundDrawable(background);
}
}
@Override
public final void addView(View child, int index, ViewGroup.LayoutParams params) {
if (child instanceof EditText) {
if (mEditText != null) {
throw new IllegalArgumentException("Can only have one Edittext subview");
}
final LayoutParams lp = new LayoutParams(params);
lp.gravity = Gravity.BOTTOM;
lp.topMargin = (int) (mHintTextView.getTextSize() + mHintTextView.getPaddingBottom() + mHintTextView.getPaddingTop());
params = lp;
setEditText((EditText) child);
}
super.addView(child, index, params);
}
private void setEditText(EditText editText) {
mEditText = editText;
mEditText.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
setShowHint(!TextUtils.isEmpty(s));
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
});
mEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View view, boolean gotFocus) {
onFocusChanged(gotFocus);
}
});
//TJ:注意这里;就是我们 显示悬浮 文本的设置显示的地方!!!
mHintTextView.setText(mEditText.getHint());
if(!TextUtils.isEmpty(mEditText.getText())){
mHintTextView.setVisibility(VISIBLE);
}
}
private void onFocusChanged(boolean gotFocus) {
if (gotFocus && mHintTextView.getVisibility() == VISIBLE) {
ObjectAnimator.ofFloat(mHintTextView, "alpha", 0.33f, 1f).start();
} else if (mHintTextView.getVisibility() == VISIBLE) {
AnimatorProxy.wrap(mHintTextView).setAlpha(1f); //Need this for compat reasons
ObjectAnimator.ofFloat(mHintTextView, "alpha", 1f, 0.33f).start();
}
}
private void setShowHint(final boolean show) {
AnimatorSet animation = null;
if ((mHintTextView.getVisibility() == VISIBLE) && !show) {
animation = new AnimatorSet();
ObjectAnimator move = ObjectAnimator.ofFloat(mHintTextView, "translationY", 0, mHintTextView.getHeight() / 8);
ObjectAnimator fade = ObjectAnimator.ofFloat(mHintTextView, "alpha", 1, 0);
animation.playTogether(move, fade);
} else if ((mHintTextView.getVisibility() != VISIBLE) && show) {
animation = new AnimatorSet();
ObjectAnimator move = ObjectAnimator.ofFloat(mHintTextView, "translationY", mHintTextView.getHeight() / 8, 0);
ObjectAnimator fade;
if (mEditText.isFocused()) {
fade = ObjectAnimator.ofFloat(mHintTextView, "alpha", 0, 1);
} else {
fade = ObjectAnimator.ofFloat(mHintTextView, "alpha", 0, 0.33f);
}
animation.playTogether(move, fade);
}
if (animation != null) {
animation.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animation) {
super.onAnimationStart(animation);
mHintTextView.setVisibility(VISIBLE);
}
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
mHintTextView.setVisibility(show ? VISIBLE : INVISIBLE);
AnimatorProxy.wrap(mHintTextView).setAlpha(show ? 1 : 0);
}
});
animation.start();
}
}
public EditText getEditText() {
return mEditText;
}
public void setHint(String hint) {
mEditText.setHint(hint);
mHintTextView.setText(hint);
}
public CharSequence getHint() {
return mHintTextView.getHint();
}
}
源码解析:
FloatLabeledEditText.java 类中
FloatLabeledEditText(…) 方法有三个:这个很好理解; 后面两个是用在自定义view中 使用的。
setAttributes(…):里面用到一个自定义的控件的属性:values–>attrs.xml 中的name:FloatLabeledEditText
里面有7个属性的定义;这个在我们的代码:
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:id="@+id/floatEdit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPaddingBottom="10dp"
float:fletTextAppearance="@style/floatlabelededittext">
"@+id/edit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
中使用的如:
float:fletPaddingBottom="10dp"
下面的方法基本上 通过名称就可以 判断出来是干啥用的了;这里不一一说明了;
在上面我们提到如何 设置 各个悬浮的文本;我们通过查看代码发现:setEditText()方法里面就有设置 悬浮文本的地方;那么 OK 看这句:
mHintTextView.setText(mEditText.getHint());
设置的悬浮文本是TextView 这里获取的设置悬浮文本是 EditText的hint属性中的内容作为 悬浮文本的设置。
那么 我们可以通过修改 TextView 的text文本 内容 来设置悬浮的内容: OK 这个设置代码在方法:setHint()中;所以自定义 悬浮文本内容就解决了:就是:本类的setHint() 方法;
所以在 需要使用的地方直接:
floatLabeledEditText.setHint("我是自定义悬浮");
即可。
代码如下:
xml 布局
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:float="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:id="@+id/floatEdit0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:fletPaddingLeft="120dp"
>
<EditText
android:id="@+id/edit0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="this is a test" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:id="@+id/floatEdit1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPadding="10dp"
>
<EditText
android:id="@+id/edit1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Username" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:id="@+id/floatEdit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPaddingBottom="10dp"
float:fletTextAppearance="@style/floatlabelededittext">
<EditText
android:id="@+id/edit2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Password" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
<com.wrapp.floatlabelededittext.FloatLabeledEditText
android:id="@+id/floatEdit3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
float:fletPaddingBottom="10dp"
float:fletTextAppearance="@style/floatlabelededittext"
>
<EditText
android:id="@+id/edit3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="PassWord Again"
android:inputType="textPassword" />
com.wrapp.floatlabelededittext.FloatLabeledEditText>
LinearLayout>
主Activity逻辑:
public class EditTextFloatActivity extends Activity {
FloatLabeledEditText floatEdit0,floatEdit1,floatEdit2,floatEdit3;
EditText edit0 ,edit1 , edit2 , edit3;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_text_float);
initDatas();
floatEdit0.setHint("我是自定义悬浮-");
edit0.setHint("自定义悬浮");
floatEdit1.setHint("我是自定义悬浮-1");
edit1.setHint("Username");
floatEdit2.setHint("我是自定义悬浮-2");
edit2.setHint("Password");
floatEdit3.setHint("我是自定义悬浮-3");
edit3.setHint("Password!");
}
public void initDatas() {
floatEdit0 = (FloatLabeledEditText) findViewById(R.id.floatEdit0);
floatEdit1 = (FloatLabeledEditText) findViewById(R.id.floatEdit1);
floatEdit2 = (FloatLabeledEditText) findViewById(R.id.floatEdit2);
floatEdit3 = (FloatLabeledEditText) findViewById(R.id.floatEdit3);
edit0 = (EditText) findViewById(R.id.edit0);
edit1 = (EditText) findViewById(R.id.edit1);
edit2 = (EditText) findViewById(R.id.edit2);
edit3 = (EditText) findViewById(R.id.edit3);
}
}
OK到这里就结束了;与大家共同进步。