最近在写一个聊天窗口,要实现软键盘弹出时listview背景不被挤压,并且弹出时Item和edittext的相对位置不变,困扰了好几天,查了很多资料,发现都没有这方面的完整内容,顾在此记录一下。与大家分享。
先预览:
首先创建布局,相信大家都会这里不做介绍。。。直接上代码
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_height="match_parent"
android:orientation="vertical"
android:id="@+id/rootview"
android:background="@drawable/splash">
<ListView
android:id="@+id/id_dialog_listview"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="@null"
android:stackFromBottom="true"
android:transcriptMode="alwaysScroll"
android:dividerHeight="10dp"></ListView>
<LinearLayout
android:id="@+id/id_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@android:color/transparent">
<EditText
android:id="@+id/id_dialog_editText"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_marginLeft="5dp"
android:layout_weight="4"
android:maxLines="5"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:layout_marginLeft="2dp"
android:gravity="bottom">
<Button
android:id="@+id/id_dialog_button"
android:layout_width="0dp"
android:layout_height="39dp"
android:layout_weight="1"
android:layout_gravity="bottom"
android:layout_marginBottom="3dp"
android:layout_marginRight="5dp"
android:gravity="center"
android:text="发送"
android:textSize="14sp"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
布局完成后写Java代码,现在首先要计算软键盘高度h,然后通过软键盘高度h使整个布局上移h,计算软键盘高度方法如下:
SoftKeyBoardListener.java
import android.app.Activity;
import android.graphics.Rect;
import android.view.View;
import android.view.ViewTreeObserver;
/**
* Created by cjh on 17-5-25.
*/
public class SoftKeyBoardListener {
private View rootView;//activity的根视图
int rootViewVisibleHeight;//纪录根视图的显示高度
private OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener;
public SoftKeyBoardListener(Activity activity) {
//获取activity的根视图
rootView = activity.getWindow().getDecorView();
//监听视图树中全局布局发生改变或者视图树中的某个视图的可视状态发生改变
rootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
//获取当前根视图在屏幕上显示的大小
Rect r = new Rect();
rootView.getWindowVisibleDisplayFrame(r);
int visibleHeight = r.height();
if (rootViewVisibleHeight == 0) {
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度没有变化,可以看作软键盘显示/隐藏状态没有改变
if (rootViewVisibleHeight == visibleHeight) {
return;
}
//根视图显示高度变小超过200,可以看作软键盘显示了
if (rootViewVisibleHeight - visibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardShow(rootViewVisibleHeight - visibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
//根视图显示高度变大超过200,可以看作软键盘隐藏了
if (visibleHeight - rootViewVisibleHeight > 200) {
if (onSoftKeyBoardChangeListener != null) {
onSoftKeyBoardChangeListener.keyBoardHide(visibleHeight - rootViewVisibleHeight);
}
rootViewVisibleHeight = visibleHeight;
return;
}
}
});
}
private void setOnSoftKeyBoardChangeListener(OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
this.onSoftKeyBoardChangeListener = onSoftKeyBoardChangeListener;
}
public interface OnSoftKeyBoardChangeListener {
void keyBoardShow(int height);
void keyBoardHide(int height);
}
public static void setListener(Activity activity, OnSoftKeyBoardChangeListener onSoftKeyBoardChangeListener) {
SoftKeyBoardListener softKeyBoardListener = new SoftKeyBoardListener(activity);
softKeyBoardListener.setOnSoftKeyBoardChangeListener(onSoftKeyBoardChangeListener);
}
}
这个方法是网上查来的,因为转载太多,搞不清原著了,原作者莫怪。感谢原作者。
最后只需要在主函数中引用就可以了:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dialog);
adapter = new MsgAdapter(Dialog.this, R.layout.msg_list_item, msgList);
msgListView = (ListView) findViewById(R.id.id_dialog_listview);
linearLayout = (LinearLayout) findViewById(R.id.rootview);
msgListView.setAdapter(adapter);
SoftKeyBoardListener.setListener(Dialog.this, new SoftKeyBoardListener.OnSoftKeyBoardChangeListener() {
@Override
public void keyBoardShow(int height) {
linearLayout.scrollBy(0,height);
}
@Override
public void keyBoardHide(int height) {
linearLayout.scrollBy(0,0-height);
}
});
使用scrollBy函数,使linearLayou整体上移height高度,正数上移,负的就是下移,监听到键盘显示就上移,隐藏就下移。
但要注意的是Manifest里面的activity里,一定要是 android:windowSoftInputMode=”adjustPan”。
本人初学者,不喜勿喷!!!