最近在做项目时,发现一个问题,最后找到了解决办法,特在此记录一下,便于以后自己回忆以及和大家分享
问题描述:我在项目的页面B放了一个线性布局,里面有EditText,本意是从A页面跳转到B页面时,可能会先做别的操作,在修改EditText里面的内容(阐述一下:我是修改完EditText内容后,过几秒自动请求网络更改内容),但是当跳转到B页面时会弹出软键盘,这显然不好,最后在xml布局里面找到EditText的父控件(也就是线性布局)加了两个属性
android:focusable="true"
android:focusableInTouchMode="true"
这样一来进入B页面后就不会加载软键盘
但是想修改EditText里面内容的时候发现一个问题,点击线性布局时会弹出软键盘,最后修改成功(这里采用了一个方法让点击线性布局时弹出软键盘并把焦点设置给EditText,写在代码① 里面),但是点击EditText时键盘是弹出来了,但是没有响应线性布局的点击事件,自然也就没修改成功,所以找了好多办法,最后采用分别监听线性布局的OnClickListener和EditText的OnTouchListener方法,分别设置相同的方法给两个监听,最后解决办法
(注:我发现EditText使用OnClickListener时有问题,因为EditText的setOnClickListener事件响应中,只有获取焦点的时候才会响应,如当焦点在别的控件上时,只能先点击获取焦点,第二次点击才会响应,解决办法改用setOnTouchListener监听)
一、先是线性布局的监听:
LinearLayout llname = findViewById(R.id.ll_name);
llname.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alterName();
}
});
二、再是EditText的监听
EditText etname = findViewById(R.id.et_name);
//设置etname的点击事件
etname.setOnTouchListener(new View.OnTouchListener() {
//按住和松开的标识
int touch_flag=0;
@Override
public boolean onTouch(View v, MotionEvent event) {
touch_flag++;
if(touch_flag==2){
alterName();
}
return false;
}
});
代码①
(描述:进入B页面后当点击线性布局时,弹出键盘,让线性布局下面的EditText获取焦点,然后当键盘弹出时,监听EditText的输入状态,当5秒内连续输入的时候移除上次的延时任务,5秒内不输入时,执行延时任务,我这里是请求网络,更改内容)
// 先弹出键盘,让焦点在输入框上
alterName(){
etMyUsername.requestFocus();// 获取焦点
imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.toggleSoftInput(0, InputMethodManager.SHOW_FORCED);
if(imm.isActive()){
// 获取焦点,先设置光标遇到最后,然后监听输入框的动态变化
etMyUsername.setSelection(etMyUsername.length());
listenetMyUsername();
}
}
/**监听输入框的动态变化*/
private void listenetMyUsername() {
etMyUsername.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
if (delayRun != null) {
//每次editText有变化的时候,则移除上次发出的延迟线程
handler.removeCallbacks(delayRun);
}
}
@Override
public void afterTextChanged(Editable s) {
newName = s.toString();
//延迟5s,如果不再输入字符,则执行该线程的run方法,取消输入框的焦点
handler.postDelayed(delayRun, 2000);
}
});
}
/**
* 延迟线程,看是否还有下一个字符输入
*/
private Runnable delayRun = new Runnable() {
@Override
public void run() {
//uploadName();
//这里写自己的逻辑
}
};
/**上传名字*/
private void uploadName() {
String url = Urls.Url_My_Name;
Map<String, String> params = new HashMap<>();
params.put("uid", uid);
params.put("name", newName);
OkHttpUtils.post()//
.url(url)//
.params(params)//
.build()//
.execute(new MyStringCallback2());
}
/**上传名字*/
class MyStringCallback2 extends StringCallback {
@Override
public void onError(Call call, Exception e) {
ToastUtils.showToast(mActivity, "网络有问题,请检查");
}
@Override
public void onResponse(String response) {
//System.out.println("PersonMsgActivity+界面修改用户名" + response);
MyAlterNameBean bean = new Gson().fromJson(response, MyAlterNameBean.class);
if (bean != null) {
int code = bean.code;
String msg = bean.msg;
if (code != 0) {
ToastUtils.showToast(mActivity, msg);
}else {
//ToastUtils.showToast(mActivity, "修改成功");
// 每次更改成功后要通知我的界面也要改变显示内容
Intent intent = new Intent();
intent.putExtra(Keys.NEWNAME, newName);
setResult(2, intent);
}
}
}
}