38

我在recyclerview中有一個開關,在從DB中檢索數據後,數據顯示在recyclerview中。當回收站打開時,我讀取DB,如果DB中的某個字段爲「Y」,則啓用該開關或禁用該開關。 現在的問題是隨之而來的onCheckedchanged偵聽器也被稱爲,我只想在用戶手動設置開關時調用onCheckedChanged。onCheckedChanged自動調用

在打開recyclerview以下被執行:

holder.enabledisable.setChecked(messengerRecord.get_is_valid().equalsIgnoreCase("Y")); 

ViewHolder類:

public class viewHolder extends RecyclerView.ViewHolder implements CompoundButton.OnCheckedChangeListener{ 
public SwitchCompat enabledisable; 
public viewHolder(View v) { 
      enabledisable = (SwitchCompat) v.findViewById(R.id.enabledisable); 
      enabledisable.setOnCheckedChangeListener(this); 
................................... 
................................... 

當recyclerView剛剛打開被稱爲OncheckedChanged方法:

@Override 
     public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
      Log.v("ranjith","called oncheckedchanged"); 
      MessengerRecord rec; 
      rec = dbHelper.getRecord(descview.getText().toString()); 
      switch (buttonView.getId()) { 
       case R.id.enabledisable: 
        if (isChecked) { 
         rec.set_is_valid("Y"); 
         dbHelper.updateRecord(rec); 
        } 
} 

在佈局文件:

<android.support.v7.widget.SwitchCompat 
    android:layout_marginRight="16dp" 
    android:layout_marginEnd="16dp" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:focusable="false" 
    android:id="@+id/enabledisable" 
    android:layout_alignRight="@+id/textview_to" 
    android:layout_alignEnd="@+id/textview_to" 
    android:layout_alignParentRight="true" 
    android:layout_alignParentEnd="true"/> 

回答

142

這很奇怪我們所有人都有這個問題,但沒有官方谷歌回答這個簡單的問題。

一個最簡單是檢查:

buttonView.isPressed() 

如果爲真,意味着用戶點擊美景。

不需要全局變量。

希望這會有所幫助。

+6

浪費了很多天試圖找出爲什麼onCheckedChanged被自動調用並拋出我的單選按鈕狀態,這意味着我的應用程序無用。感謝您指出一個簡單而有效的解決方案。最後,我可以轉向生活中的其他重要事情。 – zeeshan

+2

這絕對有效。但是,如果用戶滑動交換機,是否會發生任何事件?在這種情況下,如果使用的是滑動開關,這是行不通的。 – dhun

+0

豎起大拇指。這是我們在幾乎所有應用程序的設置部分遇到的一個非常常見的問題。而這個解決方案是最好也是最簡單的 –

0

使用全局布爾變量,當從數據庫讀取數據時將其設置爲「true」,並在onCheckChange中檢查(if)後再次將其設置爲「false」。在onCheckChange方法中首先檢查這個變量是否爲false執行代碼else return(該變量的默認值必須爲false);

@Override 
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 
    if(!isSourceDB){ 

     Log.v("ranjith","called oncheckedchanged"); 
     MessengerRecord rec; 
     rec = dbHelper.getRecord(descview.getText().toString()); 
     switch (buttonView.getId()) { 
      case R.id.enabledisable: 
       if (isChecked) { 
        rec.set_is_valid("Y"); 
        dbHelper.updateRecord(rec); 

      } 
    }//end if 
    isSourceDB = false; }// end oncheckedchange 
+0

這似乎是一個工作。我一直在尋找一種android中的功能,它只在用戶點擊時調用oncheckedchanged(即焦點已收到)。但它的工作。從我投票。 – Psypher

+0

@Ranjith:當Switch單擊第一個toggle()方法時被調用,並在toggle方法中調用setchecked()方法。所以你應該在切換方法上插入上面的代碼而不是checkchanged。順便說一句,如果你只想寫onCheckChange(),你應該寫一個方法,只改變開關的GUI狀態,並在從DB讀取數據時調用它。 – mk72

0

我在ViewPager屏幕內部遇到了同樣的問題。當我們在片段之間切換時,onCheckedChanged監聽器被一次又一次地調用。

如果有人仍然在尋找這個問題,請嘗試一下。

@Override 
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 

      if (buttonView.isInTouchMode()) { 
       ... //Your code will come here.   
      } 
} 
+0

我會盡力讓你知道它是否適用於我 – Psypher

+0

沒有爲我工作,但buttonView.isPressed()做到了。 – Matthew

6

我已經結束了使用SwitchCompat的這個子類來避免這個問題。這樣我就不需要使用這個類的樣板代碼。 每當你需要改變不費一槍監聽器,就使用setCheckedSilent代替setChecked

import android.content.Context; 
import android.os.Parcelable; 
import android.support.v7.widget.SwitchCompat; 
import android.util.AttributeSet; 

/** 
* Created by emanuel on 30/5/16. 
*/ 
public class Switch extends SwitchCompat { 

    private OnCheckedChangeListener listener; 

    public Switch(Context context, AttributeSet attrs) { 
     super(context, attrs); 
    } 

    @Override 
    public void setOnCheckedChangeListener(OnCheckedChangeListener listener) { 
     this.listener = listener; 
     super.setOnCheckedChangeListener(listener); 
    } 

    @Override 
    public void onRestoreInstanceState(Parcelable state) { 
     super.setOnCheckedChangeListener(null); 
     super.onRestoreInstanceState(state); 
     super.setOnCheckedChangeListener(listener); 
    } 

    public void setCheckedSilent(boolean checked) { 
     super.setOnCheckedChangeListener(null); 
     super.setChecked(checked); 
     super.setOnCheckedChangeListener(listener); 
    } 
} 

onRestoreInstanceState被觸發的收聽此外,在onViewCreated方法設置時,你會回到以前的片段。 希望它適合你!