1. 程式人生 > >EditText監聽輸入完成和設定點選事件時與父控制元件的衝突問題

EditText監聽輸入完成和設定點選事件時與父控制元件的衝突問題

最近在做專案時,發現一個問題,最後找到了解決辦法,特在此記錄一下,便於以後自己回憶以及和大家分享

問題描述:我在專案的頁面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);

                }
            }
        }
    }