国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 系統(tǒng) > Android > 正文

Android中EditText setText方法的踩坑實戰(zhàn)

2019-12-12 00:45:02
字體:
供稿:網(wǎng)友

1、平平常常中就這樣開始

某一天,我準備做一個搜索功能,這個搜索功能呢大概是在主活動A中,用EditText接收輸入,當EditText監(jiān)聽到輸入框中內(nèi)容有變化,跳轉(zhuǎn)到活動B中,活動B中準備有搜索歷史記錄等等,等在活動B中確定好搜索關鍵詞后,跳回到活動A中,執(zhí)行搜索,并顯示搜索結(jié)果……一切順順利利,然后呢,懵逼了,我回不了活動A了。

當時的情況大致是這樣的,

布局文件:activity_main.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".ActivityA"> <EditText android:inputType="text" android:singleLine="true" android:imeOptions="actionSearch" android:id="@+id/et_search" android:textSize="24sp" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="輸入點啥唄" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:textSize="24sp" android:gravity="center" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="我是主活動啦"/></LinearLayout>

活動A:AcitivityA.java

public class ActivityA extends AppCompatActivity { private EditText searchEditText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //找到EditText,添加文本監(jiān)聽 searchEditText=findViewById(R.id.et_search); searchEditText.addTextChangedListener(new TextWatcher() {  @Override  public void beforeTextChanged(CharSequence s, int start, int count, int after) {  Log.d("editTextSetText","beforeTextChanged");  }  @Override  public void onTextChanged(CharSequence s, int start, int before, int count) {  Log.d("editTextSetText","onTextChanged");  }  @Override  public void afterTextChanged(Editable s) {  Log.d("editTextSetText","afterTextChanged");  startActivity(new Intent(ActivityA.this,ActivityB.class));  } }); //接收B活動傳遞過來的keywords,并顯示在輸入框中 String keyword=getIntent().getStringExtra("keywords"); if(keyword!=null)  searchEditText.setText(keyword); }

活動B布局文件:activity_search.xml

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <EditText android:id="@+id/et_search_keywords" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="輸入你想要找的東西" android:textSize="24sp" android:inputType="text" android:singleLine="true" android:imeOptions="actionSearch"/> <TextView android:textSize="24sp" android:gravity="center" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:text="我就是那個準備搜索關鍵詞,歷史記錄等等等等的活動B啦" /></LinearLayout>

活動B:ActivityB.java

public class ActivityB extends AppCompatActivity { private EditText editTextKeyWords; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_search); editTextKeyWords = findViewById(R.id.et_search_keywords); editTextKeyWords.setOnEditorActionListener(new TextView.OnEditorActionListener() {  @Override  public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {  if (actionId == EditorInfo.IME_ACTION_SEARCH) {   //將取得關鍵字傳遞到A中   String keywords = v.getText().toString().trim();   Intent intent = new Intent(ActivityB.this, ActivityA.class);   intent.putExtra("keywords", keywords);   Log.d("editTextSetText", "B keywords:" + keywords);   startActivity(intent);   ActivityB.this.finish();  }  return false;  } }); }}

OK,至此大功告成,我成功復原了當時我大致做法,也還原了當時的Bug:在A中有輸入時,跳到B,在B中確定好關鍵詞后,點擊搜索(你的搜索在哪里,讓你們看下圖吧)


看到右下角我圈起來的那個搜索按鈕了嗎,布局文件照著我那個寫,監(jiān)聽就是editTextKeyWords.setOnEditorActionListener(……),布局中重要的是

 android:inputType="text" android:singleLine="true" android:imeOptions="actionSearch"

這個主要是參看這位大大的,當然了,在此這不算重點,重點是我又成功寫了個Bug。當時項目挺急的,我弄了半天沒弄明白,(我一直以為是A活動因為setText而崩潰了,然而沒有l(wèi)og……當然,最終證明似乎不是這樣子。),無奈之下,福靈心至,想到:

2、用了setHint()解決了當務之急

無奈之下選擇了該方法,問題成功解決,也沒什么明顯瑕疵,就是心理一直惦記著,這他丫的問題出在什么地方呢,定位當然是定位到了A活動中的searchEditText.setText(keyword)這一句。

后來加了幾天班,等稍微有空了,我再回頭瞧瞧,莫非,谷歌給我們寫了個小bug,結(jié)果嘛:事實證明,好像這東西是自己的鍋。

3、發(fā)現(xiàn)敵蹤跡

當時我實在onResume()調(diào)用searchEditText.setText(keyword)這幾句的,所以問題顯得比我上面寫的要隱蔽些。當然,有空了之后,我進入setText方法,一步步執(zhí)行,當然了,沒發(fā)現(xiàn)明顯問題。只是我偶爾會發(fā)現(xiàn)它會不經(jīng)意間往beforeTextChanged等這一兩個方法中眺一下,那么想一想我在里面又做了什么……,似乎我發(fā)現(xiàn)問題所在了。那么有了猜測,對該方法添加log,我們隊log做下修改,使其能明確地顯示程序執(zhí)行順序,修改代碼如下:

ActivityA.java

public class ActivityA extends AppCompatActivity { private EditText searchEditText; public static int executeOrder=0;//表示log執(zhí)行順序,進而推測代碼執(zhí)行順序 @Override protected void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_main);  Log.d("editTextSetText","after setContentView "+executeOrder++);  //找到EditText,添加文本監(jiān)聽  searchEditText=findViewById(R.id.et_search);  searchEditText.addTextChangedListener(new TextWatcher() {   @Override   public void beforeTextChanged(CharSequence s, int start, int count, int after) {    Log.d("editTextSetText","beforeTextChanged "+executeOrder++);   }   @Override   public void onTextChanged(CharSequence s, int start, int before, int count) {    Log.d("editTextSetText","onTextChanged "+executeOrder++);   }   @Override   public void afterTextChanged(Editable s) {    Log.d("editTextSetText","afterTextChanged "+executeOrder++);    startActivity(new Intent(ActivityA.this,ActivityB.class));   }  });  //接收B活動傳遞過來的keywords,并顯示在輸入框中  String keyword=getIntent().getStringExtra("keywords");  if(keyword!=null) {   searchEditText.setText(keyword);   Log.d("editTextSetText","after set text "+executeOrder++);   /*searchEditText.setHint(keyword);*/  } }}

ActivityB.java

public class ActivityB extends AppCompatActivity { private EditText editTextKeyWords; @Override public void onCreate(Bundle savedInstanceState) {  super.onCreate(savedInstanceState);  setContentView(R.layout.activity_search);  Log.d("editTextSetText", "B after setContentView " +ActivityA.executeOrder++);  editTextKeyWords = findViewById(R.id.et_search_keywords);  editTextKeyWords.setOnEditorActionListener(new TextView.OnEditorActionListener() {   @Override   public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {    if (actionId == EditorInfo.IME_ACTION_SEARCH) {      //將取得關鍵字傳遞到A中      String keywords = v.getText().toString().trim();      Intent intent = new Intent(ActivityB.this, ActivityA.class);      intent.putExtra("keywords", keywords);      Log.d("editTextSetText", "B keywords:" + keywords+" " +ActivityA.executeOrder++);      startActivity(intent);      ActivityB.this.finish();    }    return false;   }  }); }}

執(zhí)行一遍,log如下:


上述log顯示,做如下解讀:

1、 啟動應用,執(zhí)行初始化,打印 0

2、輸入內(nèi)容,執(zhí)行1,2,3,到啟動活動B

3、活動B初始化執(zhí)行 4

5、 活動B中點擊搜索 5,并啟動活動A

6、A再一次初始化 執(zhí)行6

7、問題出來了,為什么會執(zhí)行7、8、9,此時我們并沒有EditText輸入內(nèi)容,但是監(jiān)聽觸發(fā)了。

8、 執(zhí)行9之后,啟動活動B,執(zhí)行11沒問題,但是10的順序按理說應該在6之后、緊接著6.

盡管未能完全解讀這個執(zhí)行順序,但是,寫的程序陷入了一個類似死循環(huán)的bug是沒有問題的,這也就解開了為什么返回不了A活動的問題,并不是不能返回A,而是返回A之后又跳轉(zhuǎn)到B了。

進一步調(diào)試,在關鍵節(jié)點增加log,我們再setText前后增加log

if(keyword!=null) {   Log.d("editTextSetText","after set text "+executeOrder++);   searchEditText.setText(keyword);   Log.d("editTextSetText","after set text "+executeOrder++);   /*searchEditText.setHint(keyword);*/  }

log信息:


關鍵點我已經(jīng)標出來了,在7和11間,有了監(jiān)聽方法的執(zhí)行,說明:EditText的setText方法會觸發(fā) 文本變化的監(jiān)聽,這就是此次踩坑的根源。

4、 捕獲兇手:setText()方法會觸發(fā)EditText文本變化的監(jiān)聽

5、解決方案:將setText設置在設置監(jiān)聽之前,或者用setHint也可以。

如上,找出問題癥結(jié)之后,解決辦法就很簡單了,我們將setText寫在設置監(jiān)聽之前就可以避免該坑,或者干脆用setHint方法。

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對武林網(wǎng)的支持。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 大厂| 河间市| 芷江| 诏安县| 霍山县| 鄢陵县| 虎林市| 墨脱县| 大安市| 通榆县| 科技| 甘谷县| 玛纳斯县| 芦溪县| 扎兰屯市| 邵武市| 旬阳县| 太白县| 那曲县| 黎川县| 平武县| 南陵县| 若尔盖县| 杭锦旗| 平阴县| 高密市| 古田县| 六枝特区| 丹凤县| 南部县| 兰考县| 宜章县| 安丘市| 大英县| 芜湖县| 海口市| 康马县| 罗城| 五台县| 大石桥市| 寿阳县|