Basing myself on tynn's option of overriding OnBindViewHolder method, I have implemented it and it is working. So I will post here the code with explanatory comments in case someone wants to use it.
NOTE: I'm developing my app on Xamarin.Android, so the code is in C#, but it should be really intuitive to translate it to Java (or Kotlin).
CustomSwitchPreferenceWidget.cs
namespace KeepTravelling.Ui
{
class CustomSwitchPreferenceWidget : SwitchPreferenceCompat
{
private int TitleId = 0;
private bool IsTitleFound => TitleId > 0; //equivalent to bool IsTitleFound(){ return TitleId > 0};
public string TextWhenOn { get; set; }//getters and setters
public string TextWhenOff { get; set; }
public CustomSwitchPreferenceWidget(Context context, IAttributeSet attrs) : base(context, attrs)
{
TypedArray attrsArray = context.ObtainStyledAttributes(attrs, Resource.Styleable.CustomSwitchPreferenceWidget);
TextWhenOn = attrsArray.GetString(Resource.Styleable.CustomSwitchPreferenceWidget_textWhenOn);
TextWhenOff = attrsArray.GetString(Resource.Styleable.CustomSwitchPreferenceWidget_textWhenOff);
}
//Method that will search through holder element for a view with id = "title"
//Once found it will store it in TitleId member
private void FindTitleId(PreferenceViewHolder holder)
{
//Base element is a LinearLayout, but you can check it again to make sure it is
LinearLayout layout = (LinearLayout)holder.ItemView;
for (int i = 0; i < layout.ChildCount; i++)
{
var item = layout.GetChildAt(i);
if (item.GetType().ToString().Contains("Layout")) //check if child element is a layout view
{
ViewGroup group = (ViewGroup)item;
for (int j = 0; j < group.ChildCount; j++)
{
var nestedItem = group.GetChildAt(j);
string entryName = Context.Resources.GetResourceEntryName(nestedItem.Id);
if (entryName.Equals("title"))//we are looking for the TextView with id = "title"
{
//If we found it, store in TitleId member and return from the method
TitleId = nestedItem.Id;
return;
}
if (nestedItem.GetType().ToString().Contains("Layout"))
{
ViewGroup nestedGroup = (ViewGroup)nestedItem;
for (int k = 0; k < nestedGroup.ChildCount; k++)//3 levels should be enough and it actually never arrive here
{
var nestedNestedItem = nestedGroup.GetChildAt(k);
string nestedEntryName = Context.Resources.GetResourceEntryName(nestedNestedItem.Id);
if (entryName.Equals("title"))
{
TitleId = nestedNestedItem.Id;
return;
}
}
}
}
}
}
}
public override void OnBindViewHolder(PreferenceViewHolder holder)
{
base.OnBindViewHolder(holder);
//Check if we already have found it
if (!IsTitleFound)
{
//If not => find it!!
FindTitleId(holder);
//If for some reason it is not found, return from method
if (!IsTitleFound) return;
}
AppCompatTextView title = (AppCompatTextView)holder.FindViewById(TitleId);
if (title != null)
{
if (MChecked)//MChecked value is self-explanatory
{
title.Text = TextWhenOn;
}
else
{
title.Text = TextWhenOff;
}
}
}
}
}
Then you must declare the attributes in values/attrs.xml like this:
Resources/values/attrs.xml
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<declare-styleable name="CustomSwitchPreferenceWidget">
<attr name="textWhenOn" format="string"/>
<attr name="textWhenOff" format="string"/>
</declare-styleable>
</resources>
And now you can use them in your layout (in my case I use it in a preference file):
Resources/xml/preferences.axml
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:customAttrs="http://schemas.android.com/apk/res-auto2">
<!-- More items -->
<!-- ... -->
<KeepTravelling.Ui.CustomSwitchPreferenceWidget
android:defaultValue="true"
android:title="Start location service"
android:key="start_stop_option"
android:summary="If this option is turned off the service won't be running and thus you will not get new locations."
customAttrs:textWhenOn="Text when ON"
customAttrs:textWhenOff="Text when OFF">
</KeepTravelling.Ui.CustomSwitchPreferenceWidget>
</PreferenceScreen>
Note that you should declare the xml namespace you are using so it won't match with android's one. The URL doesn't need to exist, it only has to be any string that will be unique in the project.
And the result:

Feel free to ask any question.
EDIT: made the code generic so it can be used for any purpose.