前段時間項目需求,需要做一個有限制長度的輸入框並動態顯示剩余文字,同時也要動態改變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); } } }; }
大致思路就是如此。如有疑問,歡迎加關注聯系,相互學習。
