Android 動態改變高度以及計算長度的EditText


前段時間項目需求,需要做一個有限制長度的輸入框並動態顯示剩余文字,同時也要動態改變EditText的高度來增加用戶體驗。現整理出來與大家分享。

先來看看效果圖

效果圖

看了效果就分享一下布局

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/black"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/contentlen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentRight="true"
        android:textColor="@android:color/white"
        android:visibility="gone" />


    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" >

        <FrameLayout
            android:id="@+id/send_layout"
            android:layout_width="59.0dip"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerVertical="true"
            android:layout_marginLeft="8.0dip"
            android:addStatesFromChildren="true" >

            <Button
                android:id="@+id/send"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:background="@drawable/send_button_normal"
                android:minHeight="34.0dip"
                android:text="發送"
                android:textColor="#ffffff"
                android:textSize="14.0sp" />
        </FrameLayout>

        <EditText
            android:id="@+id/input"
            android:layout_width="fill_parent"
            android:layout_height="40dip"
            android:layout_alignParentLeft="true"
            android:layout_centerVertical="true"
            android:layout_marginBottom="8.0dip"
            android:layout_marginTop="8.0dip"
            android:layout_toLeftOf="@id/send_layout"
            android:background="@drawable/input_bg"
            android:inputType="textMultiLine"
            android:maxLines="4"
            android:textColor="#000000"
            android:textSize="16.0sp" />
    </RelativeLayout>

</RelativeLayout>
android:layout_alignParentBottom="true"

這句很重要,很多人在第一次做的時候不知道,經常會說彈出的鍵盤會遮住了輸入框,這個加上manifest.xml里的android:configChanges="keyboardHidden|orientation|screenSize"就能可以實現彈出輸入法時吧輸入框頂上去

 <activity
            android:name="com.hjhrq1991.myeditdemo.MainActivity"
            android:configChanges="keyboardHidden|orientation|screenSize"
            android:label="@string/app_name"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="adjustResize" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
  </activity>

這里我使用TextWatcher來對EditText進行監聽,動態計算輸入的內容。至於取得控件的高度,相信不少新人都是在oncreate方法里使用getHeight方法來取得高度,然后很多人都會拋去一個問題,怎么我取得的值為0?這是因為activity在初始化的時候創建view,而在剛創建view對象時系統並沒有繪制完成,因此get出來的高度為0。那么怎么去正確get到高度?應該是在view繪制完成后再去get,是的,監聽view的繪制,在view繪制完成后再使用getHeight方法。這里我建議使用ViewTreeObserver方法來監聽,再view繪制完成后系統會回調給acitvity通知其繪制完成,而且只執行一次。具體代碼如下

package com.hjhrq1991.myeditdemo;

import android.os.Bundle;
import android.app.Activity;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.ViewTreeObserver;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

    private EditText mMsg;//輸入框
    private TextView mContentLen;//文字長度提示文本
    
    private int mHeight;
    private int middleHeight;
    private int maxHeight;
    
    private boolean lenTips = true;
    
    private int MAX_LENGTH = 100;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        init();
    }
    
    /**
     * @deprecated 初始化,在這里使用ViewTreeObserver獲取控件的高度
     */
    private void init() {
        mMsg = (EditText) findViewById(R.id.input);
        mContentLen = (TextView) findViewById(R.id.contentlen);
        
        //動態計算字符串的長度
        mMsg.addTextChangedListener(mTextWatcher);

        //取得控件高度
        ViewTreeObserver vto2 = mMsg.getViewTreeObserver();
        vto2.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
            @SuppressWarnings("deprecation")
            @Override
            public void onGlobalLayout() {
                mMsg.getViewTreeObserver().removeGlobalOnLayoutListener(this);
                mHeight = mMsg.getHeight();
                middleHeight = 8 * mHeight / 5;
                maxHeight = 21 * mHeight / 10;
            }
        });
    }

    /**
     * edittext輸入監聽
     */
    TextWatcher mTextWatcher = new TextWatcher() {
        private CharSequence temp;

        // private int editStart;
        // private int editEnd;
        @Override
        public void onTextChanged(CharSequence s, int start, int before,
                int count) {
            // TODO Auto-generated method stub
            temp = s.toString().trim();
        }

        @Override
        public void beforeTextChanged(CharSequence s, int start, int count,
                int after) {
            // TODO Auto-generated method stub
        }

        @Override
        public void afterTextChanged(Editable s) {
            // TODO Auto-generated method stub
            // editStart = mMsg.getSelectionStart();
            // editEnd = mMsg.getSelectionEnd();
            int len = temp.length();//取得內容長度
            int lineCount = mMsg.getLineCount();//取得內容的行數
            if (len != 0) {
                mContentLen.setVisibility(View.VISIBLE);
                if (len <= MAX_LENGTH) {
                    mContentLen.setText("(" + (MAX_LENGTH - temp.length())
                            + ")");
                } else {
                    if (lenTips) {
                        Toast.makeText(
                                getApplicationContext(),
                                String.format(
                                        getString(R.string.more_than_litmit),
                                        MAX_LENGTH), 100).show();
                        lenTips = false;
                    }
                    mContentLen.setText("(-" + (temp.length() - MAX_LENGTH)
                            + ")");
                }
            } else {
                mContentLen.setVisibility(View.GONE);
            }
            /**
             * 根據行數動態計算輸入框的高度
             */
            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) mMsg
                    .getLayoutParams();
            if (lineCount <= 1) {
                params.height = mHeight;
                mMsg.setLayoutParams(params);
            } else if (lineCount == 2) {
                params.height = middleHeight;
                mMsg.setLayoutParams(params);
            } else {
                params.height = maxHeight;
                mMsg.setLayoutParams(params);
            }
        }
    };

}

大致思路就是如此。如有疑問,歡迎加關注聯系,相互學習。

demo下載請猛戳


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM