效果图:
首先 在AndroidManifest.xml中对Activity配置windowSoftInputMode 设置为adjustPan时弹出软键盘会推动整个activity网上偏移,adjustResize则不会偏移 软键盘会覆盖在Activity上方都不是我们想要的效果。
思路:使用dialog来实现
1.右侧输入框使用TextView实现 点击时弹出dialog(背景全透明) ,在输入时同步数据 也可以实现发送等功能
2.listview在弹出软键盘时需要获取软件盘的高度 来自动滚动listview到底部
关键代码如下:
public static Dialog createTransDialog(Context context, View view) {//创建dialog
Dialog dialog = new Dialog(context, R.style.input_msg_dialog);
dialog.setCanceledOnTouchOutside(false); //禁止外部点击取消
// dialog.setCancelable(false);//禁止返回键取消 --- 外部去设置
dialog.setContentView(view, new LinearLayout.LayoutParams
(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT));
Window window = dialog.getWindow();//添加动画
window.setWindowAnimations(R.style.dialog_anim_sytle_alpha);
WindowManager.LayoutParams lp = window.getAttributes();
lp.width = ScreenCenter.getDisplayWidth();
dialog.getWindow().setAttributes(lp);
return dialog;
}
<!--dialog样式半透明-->
<style name="dialog_tip" parent="android:style/Theme.Dialog">
<item name="android:background">#00000000</item>
<!--背景颜色及和透明程度-->
<item name="android:windowBackground">@android:color/transparent</item>
<!--是否去除标题 -->
<item name="android:windowNoTitle">true</item>
<!--是否去除边框-->
<item name="android:windowFrame">@null</item>
<!--是否浮现在activity之上-->
<item name="android:windowIsFloating">true</item>
</style>
<!--dialog样式全透明-->
<style name="input_msg_dialog" parent="@android:style/Theme.Dialog">
<item name="android:windowFrame">@null</item><!--边框-->
<item name="android:windowIsFloating">true</item><!--是否浮现在activity之上-->
<item name="android:windowIsTranslucent">false</item><!--半透明-->
<item name="android:windowNoTitle">true</item><!--无标题-->
<item name="android:windowBackground">@color/transparent</item><!--背景透明-->
<item name="android:backgroundDimEnabled">false</item><!--模糊-->
</style>
dialog透明度变化动画
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:shareInterpolator="true">
<alpha
android:fromAlpha="0.9"
android:toAlpha="1"
android:duration="90"/>
</set>
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator"
android:shareInterpolator="true">
<alpha
android:fromAlpha="1"
android:toAlpha="0.9"
android:duration="90"/>
</set>
关键获取软键盘高度
两种方法 (亲测)
方法一:(在华为平板和定制PID上都可以获取到准确高度值)
private boolean mIsSoftKeyboardPop = false;
private int mScreenHeight = 0;
private int mOldh = -1;
private int mNowh = -1; //高度
public SoftKeyboardSizeWatchLayout(Context context, AttributeSet attrs) {
super(context, attrs);
mContext = context;
getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener(){
@Override
public void onGlobalLayout() {
Rect r = new Rect();
((Activity)(mContext)).getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
if(mScreenHeight == 0){
mScreenHeight = r.bottom;
}
mNowh = mScreenHeight - r.bottom;
if(mOldh != -1 && mNowh != mOldh) {
if (mNowh > 0) {
mIsSoftKeyboardPop = true; //显示
} else {
mIsSoftKeyboardPop = false; //隐藏
}
}
mOldh = mNowh;
}
});
}
方法二 通过反射获取:(在华为PID可以准确获取值 在定制PID上获取比实际值大)
public static int keyboardHeight = 0;
boolean isVisiableForLast = false;
ViewTreeObserver.OnGlobalLayoutListener onGlobalLayoutListener = null;
public void addOnSoftKeyBoardVisibleListener() {
final View decorView = getWindow().getDecorView();
onGlobalLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect rect = new Rect();
decorView.getWindowVisibleDisplayFrame(rect);
//计算出可见屏幕的高度
int displayHight = rect.bottom - rect.top;
//获得屏幕整体的高度
int hight = decorView.getHeight();
boolean visible = (double) displayHight / hight < 0.8;
int statusBarHeight = 0;
try {
Class<?> c = Class.forName("com.android.internal.R$dimen");
Object obj = c.newInstance();
Field field = c.getField("status_bar_height");
int x = Integer.parseInt(field.get(obj).toString());
statusBarHeight = getContext().getResources().getDimensionPixelSize(x);
} catch (Exception e) {
e.printStackTrace();
}
if(visible&&visible!= isVisiableForLast){
//获得键盘高度
keyboardHeight = hight - displayHight-statusBarHeight;
}
isVisiableForLast = visible;
}
};
decorView.getViewTreeObserver().addOnGlobalLayoutListener(onGlobalLayoutListener);
}
在显示的时候可以listview下发设置一个view来动态改变他高度跟软键盘高度一致推动listview网上移动,然后通过listview的setSelection来选中最后一个item滑动到底部 最后一个item可以用adapter.getcount()-1来获取。
动态设置listview的高度(未测)
//滑动时可以做适当的延时,不然会出现没有滑动到最底部的情况出现
new Handler(getActivity().getMainLooper()).postDelayed(new Runnable() {
@Override
public void run() {
scrollToPosition(mAdapter.getCount()-1);
}
},300);