android 配合scrollview 解决键盘遮挡EditText的问题

 

 

1.BaseActivity.java

package com.ange.keyboardhidedemo;

import android.app.Activity;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ScrollView;

import java.util.ArrayList;
import java.util.List;

public class BaseActivity extends Activity implements View.OnLayoutChangeListener, View.OnFocusChangeListener {
    private final static String TAG = "BaseActivity";


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //todo 在子类里调用 initKeyBoardListener
    }

    /**
     * 要键盘弹出时,scrollView做滑动需,调用此方法
     *
     * @return
     */
    protected void initKeyBoardListener(ScrollView scrollView) {
        this.mainScrollView = scrollView;
        this.editTexts = new ArrayList<>();
        findEditText(scrollView);
        setFoucesListener();
    }

    protected void initKeyBoardListener(ScrollView scrollView, int offset) {
        this.mainScrollView = scrollView;
        this.editTexts = new ArrayList<>();
        findEditText(scrollView);
        setFoucesListener();
        this.offset = offset;
    }

    //偏移量
    private int offset;
    //当前页面获取了焦点的editText
    private ScrollView mainScrollView;
    private Runnable scrollRunnable;
    private boolean normalCanScroll = true;
    private EditText currentFocusEt;
    //当前页面获取了所有的editText
    List<EditText> editTexts;

    @Override
    protected void onResume() {
        super.onResume();
        //添加layout大小发生改变监听器
        getContentView().addOnLayoutChangeListener(this);
    }

    public View getContentView() {
        return ((ViewGroup) findViewById(android.R.id.content)).getChildAt(0);
    }

    @Override
    public void onLayoutChange(View v, int left, int top, int right, final int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { //获取屏幕高度
        int screenHeight = this.getWindowManager().getDefaultDisplay().getHeight();
        //阀值设置为屏幕高度的1/3
        int keyHeight = screenHeight / 3;
        if (mainScrollView != null && normalCanScroll) {
            normalCanScroll = mainScrollView.canScrollVertically(1);
            Log.e(TAG, "mainScrollView:canScroll:" + normalCanScroll);
        }

        //现在认为只要控件将Activity向上推的高度超过了1/3屏幕高,就认为软键盘弹起

        if (oldBottom != 0 && bottom != 0 && (oldBottom - bottom > keyHeight)) {
            Log.e(TAG, "弹起");
            if (currentFocusEt != null) {
                Log.e(TAG, currentFocusEt.getText().toString());
                int[] location = new int[2];
                currentFocusEt.getLocationOnScreen(location);
                int x = location[0];
                int y = location[1];
                int height = currentFocusEt.getHeight();
                y = y + height;
                Log.e(TAG, "bottom:" + bottom + " currentFocusEt.bottom:" + y);
                if (y > bottom && mainScrollView != null) {
                    final int finalY = y;
                    if (normalCanScroll) {
                        scrollRunnable = new Runnable() {
                            @Override
                            public void run() {
                                mainScrollView.scrollBy(0, finalY - bottom + offset);
                            }
                        };
                        mainScrollView.postDelayed(scrollRunnable, 100);
                    } else {
                        mainScrollView.scrollBy(0, finalY - bottom + offset);
                    }
                }
            }
        } else if (oldBottom != 0 && bottom != 0 && (bottom - oldBottom > keyHeight)) {
            Log.e(TAG, "收回");
        }
    }

    /**
     * 监听焦点获取当前的获取焦点的editText
     *
     * @param v
     * @param hasFocus
     */
    @Override
    public void onFocusChange(View v, boolean hasFocus) {
        if (hasFocus && v instanceof EditText) {
            currentFocusEt = (EditText) v;
        }
    }

    /**
     * 找出当前页面的所有editText
     *
     * @param view
     */
    private void findEditText(View view) {
        if (view instanceof ViewGroup) {
            ViewGroup viewGroup = (ViewGroup) view;
            for (int i = 0; i < viewGroup.getChildCount(); i++) {
                View v = viewGroup.getChildAt(i);
                findEditText(v);
            }
        } else if (view instanceof EditText) {
            editTexts.add((EditText) view);
        }
    }

    /**
     * 当前页面的所有editText设置焦点监听
     */
    private void setFoucesListener() {
        for (EditText et : editTexts) {
            et.setOnFocusChangeListener(this);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mainScrollView != null) {
            mainScrollView.removeCallbacks(scrollRunnable);
        }
    }
}

2.使用方式:在子类Activity初始化  initKeyBoardListener(scrollView);

注意(Activity里必须有ScrollView ,而且EditText在ScrollView里面)

package com.ange.keyboardhidedemo;

import android.os.Bundle;
import android.widget.ScrollView;

public class MainActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initKeyBoardListener((ScrollView) findViewById(R.id.scrollView));
    }
}
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:id="@+id/scrollView"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

   <LinearLayout
       android:orientation="vertical"
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
       <EditText
           android:layout_marginTop="500dp"
           android:id="@+id/et"
           android:layout_width="match_parent"
           android:layout_height="wrap_content" />
   </LinearLayout>

</ScrollView>

 

3.在AndroidManifest里添加

  <activity
            android:name=".XXXX"
            android:screenOrientation="portrait"
            android:windowSoftInputMode="stateAlwaysHidden|adjustResize"  />

stateAlwaysHidden:当该 Activity主窗口获取焦点时,软键盘总是被隐藏的。

adjustResize:当弹出键盘时,Activity主窗口占位变小,留出显示键盘的控件。

原理分析:

当触摸EditText ,键盘弹出-> 

activity窗口的大小会发生改变->

 //在根部局添加layout大小发生改变监听器: getContentView().addOnLayoutChangeListener(this);

在onLayoutChange 里计算当前拥有焦点的editText的位置,计算scrollView 需要滑动多少距离才能使EditText显示在视图上,然后进行滑动;

代码地址:https://github.com/niangegelaile/Keyboardhidedemo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值