https://gist.github.com/chrisbanes/11247418
這是ChrisBanes公布的source code 先看一下功能
我們可以稍微看一下source code,
FloatLableLayout.java
@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) {
}
});
可以看到他在 addview時將 child的 edittext加上 textchanged Event
然後再利用textChanged event去顯示或隱藏相關的label
其實我比較好奇的地方是他為何不乾脆將 editText 直接包含在custom view裡頭
反而是利用如下圖的方式
<com.example.my.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="password"
android:imeOptions="actionDone"
android:inputType="textNoSuggestions"
android:singleLine="true" />
</com.example.my.FloatLabelLayout>
是說這樣寫的自由度比較高,但是使用者錯誤使用的機會也會增加,可以想像的好處大概只有當 FloatLabelLayout 的child 有較多UI時,可以將layout 都放在 floatLabelLayout內可以少使用一個
relative layout 如下
<com.example.my.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="password"
android:imeOptions="actionDone"
android:inputType="textNoSuggestions"
android:singleLine="true" />
<ImageView android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_launcher"/>
</com.example.my.FloatLabelLayout>
但是就如上面所說的,當使用者加入兩個editText將會造成錯誤的情況,我目前能想到比較好的解法應該是將view綁定TextView而不是FrameLayout,
簡單的說就是客製一個TextView 並包含上面的功能。
小結
這算是個簡單卻頗有趣的UI。

沒有留言:
張貼留言