javaandroidandroid-layoutandroid-viewswitchcompat

SwitchCompat setTextOn() and setTextOff() doesn't work on runtime


I've tried to set the text on SwitchCompat, but it doesn't work. It only work for the first time. But when you tried to change the text (eg. when button is clicked), it doesn't work.

For example:

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    final SwitchCompat switchCompat = (SwitchCompat)findViewById(R.id.switch_test);
    switchCompat.setTextOn("Yes");
    switchCompat.setTextOff("No");
    switchCompat.setShowText(true);

    Button buttonTest = (Button)findViewById(R.id.button_test);
    buttonTest.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            switchCompat.setTextOn("YOO");
            switchCompat.setTextOff("NAH");
            //switchCompat.requestLayout();  //tried to this but has no effect
            //switchCompat.invalidate();     //tried to this but has no effect
        }
    });
}

You will see that the text stays as Yes and No. I've tried to call requestLayout() and invalidate() with no success. Any idea?


Solution

  • The problem is, that SwitchCompat is not designed with that case in mind. It has private fields mOnLayout and mOffLayout, which are computed once and not recomputed later when text is being changed.

    So, you have to explicitly null them out in order text change to initiate those layouts to be recreated.

    
        buttonTest.setOnClickListener(new View.OnClickListener() {
          @Override
          public void onClick(View v) {
    
            try {
              Field mOnLayout = SwitchCompat.class.getDeclaredField("mOnLayout");
              Field mOffLayout = SwitchCompat.class.getDeclaredField("mOffLayout");
    
              mOnLayout.setAccessible(true);
              mOffLayout.setAccessible(true);
    
              mOnLayout.set(switchCompat, null);
              mOffLayout.set(switchCompat, null);
            } catch (NoSuchFieldException e) {
              e.printStackTrace();
            } catch (IllegalAccessException e) {
              e.printStackTrace();
            }
    
            switchCompat.setTextOn("YOO");
            switchCompat.setTextOff("NAH");
    
          }
        });
    
    

    Result:

    enter image description here