前段时间项目需求,需要做一个有限制长度的输入框并动态显示剩余文字,同时也要动态改变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); } } }; }
大致思路就是如此。如有疑问,欢迎加关注联系,相互学习。