美文网首页
仿QQ微信点击EditText布局随软键盘的弹出顶上去

仿QQ微信点击EditText布局随软键盘的弹出顶上去

作者: 岛在深海处 | 来源:发表于2017-02-15 20:45 被阅读0次

    主要原理:监听软键盘的弹出,调用ScrollView的
    fullScroll(ScrollView.FOCUS_DOWN);或者是scrollTo(0, 1000)的方法

    已如下xml布局为例:

    总得来说就是将需要向上顶的布局写在ScrollView中。理解后可略过。

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/rl_contain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentBottom="true"
        android:fitsSystemWindows="true">
    
    <include
        android:id="@+id/title"
        layout="@layout/include_login_header" />
    
    <ScrollView
        android:id="@+id/sv_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@+id/title">
    
    
        <RelativeLayout
            android:id="@+id/rl_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_alignParentBottom="true"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android:orientation="vertical">
    
    
            <ImageView
                android:id="@+id/iv_login_logo"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:layout_gravity="center_horizontal"
                android:layout_marginTop="40dp"
                android:src="@mipmap/logo_login" />
    
            <EditText
                android:id="@+id/et_username"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/iv_login_logo"
                android:layout_marginLeft="38dp"
                android:layout_marginRight="38dp"
                android:layout_marginTop="58dp"
                android:background="@null"
                android:hint="@string/login_username"
                android:inputType="phone"
                android:paddingBottom="12dp"
                android:singleLine="true"
                android:textColorHint="@color/search_edittext_hint"
                android:textSize="@dimen/font_size_14" />
    
            <View
                android:id="@+id/v_line1"
                style="@style/horizontal_line_gray"
                android:layout_below="@+id/et_username"
                android:layout_marginLeft="38dp"
                android:layout_marginRight="38dp" />
    
            <EditText
                android:id="@+id/et_passwork"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/v_line1"
                android:layout_marginLeft="38dp"
                android:layout_marginRight="38dp"
                android:layout_marginTop="16dp"
                android:background="@null"
                android:hint="@string/login_password"
                android:inputType="textPassword"
                android:paddingBottom="12dp"
                android:singleLine="true"
                android:textColorHint="@color/search_edittext_hint"
                android:textSize="@dimen/font_size_14" />
    
            <View
                android:id="@+id/v_line2"
                style="@style/horizontal_line_gray"
                android:layout_below="@+id/et_passwork"
                android:layout_marginLeft="38dp"
                android:layout_marginRight="38dp" />
    
            <RelativeLayout
                android:id="@+id/rl_1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/v_line2">
    
                <TextView
                    android:id="@+id/tv_register"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_marginLeft="30dp"
                    android:padding="8dp"
                    android:text="@string/login_register"
                    android:textColor="@color/search_edittext_hint" />
    
                <TextView
                    android:id="@+id/tv_login_forget"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_marginRight="30dp"
                    android:padding="8dp"
                    android:text="@string/login_forget"
                    android:textColor="@color/search_edittext_hint" />
            </RelativeLayout>
    
            <Button
                android:id="@+id/btn_login"
                android:layout_width="match_parent"
                android:layout_height="48dp"
                android:layout_alignParentBottom="true"
                android:layout_below="@+id/rl_1"
                android:layout_centerHorizontal="true"
                android:layout_marginLeft="38dp"
                android:layout_marginRight="38dp"
                android:layout_marginTop="22dp"
                android:background="@drawable/btn_normal_bg"
                android:gravity="center"
                android:text="@string/login_btn"
                android:textColor="@color/white"
                android:textSize="@dimen/font_size_15" />
    
        </RelativeLayout>
    
    </ScrollView>
    
    </RelativeLayout>
    
    首先提供一个软键盘监听的工具类
    package com.xinsundoc.doctor.utils;
    
    import android.app.Activity;
    import android.graphics.Rect;
    import android.os.Handler;
    import android.util.Log;
    import android.view.View;
    import android.view.ViewTreeObserver;
    import android.widget.FrameLayout;
    import android.widget.ScrollView;
    
    
    /**
     * 类名称:KeyboardUtil<br>
     * 内容摘要: 监听软键盘显示与隐藏
     */
    public class KeyboardUtil {
        private static final String TAG = "KeyboardUtil";
    
        public static KeyboardUtil assistActivity(Activity activity, int viewId) {
            return new KeyboardUtil(activity, viewId);
        }
    
        private View mChildOfContent;
        private ScrollView mScrollView; //从activity传进来的ScrollView
    
        private KeyboardUtil(Activity activity, int viewId) {
            FrameLayout content = (FrameLayout) activity
                    .findViewById(android.R.id.content);
            mChildOfContent = content.getChildAt(0);
            mScrollView = (ScrollView) content.findViewById(viewId); //从activity       传进来的ScrollView
            mChildOfContent.getViewTreeObserver().addOnGlobalLayoutListener(
                new ViewTreeObserver.OnGlobalLayoutListener() {
                    @Override
                    public void onGlobalLayout() {
                        possiblyResizeChildOfContent();
                    }
                });
    }
    
        private void possiblyResizeChildOfContent() {
            int contentHeight = mChildOfContent.getRootView().getHeight();
            int curDisplayHeight = computeUsableHeight();
            if (contentHeight - curDisplayHeight > contentHeight / 4) { //软键盘弹出
                Log.e(TAG, "possiblyResizeChildOfContent: 软键盘弹出" );
    //                mScrollView.fullScroll(ScrollView.FOCUS_DOWN);
        //将ScrollView滑动到底部
        //这里不开线程的话,会出现点击第二个输入框不顶上去的bug,
        //初步估计是mScrollView.scrollTo(0, 1000);的原因(最好使用handler)
               new Thread(){
                    @Override
                    public void run() {
                        mScrollView.scrollBy(0, 1000);
                    }
                }.start();
                if(mKeyBoardOpenListener != null){
                    mKeyBoardOpenListener.open();
                }
            } else {  //软键盘关闭
                if(mKeyBoardOpenListener != null){
                    mKeyBoardOpenListener.close();
                }
                Log.e(TAG, "possiblyResizeChildOfContent: 软键盘关闭" );
            }
    }
    
        /**
         * 获取屏幕可显示区域高度
         *
         * @return
         */
        private int computeUsableHeight() {
            Rect r = new Rect();
            mChildOfContent.getWindowVisibleDisplayFrame(r);
           return r.height();
        }
    
        private KeyBoardOpenListener mKeyBoardOpenListener;
         /**
         * 给其他类提供软键盘弹起关闭的监听
         *
         */
        public interface KeyBoardOpenListener{
            void open();
            void close();
        }
        public void setOnKeyBoardOpenListener(KeyBoardOpenListener mKeyBoardOpenListener){
            this.mKeyBoardOpenListener = mKeyBoardOpenListener;
        }
    }
    
    方法一:使用fullScroll(ScrollView.FOCUS_DOWN):

    使用者中方法有一个问题:
    如果一个ScrollView中有多个EditText,不管你点击哪个EditText调起软键盘,调用fullScroll(ScrollView.FOCUS_DOWN)方法后都会将焦点给最底部的那个EditText。
    解决方法:
    1.通过EditText的setOnTouchListener()方法获取首次点击的是哪个EditText();
    2.在软键盘的监听方法open()中调用editText.requestFocus();

    public class LoginActivity extends AppCompatActivity {
    private static final String TAG = "LoginActivity";
    @BindView(R.id.et_passwork)
    EditText password;
    @BindView(R.id.et_username)
    EditText mobile;
    @BindView(R.id.tv_main_title)
    
    private EditText mEdittext;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login2);
        ButterKnife.bind(this);
    
        inputManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
        KeyboardUtil keyboardUtil = KeyboardUtil.assistActivity(this, R.id.sv_content);
        keyboardUtil.setOnKeyBoardOpenListener(new KeyboardUtil.KeyBoardOpenListener() {
            @Override
            public void open() {
                if(mEdittext != null){
                    mEdittext.requestFocus(); //请求获取焦点
                }
            }
    
            @Override
            public void close() {
    
            }
        });
    
        mobile.setOnTouchListener(new MyOnTouchListener());
        password.setOnTouchListener(new MyOnTouchListener());
    }
    
    /**
     * Edittext的监听事件
     */
    class MyOnTouchListener implements View.OnTouchListener {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (v.getId()){
                case R.id.et_username:
                    mEdittext = mobile;
                    Log.e(TAG, "onTouch: mobile点击了");
                    break;
                case R.id.et_passwork:
                    mEdittext = password;
                    Log.e(TAG, "onTouch: password点击了");
                    break;
            }
            return false;
        }
    }
    }
    
    方法二:使用scrollTo(0, 100)开新线程:

    在软键盘弹起方法中调用

    //这里不开新线程的话,会出现点击第二个输入框不顶上去的bug,
    //初步估计是mScrollView.scrollTo(0, 1000);的原因 最好使用handler开新线程
       new Thread(){
                    @Override
                    public void run() {
                        mScrollView.scrollBy(0, 1000);
                    }
                }.start();

    相关文章

      网友评论

          本文标题:仿QQ微信点击EditText布局随软键盘的弹出顶上去

          本文链接:https://www.haomeiwen.com/subject/nchjmttx.html