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下载请猛戳

时间: 2024-10-12 11:39:29

Android 动态改变高度以及计算长度的EditText的相关文章

Android动态改变布局,比如登陆弹出软键盘,登陆框上移(转载)

Android动态改变布局 http://www.cnblogs.com/angeldevil/p/3836256.html 遇到这么个需求,先看图:      其实是一个软件的登录界面,初始是第一个图的样子,当软键盘弹出后变为第二个图的样子,因为登录界面有用户名.密码.登录按钮,不这样的话软键盘弹出后会遮住登录按钮(其实之前的实现放到了ScrollView里面,监听软键盘弹出后滚动到底部,软键盘隐藏后滚动到顶部,也是可以的). 最简单的方法就是多加几个冗余的View,根据软键盘的状态隐藏不需要

android &nbsp; 动态改变图片大小

在oncreate中,使用getheight等函数不能获得控件大小,得到的为0 应使用其他方法 Resources res = getResources(); final ImageView view=(ImageView)findViewById(R.id.IV_about); final Drawable drawable=res.getDrawable(R.drawable.ic_about); DisplayMetrics dm = new DisplayMetrics(); getWi

android 动态改变屏幕方向

LANDSCAPE与PORTRAIT 范例说明 要如何通过程序控制Activity的显示方向?在Android中,若要通过程序改变屏幕显示的方向,必须要覆盖 setRequestedOrientation()方法,而若要取得目前的屏幕方向,则需要访问getRequestedOrientation()方 法. 本 范例为求简要示范更改做法,设计了一个按钮,当单击按钮的同时,判断当下的屏幕方向,例如竖排(PORTRAIT),则将其更改为横排 (LANDSCAPE);若为横排(LANDSCAPE),则

android 动态改变控件位置和大小 .

动态改变控件位置的方法: setPadding()的方法更改布局位置. 如我要把Imageview下移200px: ImageView.setPadding( ImageView.getPaddingLeft(),  ImageView.getPaddingTop()+200, ImageView.getPaddingRight(),  ImageView.getPaddingBottom()); 动态改变控件大小的方法: 1.声明控件参数获取对象 LayoutParams lp: 2.获取控件

Android 动态改变布局属性RelativeLayout.LayoutParams.addRule()

我们知道,在 RelativeLayout 布局中有很多特殊的属性,通常在载入布局之前,在相关的xml文件中进行静态设置即可. 但是,在有些情况下,我们需要动态设置布局的属性,在不同的条件下设置不同的布局排列方式,这时候就需要用到 RelativeLayout.LayoutParams.addRule() 方法,该方法有两种重载方式: addRule(int verb) :用此方法时,所设置节点的属性不能与其它兄弟节点相关联或者属性值为布尔值(布尔值的属性,设置时表示该属性为 true,不设置就

Android动态改变ListView的高度

定义一个函数将dp转换为像素 public int Dp2Px(Context context, float dp) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dp * scale + 0.5f); } 定义函数动态控制listView的高度 public void setListViewHeightBasedOnChildren(ListView listVie

Android动态改变布局

遇到这么个需求,先看图:      事实上是一个软件的登录界面,初始是第一个图的样子,当软键盘弹出后变为第二个图的样子,由于登录界面实username.password.登录button,不这种话软键盘弹出后会遮住登录button(事实上之前的实现放到了ScrollView里面,监听软键盘弹出后滚动究竟部,软键盘隐藏后滚动到顶部,也是能够的). 最简单的方法就是多加几个冗余的View,依据软键盘的状态隐藏不须要的View,显示须要的View,但这样感觉太挫了,然后就想起了前两年研究的Relati

Android 动态改变组件大小

注意,你要改变组件的部分,要在XML中将其设置为warp_content.比如 你如果要改变button宽度,在xml中就要将其layout_width设置为wrap_content 在代码中动态设置宽度是通过设置设置LayoutParams来达到效果的 ImageView pictureView = (ImageView) convertView.findViewById(R.id.picture_view); ViewGroup.LayoutParams layoutParams=holde

Android 动态改变Layout的大小

设置View的大小是通过设置LayoutParams参数. 如果一个view在一个RelativeLayout里面,需要用一个RelativeLayout.LayoutParams对象来设置 在代码里面设置的高度height是px,如果想用dp单位设置,需要获取屏幕的密度,然后转换. final float scale = getActivity().getResources().getDisplayMetrics().density; int height = (int) (48 * scal