在android 手机上 ,点击输入框 都会弹出输入键盘 那么问题来了 ,Android SDK目前提供的软键盘弹出模式接口只有两种:一是弹时自动回冲界面,将所有元素上顶,一种则是不重绘界面,直接将控件元素遮住。
解决方法:
第一步:给想要被顶上去的内容嵌套一个 ScrollView :
<ScrollView
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:scrollbars="none"
>
…… 想要被顶上去的内容 ……
ScrollView>
第二部 在清单文件中给对应的 Activity 设置
android:windowSoftInputMode="adjustResize"
一些机型到这里问题就已经解决了!
有些机型会出现点击过 EditView 它获得了焦点也弹出了软键盘,
但是收回软键盘后,再点击该 EditView 会出现被软键盘遮挡的情况,
点其它 EditView 后,再来点该 EditView 又恢复正常不再被遮挡,
为了解决此问题见如下:
第三步:
发现去掉 ScrollView 的 android:scrollbars=”none” 属性后问题就解决了!
但会出现滚动条,所以这个属性不能去掉,
只需在 Activity 的 onCreate 事件处理函数中的 setContentView 方法后紧跟着写上
getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
即可解决此问题!
下边说下我遇到问题 ,不管上述方法 如何设置, 都会将 不想弹出的东西弹出屏幕解决方法。
通用方法:
实现思路: 用屏幕 高度, 减去状态栏高度,减去标题的高度,减去键盘高度 。 得到我们键盘弹出需要展示的高度。如下图:
主要调用方法:
/**
*
*
* @param root 最外层布局 页面根布局
* @param needToScrollView 要滚动的布局,就是说在键盘弹出的时候,你需要视图滚动上去的View,在键盘隐藏的时候,他又会滚动到原来的位置的布局
*/
private void controlKeyboardLayout(final View root, final View needToScrollView) {
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private Rect r = new Rect();
@Override
public void onGlobalLayout() {
//拿到标题栏的高度
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
title_ll.measure(w, h);
int titlebarHeight = title_ll.getMeasuredHeight();
int width = title_ll.getMeasuredWidth();
int stateHeight = -1;
//获取status_bar_height资源的ID
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
//根据资源ID获取响应的尺寸值
stateHeight = getResources().getDimensionPixelSize(resourceId);
}
Log.e("onGlobalLayout", "状态栏高度:" + stateHeight);
// int titlebarHeight;
// titlebarHeight = (int) getResources().getDimension(R.dimen.titlebar_height);
Log.e("onGlobalLayout", "标题栏高度 :" + titlebarHeight);
//获取当前界面可视部分
GoodsStatusActivity.this.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//获取屏幕的高度
int screenHeight = GoodsStatusActivity.this.getWindow().getDecorView().getRootView().getHeight();
Log.e("onGlobalLayout", "获取屏幕的高度 :" + screenHeight);
//此处就是用来获取键盘的高度的, 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
int heightDifference = screenHeight - r.bottom;
Log.e("onGlobalLayout", "键盘高度 :" + heightDifference);
ViewGroup.LayoutParams layoutParams = needToScrollView.getLayoutParams();
//拿到需要调整的高度,这里需要按照实际情况计算你们自己的高度
//博主需要的高度是:屏幕宽度-状态栏高度-标题栏高度-键盘的高度
int height = screenHeight - titlebarHeight - heightDifference - stateHeight;
//如果计算出来的和原来的不一样,那么就调整一下
if (height != layoutParams.height) {
//设置新的高度
layoutParams.height = height;
//重新布局
rl_root.requestLayout();
}
/* // 键盘弹出 list view 显示到最后一条
if (heightDifference>0){
list_lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
list_lv.setStackFromBottom(true);
}
*/
}
});
}
完整页面代码
package com.demo.checkboxdemoproject;
import android.graphics.Rect;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements Adapter.OnShowItemClickListener, View.OnClickListener {
private String TAG = "MainActivity";
private LinearLayout l_ll, r_ll, title_ll;
private TextView tile_tv, r_title_tv;
private ImageView l_title_iv;
private ListView list_lv;
private LinearLayout del_ll, edit_ll, group_ll, deleteNumber_ll;
LinearLayout rl_root;
private boolean isShow = false;
private Adapter myAdapter;
private EditText text_et;
private Button send_btn;
private TextView del_tv, chax_all_tv, chax_number_tv, chax_reverse_tv, texeSize_tv, empty_tv;
private Map map = new HashMap<>();
private List dataList = new ArrayList(); // list 数据原 排序后
private TextWatcher watcher = new TextWatcher() {
//文本变化中
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Log.d("TextWatcher", "——————变化中_" + count);
}
//文本变化之前
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Log.d("TextWatcher", "变化前 ——————" + s);
}
// 文本变化之后
@Override
public void afterTextChanged(Editable s) {
String text = s.toString().trim();
if (text != null && !text.equals("")) {
texeSize_tv.setText(text.length() + "/1000");
} else {
texeSize_tv.setText("0/1000");
}
Log.d("TextWatcher", "变化后" + s.toString());
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViews();
initTitle();
setListviewData(false, false); //全部不现实 false 不选择
myAdapter = new Adapter(dataList, this);
list_lv.setAdapter(myAdapter);
list_lv.setEmptyView(empty_tv);
if (dataList != null && dataList.size() < 1) {
r_ll.setVisibility(View.INVISIBLE);
r_title_tv.setText("编辑");
} else {
r_ll.setVisibility(View.VISIBLE);
r_title_tv.setText("编辑");
}
myAdapter.setOnShowItemClickListener(this);
list_lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView> parent, View view, int position, long id) {
// TODO 自动生成的方法存根
if (isShow) {
ItemBean item = dataList.get(position);
boolean isChecked = item.isChecked();
if (isChecked) {
item.setChecked(false);
} else {
item.setChecked(true);
}
myAdapter.notifyDataSetChanged();
List sunList = new ArrayList();
for (int i = 0; i < dataList.size(); i++) {
if (dataList.get(i).isChecked()) {
Log.d(TAG, "选着好的——" + "位置——" + i);
sunList.add(i);
}
}
chax_number_tv.setText("已选中" + sunList.size() + "条" + " 共" + dataList.size() + "条");
Log.d(TAG, " 点击了item选着啦 " + sunList.size());
} else {
Log.d(TAG, " 点击了item————homeId");
}
}
});
del_tv.setOnClickListener(this);
send_btn.setOnClickListener(this);
chax_all_tv.setOnClickListener(this);
chax_reverse_tv.setOnClickListener(this);
text_et.addTextChangedListener(watcher);
// 键盘打开
// controlKeyboardLayout(rl_root, group_ll);
}
// 初始化view
private void findViews() {
title_ll = (LinearLayout) findViewById(R.id.title_ll_2);
group_ll = (LinearLayout) findViewById(R.id.group_ll);
send_btn = (Button) findViewById(R.id.send_btn);
list_lv = (ListView) findViewById(R.id.list_lv);
del_tv = (TextView) findViewById(R.id.del_button);
chax_reverse_tv = (TextView) findViewById(R.id.chax_reverse_tv);
del_ll = (LinearLayout) findViewById(R.id.del_ll);
deleteNumber_ll = (LinearLayout) findViewById(R.id.deleteNumber_ll);
edit_ll = (LinearLayout) findViewById(R.id.edit_ll);
chax_all_tv = (TextView) findViewById(R.id.chax_all_tv);
chax_number_tv = (TextView) findViewById(R.id.chax_number_tv);
text_et = (EditText) findViewById(R.id.text_et);
texeSize_tv = (TextView) findViewById(R.id.texeSize_tv);
edit_ll.setVisibility(View.VISIBLE);
del_ll.setVisibility(View.GONE);
texeSize_tv.setText("0/1000");
empty_tv = (TextView) findViewById(R.id.empty_tv);
rl_root = (LinearLayout) findViewById(R.id.rl_root);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.l_ll:
finish();
break;
// 点击编辑 全部显示出来
case R.id.r_ll:
String text = r_title_tv.getText().toString().trim();
if (text.equals("完成")) {
if (isShow) {
// selectedList.clear();
for (ItemBean bean : dataList) {
bean.setChecked(false);
bean.setShow(false);
}
myAdapter.notifyDataSetChanged();
isShow = false;
}
r_title_tv.setText("编辑");
r_ll.setVisibility(View.VISIBLE);
edit_ll.setVisibility(View.VISIBLE);
del_ll.setVisibility(View.GONE);
}
if (text.equals("编辑")) {
isShow = true;
myAdapter.notifyDataSetChanged();
r_title_tv.setText("完成");
r_ll.setVisibility(View.VISIBLE);
isShow = true;
if (isShow) {
// selectedList.clear();
for (ItemBean bean : dataList) {
bean.setChecked(false);
bean.setShow(true);
}
myAdapter.notifyDataSetChanged();
// isShow = false;
}
edit_ll.setVisibility(View.GONE);
del_ll.setVisibility(View.VISIBLE);
chax_number_tv.setText("已选中 0条" + " 共" + dataList.size() + "条");
}
break;
// 删除
case R.id.del_button:
// 有选着的数据 把它删除,没有选择的 , 就再次加入集合 ,注意 集合清空
if (myAdapter.getNumber() != 0 && myAdapter.getNumber() > 0) {
List dataListDeta = new ArrayList();
ItemBean goodsStatusBean;
for (int i = 0; i < dataList.size(); i++) {
if (dataList.get(i).isChecked() == true) {
Log.d(TAG, "需要删除的主键——true-- " + dataList.get(i).getId());
} else {
goodsStatusBean = new ItemBean();
goodsStatusBean.setTitle(dataList.get(i).getTitle()); // 标题
goodsStatusBean.setId(dataList.get(i).getId());
goodsStatusBean.setChecked(false);
goodsStatusBean.setShow(isShow);
dataListDeta.add(goodsStatusBean);
}
}
dataList.clear();
dataList.addAll(dataListDeta);
myAdapter.notifyDataSetChanged();
dataListDeta.clear();
chax_number_tv.setText("已选中" + "0" + "条" + " 共" + dataList.size() + "条");
// del_tv.setBackgroundResource(R.color._cccccc_bg);
deleteNumber_ll.setVisibility(View.INVISIBLE);
if (dataList != null && dataList.size() < 1) {
r_ll.setVisibility(View.GONE);
del_ll.setVisibility(View.GONE);
edit_ll.setVisibility(View.VISIBLE);
r_title_tv.setText("编辑");
} else {
r_ll.setVisibility(View.VISIBLE);
r_title_tv.setText("完成");
}
} else {
Toast.makeText(this, "请选择需要删除的数据", Toast.LENGTH_SHORT).show();
}
break;
case R.id.send_btn:
String getText = text_et.getText().toString().trim();
if (getText != null && !getText.equals("")) {
ItemBean titleCardAndFileBean = new ItemBean();
titleCardAndFileBean.setId(dataList.size()+1); // 注意这里 ,这个ID 不可以重复
titleCardAndFileBean.setChecked(false);
titleCardAndFileBean.setTitle(getText);
titleCardAndFileBean.setTime(System.currentTimeMillis() + "");
titleCardAndFileBean.setShow(false);
dataList.add(titleCardAndFileBean);
// 展示在最后
if (myAdapter != null) {
myAdapter.notifyDataSetChanged();
list_lv.setSelection(dataList.size() - 1);
} else {
myAdapter = new Adapter(dataList, this);
list_lv.setAdapter(myAdapter);
list_lv.setSelection(dataList.size() - 1);
}
text_et.setText("");
texeSize_tv.setText("0/1000");
if (dataList != null && dataList.size() < 1) {
r_ll.setVisibility(View.INVISIBLE);
} else {
r_ll.setVisibility(View.VISIBLE);
}
} else {
Toast.makeText(this, "输入不能为空", Toast.LENGTH_SHORT).show();
return;
}
break;
// 全选 把在展示的数据 全部选择
case R.id.chax_all_tv:
dataList.clear();
setListviewData(true, true);
myAdapter.notifyDataSetChanged();
if (dataList.size() < 1) {
return;
}
chax_number_tv.setText("已选中" + dataList.size() + "条" + " 共" + dataList.size() + "条");
chax_reverse_tv.setVisibility(View.VISIBLE);
chax_all_tv.setVisibility(View.GONE);
break;
// 反选 把在展示的数据 是否选择 反过来
case R.id.chax_reverse_tv:
chax_reverse_tv.setVisibility(View.GONE);
chax_all_tv.setVisibility(View.VISIBLE);
List sunList = new ArrayList<>();
ItemBean goodsStatusBean;
for (int i = 0; i < dataList.size(); i++) {
if (dataList.get(i).isChecked() == true) {
Log.d("del_button", "需要删除的主键——true-- " + dataList.get(i).getId());
goodsStatusBean = new ItemBean();
goodsStatusBean.setTitle(dataList.get(i).getTitle()); // 标题
goodsStatusBean.setId(dataList.get(i).getId());
goodsStatusBean.setChecked(false);
goodsStatusBean.setShow(isShow);
dataList.set(i, goodsStatusBean);
} else {
Log.d("del_button", "需要删除的主键— false—" + dataList.get(i).getId());
goodsStatusBean = new ItemBean();
goodsStatusBean.setTitle(dataList.get(i).getTitle()); // 标题
goodsStatusBean.setId(dataList.get(i).getId());
goodsStatusBean.setChecked(true);
goodsStatusBean.setShow(isShow);
dataList.set(i, goodsStatusBean);
sunList.add(i);
}
}
myAdapter.notifyDataSetChanged();
chax_number_tv.setText("已选中" + sunList.size() + "条" + " 共" + dataList.size() + "条");
sunList.clear();
break;
}
}
// 添加 listvie 数据 isShow 是否显示 , isChecked 是否选着
private List< ItemBean> setListviewData(boolean isShow, boolean isChecked) {
ItemBean titleCardAndFileBean = new ItemBean();
titleCardAndFileBean.setId(1); // 注意ID 不可以重复
titleCardAndFileBean.setChecked(isChecked);
titleCardAndFileBean.setTitle("数据1?????");
titleCardAndFileBean.setTime(1234556 + "");
titleCardAndFileBean.setShow(isShow);
dataList.add(titleCardAndFileBean);
ItemBean titleCardAndFileBean2 = new ItemBean();
titleCardAndFileBean2.setId(2); // 注意ID 不可以重复
titleCardAndFileBean2.setChecked(isChecked);
titleCardAndFileBean2.setTitle("数据1?????");
titleCardAndFileBean2.setTime(222222222 + "");
titleCardAndFileBean2.setShow(isShow);
dataList.add(titleCardAndFileBean2);
return dataList;
}
private void initTitle() {
l_ll = (LinearLayout) findViewById(R.id.l_ll);
r_ll = (LinearLayout) findViewById(R.id.r_ll);
tile_tv = (TextView) findViewById(R.id.tile_tv);
l_title_iv = (ImageView) findViewById(R.id.l_title_iv);
r_title_tv = (TextView) findViewById(R.id.r_title_tv);
tile_tv.setText("我是标题");
l_title_iv.setImageResource(R.mipmap.w_fanhui_title);
r_title_tv.setText("编辑");
l_ll.setOnClickListener(this);
r_ll.setOnClickListener(this);
}
// 点击 单选监听
@Override
public void onShowItemClick(ItemBean bean, int position, List items) {
if (myAdapter.getNumber() > 0) {
// del_tv.setBackgroundResource(R.color._c82015_bg);
deleteNumber_ll.setVisibility(View.VISIBLE);
} else {
// del_tv.setBackgroundResource(R.color._cccccc_bg);
deleteNumber_ll.setVisibility(View.INVISIBLE);
}
}
/**
* 在聊天的内容比较多的时候没有问题,当时在内容比较少的时候上面的内容就会看不见,所以这个方法也是不可取的
*
* @param root 最外层布局
* @param needToScrollView 要滚动的布局,就是说在键盘弹出的时候,你需要试图滚动上去的View,在键盘隐藏的时候,他又会滚动到原来的位置的布局
*/
private void controlKeyboardLayout(final View root, final View needToScrollView) {
root.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
private Rect r = new Rect();
@Override
public void onGlobalLayout() {
//拿到标题栏的高度
int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
title_ll.measure(w, h);
int titlebarHeight = title_ll.getMeasuredHeight();
int width = title_ll.getMeasuredWidth();
int stateHeight = -1;
//获取status_bar_height资源的ID
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
//根据资源ID获取响应的尺寸值
stateHeight = getResources().getDimensionPixelSize(resourceId);
}
Log.e("onGlobalLayout", "状态栏高度:" + stateHeight);
// int titlebarHeight;
// titlebarHeight = (int) getResources().getDimension(R.dimen.titlebar_height);
Log.e("onGlobalLayout", "标题栏高度 :" + titlebarHeight);
//获取当前界面可视部分
MainActivity. this.getWindow().getDecorView().getWindowVisibleDisplayFrame(r);
//获取屏幕的高度
int screenHeight = MainActivity.this.getWindow().getDecorView().getRootView().getHeight();
Log.e("onGlobalLayout", "获取屏幕的高度 :" + screenHeight);
//此处就是用来获取键盘的高度的, 在键盘没有弹出的时候 此高度为0 键盘弹出的时候为一个正数
int heightDifference = screenHeight - r.bottom;
Log.e("onGlobalLayout", "键盘高度 :" + heightDifference);
ViewGroup.LayoutParams layoutParams = needToScrollView.getLayoutParams();
//拿到需要调整的高度,这里需要按照实际情况计算你们自己的高度
//博主需要的高度是:屏幕宽度-状态栏高度-标题栏高度-键盘的高度
int height = screenHeight - titlebarHeight - heightDifference - stateHeight;
//如果计算出来的和原来的不一样,那么就调整一下
if (height != layoutParams.height) {
//设置新的高度
layoutParams.height = height;
//重新布局
rl_root.requestLayout();
}
// 键盘弹出 list view 显示到最后一条
if (heightDifference>0){
list_lv.setTranscriptMode(ListView.TRANSCRIPT_MODE_ALWAYS_SCROLL);
list_lv.setStackFromBottom(true);
}
}
});
}
}