之前的Android沉浸式状态栏实现并没有考虑软键盘的影响,接下来的内容将会针对这个问题给出解决方案,先看一下效果图
这个是一个留言板的效果图:
即弹出软键盘的时候并不会导致整个布局上移。
具体如何实现?按照以下步骤进行设置:
1、布局文件中声明如下
<activity
android:name="com.storm.durian.activity.LeaveMessageDetailsActivity"
android:screenOrientation="portrait"
/>
2、这里重写了RelativeLayout,并重写了fitSystemWindows,这个是最最关键的,
/**
* 自适应布局
*/
public class FitsSystemWindowsLayout extends RelativeLayout {
private static final String TAG = FitsSystemWindowsLayout.class.getSimpleName();
private SoftKeyBoardStateListener softKeyBoardStateListener;
public FitsSystemWindowsLayout(Context context) {
super(context);
}
public FitsSystemWindowsLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FitsSystemWindowsLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
dispatchListenerLow(heightMeasureSpec);
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
/**
* 处理低版本键盘弹出
*
* @param heightMeasureSpec 高度
*/
private void dispatchListenerLow(int heightMeasureSpec) {
if (softKeyBoardStateListener == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
return;
}
int oldSpec = getMeasuredHeight();
if (oldSpec <= 0) {
return;
}
int newSpec = MeasureSpec.getSize(heightMeasureSpec);
int offset = oldSpec - newSpec;
if (offset > 100) {
LogHelper.i(TAG, "键盘打开");
softKeyBoardStateListener.onSoftKeyBoardStateChange(true);
} else if (offset < -100) {
LogHelper.i(TAG, "键盘关闭");
softKeyBoardStateListener.onSoftKeyBoardStateChange(false);
}
}
@Override
protected boolean fitSystemWindows(Rect insets) {
dispatchListener(insets);
insets.top = 0;
return super.fitSystemWindows(insets);
}
/**
* 分发监听
*
* @param insets
*/
private void dispatchListener(Rect insets) {
if (softKeyBoardStateListener == null || android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
return;
}
if (insets.top != 0 && insets.bottom != 0) {
LogHelper.i(TAG, "键盘打开");
softKeyBoardStateListener.onSoftKeyBoardStateChange(true);
} else {
LogHelper.i(TAG, "键盘关闭");
softKeyBoardStateListener.onSoftKeyBoardStateChange(false);
}
}
/**
* 设置软键盘监听事件
*
* @param softKeyBoardStateListener
*/
public void setSoftKeyBoardListener(SoftKeyBoardStateListener softKeyBoardStateListener) {
this.softKeyBoardStateListener = softKeyBoardStateListener;
}
public interface SoftKeyBoardStateListener {
public void onSoftKeyBoardStateChange(boolean isOpen);
}
}
虽然以上布局也提供了键盘打开或者关闭的回调,但是在某些低版本手机上还是支持的不太好,需要这个回调的可以将此回调作为其中一个方法,但是不要过分依赖
3、布局文件使用com.storm.durian.view.FitsSystemWindowsLayout包裹整个布局,并设置android:fitsSystemWindows=“true”
<?xml version="1.0" encoding="utf-8"?>
<com.storm.durian.view.FitsSystemWindowsLayout android:id="@+id/leave_message_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/ececec"
android:fitsSystemWindows="true">
<include
android:id="@+id/leave_message_title"
layout="@layout/common_back"/>
<LinearLayout
android:id="@+id/ll_leave_message_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@drawable/leave_message_bottom_bg"
android:orientation="horizontal">
<EditText
android:id="@+id/et_leave_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="@drawable/et_leave_message_bg"
android:hint="亲,给我留言我会回复你哒~"
android:maxLines="4"
android:textColor="@color/_3e363d"
android:textSize="@dimen/text_size_small"/>
<Button
android:id="@+id/btn_leave_message_send"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="10dp"
android:layout_weight="1"
android:background="@drawable/btn_leave_message_send_selector"
android:singleLine="true"
android:text="发送"
android:textColor="@color/_3e363d"
android:textSize="@dimen/text_size_middle"/>
</LinearLayout>
<ListView
android:id="@+id/lv_leave_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/ll_leave_message_input"
android:layout_below="@id/leave_message_title"
android:cacheColorHint="#00000000"
android:divider="@color/dbdbdb"
android:dividerHeight="1dp"
android:fadingEdge="none"/>
<ViewStub
android:id="@+id/activity_leave_message_loading_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/leave_message_title"
android:inflatedId="@+id/activity_leave_message_loading_subTree"
android:layout="@layout/common_loading"/>
<ViewStub
android:id="@+id/leave_message_empty_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/ll_leave_message_input"
android:layout_below="@id/leave_message_title"
android:inflatedId="@+id/leave_message_empty_subTree"
android:layout="@layout/common_tips_layout"/>
<ViewStub
android:id="@+id/leave_message_net_error_stub"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/leave_message_title"
android:inflatedId="@+id/leave_message_net_error_subTree"
android:layout="@layout/common_net_error_layout"/>
</com.storm.durian.view.FitsSystemWindowsLayout>
4、Activity中处理
设置setImmerseLayout(findViewById(R.id.leave_message_title));
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_leave_detail_message);
setImmerseLayout(findViewById(R.id.leave_message_title));
logic = LeaveMessageLogic.getInstance(getApplicationContext());
mHandler = new MyHandler(this);
initView();
}
再看BaseActivity中的setImmerseLayout方法
版本要求仍然是4.4以上
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isStart = true;
ShareSDK.initSDK(this);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
//透明状态栏
getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
//透明导航栏
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
statusBarHeight = ScreenUtil.getStatusBarHeight(this);
}
ScreenManager.getScreenManager().pushActivity(this);
}
protected void setImmerseLayout(View view) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
Window window = getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
// window.addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
int statusBarHeight = ScreenUtil.getStatusBarHeight(this.getBaseContext());
view.setPadding(0, statusBarHeight, 0, 0);
}
}
OK,需要的朋友们可以自己尝试一下!有空的话会将这个沉浸式的留言板的功能写一下分享出来!