2014年4月26日 星期六

Android 開發 (四十) FloatingLabelLayout

FloatingLabelLayout
 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。

沒有留言:

張貼留言