直接描述我的效果和具体实现,至于其他做法为什么行或者为什么不行,在此不做讨论;
效果图:
软键盘隐藏的时候
软键盘显示的时候
实现思路:
不管界面上是什么布局,只要能获取到对应的实例,都能对他进行操作,我这里标题是ToolBar,下面消息列表是RecycleView和一个RelativeLayout,ToolBar下面整个在一个大的RelativeLayout里面,既然要保持ToolBar在顶部,又要输入框正常弹起显示,故我们直接就对大的RelativeLayout操作,软件盘弹起后,监控软键盘的高度,对大的RelativeLayout显示进行压缩,由于RecyclerView的可滑动性,故相当于对RecyclerView进行了压缩,压缩就是重新设置控件的高度,当软键盘隐藏时,监听到软键盘的变化,再次设置大的RelativeLayout的高度,回复原样。监控软键盘的高度使用ViewTreeObserver类(对于这个类的详细就不说了),这里使用该类里的OnGlobalLayoutListener监听器来监听软键盘的显示与隐藏。
上代码:
(部分代码已删除,仅保留主要思想的代码)
import android.Manifest;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import cn.crledu.dcol.R;
import cn.crledu.dcol.adapter.TalkMessageAdapter;
import cn.crledu.dcol.entity.ChatMessage;
import cn.crledu.dcol.utils.Utils;
public class MsgTalkActivity extends AppCompatActivity {
private Bitmap bitmap;//选择需要发送的图片
private int keyHeight = 0;//软键盘的高度
private int screenHeight = 0;//屏幕的高度
private int titleHeight = 0;//标题栏的高
private int toolBarHeight = 0;//ToolBar的高
private int tempSoftHeight = 8;//用来调整布局与软键盘的距离
private int tempHeight = 32;
private InputMethodManager imm;
private static boolean isAction = false;
private ViewTreeObserver.OnGlobalLayoutListener mLayoutChangeListener;
//处理软键盘的变动对内容布局的改变
private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 0://显示软键盘
lp.height = screenHeight - keyHeight - toolBarHeight - 2 * titleHeight - Utils.trueDensity(MsgTalkActivity.this, tempSoftHeight);
ll_content_view.setLayoutParams(lp);
break;
case 1://隐藏软键盘
lp.height = screenHeight - toolBarHeight - 2 * titleHeight - Utils.trueDensity(MsgTalkActivity.this, tempHeight);
ll_content_view.setLayoutParams(lp);
break;
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.msg_talk);
Toolbar custom_toolbar = (Toolbar) findViewById(R.id.custom_toolbar);
setSupportActionBar(custom_toolbar);
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
screenHeight = getWindowManager().getDefaultDisplay().getHeight();
toolBarHeight = custom_toolbar.getHeight();
titleHeight = utils.getStatusBarHeight(this);
ll_content_view = (LinearLayout) findViewById(R.id.ll_content_view);
lp = (LinearLayout.LayoutParams) ll_content_view.getLayoutParams();
msg_context = (RecyclerView) findViewById(R.id.msg_context);
msg_context.setLayoutManager(new LinearLayoutManager(this));
adapter = new TalkMessageAdapter(lists, this);
msg_context.setAdapter(adapter);
msg_context.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm.isActive() && getCurrentFocus() != null) {
if (getCurrentFocus().getWindowToken() != null) {
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
}
}
return false;
}
});
mLayoutChangeListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
int softHeight = screenHeight - (r.bottom - r.top);
if (isAction = softHeight > screenHeight / 3) {//软键盘显示
keyHeight = softHeight;
handler.sendEmptyMessage(0);//显示
} else {
handler.sendEmptyMessage(1);//隐藏
}
}
};
getWindow().getDecorView().getViewTreeObserver().addOnGlobalLayoutListener(mLayoutChangeListener);
}
@Override
protected void onDestroy() {
super.onDestroy();
//移除监听,释放资源
getWindow().getDecorView().getViewTreeObserver().removeOnGlobalLayoutListener(mLayoutChangeListener);
}
}
大致就这些了,自己的一点总结,肯定有不足的地方,欢迎指正。