您的位置:首页 > 移动开发 > Android开发

Android 盘弹出时布局内指定内容上移

2017-11-28 18:08 253 查看
在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.Mea
14ba5
sureSpec.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<Integer, Boolean> map = new HashMap<>();
private List<ItemBean> dataList = new ArrayList<ItemBean>(); //  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<Integer> sunList = new ArrayList<Integer>();
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<ItemBean> dataListDeta = new ArrayList<ItemBean>();
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<Integer> 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<ItemBean> 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);
}
}
});

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: