Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to consider variation while switching theme?

I'm Working on an android app that has a requirement to switch theme based on the themeCode given from server. I'm using sharePref to save the theme code and applying it with setTheme(R.style.themeName);. Its working fine till the basic theme attributes like

colorPrimary
colorPrimaryDark
colorAccent
windowActionBar
windowNoTitle

For this I has created different styles in styles.xml. But I have a limitation that some fields say EditText has variation as EditText

  • person name
  • email
  • phone
  • password etc.

And similarly TextView has variation as TextView

  • Heading
  • Single Line
  • Mutiline
  • Link etc.

Before multi-theme requirement I had created separate themes for all as

  • Apptheme.Edittext.email
  • Apptheme.Edittext.Password
  • Apptheme.Edittext.PersonName etc. And was applying to specific view in xml like

     style="@style/AppTheme.EditText.PersonName"  
    

Now I have viewed many tutorials/posts but did not find solution to the variations in attribute. Please help to apply these variation, I'll be thankful for this.

Regards: Inzimam Tariq

like image 213
Inzimam Tariq IT Avatar asked Nov 08 '22 10:11

Inzimam Tariq IT


1 Answers

In my opinion changing app theme at runtime, will definitely need to reload activity; this in most cases will create issues at some point (if project is extended to a mid scale, having a user control like toggle or a switch and if user taps switch repeatedly app may easily crash)


I would suggest to use custom control classes (Textviews, Buttons..etc); wherein this properties are differentiated with current theme value from sharedPref. This approach has a con; it will require to change all views manually of current screen and those in already rendered in memory(if any), rest all it will be much smoother transition in compare to our conventional approach

EDIT: Example for CustomTextView ##

This is an example for customtextview class

public class CustomTextView extends android.support.v7.widget.AppCompatTextView {
private static final String TAG = "TextView";
private Typeface tf = null;
private SharedPreferenceUtils preferenceUtils = SharedPreferenceUtils.getInstance();

/**
 * @param context:This is an abstract class whose implementation is provided by Android Operating System.
 * @param attrs:A      collection of attributes, as found associated with a tag in an XML document.
 * @param defStyle:
 */
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    if (preferenceUtils.getBooleanValue(PrefsKeyValue.bTheme)) {
        this.setTextColor(ResourceUtils.getColor(R.color.lightThemeTextColor));
    } else {
        this.setTextColor(ResourceUtils.getColor(R.color.colorWhite));
    }

    try {
        TypedArray a = context.obtainStyledAttributes(attrs,
                R.styleable.CustomEditText, defStyle, 0);

        String str = a.getString(R.styleable.CustomTextView_FontEnum);
        int original = a.getInt(R.styleable.CustomEditText_FontEnum, 0);
        CustomEnum.CustomFontType customEnumValue = CustomEnum.CustomFontType.fromId(a.getInt(R.styleable.CustomEditText_FontEnum, 0));
        a.recycle();
        switch (customEnumValue) {
            case BOLD:
                setTypeface(HelveticaNeueBold.getInstance(context).getTypeFace());
                break;

            case LIGHT:
                setTypeface(HelveticaNeueMedium.getInstance(context).getTypeFace());
                break;

            case REGULAR:
                setTypeface(HelveticaNeue.getInstance(context).getTypeFace());
                break;

            default:
                break;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

public CustomTextView(Context context, AttributeSet attrs) {
    this(context, attrs, 0);
}


public boolean setCustomFont(Context ctx, String asset) {

    try {
        tf = Typeface.createFromAsset(ctx.getAssets(), asset);
    } catch (Exception e) {
        LogUtils.LogE(TAG, "Could not get typeface: " + e.getMessage());
        return false;
    }

    setTypeface(tf);
    return true;
}}

Herein I have changed textcolor in accordance to theme value from sharedPref

 if (preferenceUtils.getBooleanValue(PrefsKeyValue.bTheme)) {
        this.setTextColor(ResourceUtils.getColor(R.color.lightThemeTextColor));
    } else {
        this.setTextColor(ResourceUtils.getColor(R.color.colorWhite));
    }

Then use this class as textview tag in xml file.

    <com.mypkg.customview.CustomTextView
    style="@style/signup_textViewStyle"
    android:text="@string/activity_login_password" />

I believe, you can handle property variation with theme for controls in same manner.

like image 69
Dhaval Patel Avatar answered Nov 15 '22 06:11

Dhaval Patel