Friday, April 13, 2018

Android ThemeLibrary

Hello visitors,

After a long gap, I bring a post for you.
I don't like to waste your time anymore.

Let's start-
Today, I will write about a new library. The Library is about for android theming and color plate.

First of all, see some screenshot-
sample11

So you can see that this library has an awesome theme list. You can use this list and with your own additional list. You can also remove this list and use your own theme list.
It has a built-in night mode icon that switches On and Off night mode. The biggest advantage of this library is If you don't like this option you can turn off by one line of code.
See another screenshot (here night mode is enabled)
nightmode

So you can see that this is highly customizable.
Enough intro lets get started-


Minimum API:
you need to set your minimum API 17 or later.

Now Installing:
Add below line build.gradle (project gradle file)
maven { url 'https://jitpack.io' }
now add this dependency to the build.gradle file
implementation 'com.github.Iamsdt:ThemeLibrary:2.0'
Installing is done.
Now time for configuration.

Configuration: 
Step1: 
Change your parent of app theme to LibraryAppTheme
Note: No need to add primary color, primary dark color, and accent color. it's already added in the LibraryAppTheme unless you want to update.
<!-- Base Theme -->
<style name="AppTheme" parent="LibraryAppTheme">
    .....
</style>
Step2: 
Update AndroidManifest.xml
android:theme="@style/AppTheme"
tools:replace="android:theme">
Step3: 
Start ColorActivity
startActivityForResult(ColorActivity.createIntent(this),121)
now override onActivityResult() method and recreate the activity
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == 121){
            if (resultCode == Activity.RESULT_OK) {
                recreate()
            }
        }
    }
That's it. It's done.
Hope it's work in your app.
If you want more customization then jump in customization section. Or, It's is ok then you have nothing to worry.

Customization 
This library is highly customizable...

Let's customize with your needs Change theme-

If you want to provide a custom theme list one.
Then create theme first. I am just showing a simple example how you can implement theme on style.XML
<style name="teal" parent="LibraryAppTheme.NoActionBar">
    <item name="colorPrimary">@color/teal_500</item>
    <item name="colorPrimaryDark">@color/teal_700</item>
    <item name="colorAccent">@color/blue_500</item>
    <item name="colorControlHighlight">@color/cyan_500</item>
</style>
Create your own list on the basis of this theme. Create a custom array list of MyTheme and fill the array with theme ids.
val list = ArrayList<MyTheme>()
list.add(MyTheme("Red",R.style.red))
call the method addMoreThemes() and pass this list
ColorActivity.addMoreThemes(getList())
startActivityForResult(ColorActivity.createIntent(this),121)
see the changes. your theme is on the list.

Ok, If you don't like the default theme list you can remove it simply
ColorActivity.addMoreThemes(list,false)
now you can see the theme list contain only your provided theme list

Customize title: 
Do you want to change the title? No problem. This option is also available
Let's see-
ColorActivity.updateToolbarTitle("Color")
want to provide a theme list and update the title- it is also possible
ColorActivity.addMoreThemes(list,"Color")
Want to provide a theme list with default false and also want to update the title-
ColorActivity.addMoreThemes(list,false,"Color")
you may notice there is night mode button available. If you want to turn off this option it is also possible.
let's change the code-
ColorActivity.hideNightModeIcon()

Issues:
some people report about an issue about PreferenceFragmentCompat that toolbar is not showing toolbar on setting activity.

I solve this issue, Let me alow to show the way.

First, see the solved screenshot-
fixed settings toolbar



You have to change the layout XML file-
In the XML file, you have to add a toolbar, like other activity.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
    tools:context="package.SettingsActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <fragment
        android:layout_marginTop="?attr/actionBarSize"
        android:id="@+id/settings_fragment"
        android:name="package.SettingsFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />


</android.support.design.widget.CoordinatorLayout>
this is the full XML change now on the Java code-
On the java code no big changes-
SettingsActivity.java
class SettingsActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        ThemeUtils.initialize(this)

        setContentView(R.layout.activity_settings)
        setSupportActionBar(toolbar)

        supportActionBar?.setDisplayHomeAsUpEnabled(true)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        if (item.itemId == android.R.id.home) {
            onBackPressed()
        }

        return super.onOptionsItemSelected(item)
    }

}
And Settings Fragment:
class SettingsFragment: PreferenceFragmentCompat(),
        SharedPreferences.OnSharedPreferenceChangeListener{

    override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
        // Add 'general' preferences, defined in the XML file
        addPreferencesFromResource(R.xml.pref_general)

        val sharedPreferences = preferenceScreen.sharedPreferences

        val count = preferenceScreen.preferenceCount

        (0 until count)
                .asSequence()
                .map { preferenceScreen.getPreference(it) }
                .forEach {
                    when (it) {
                        is CheckBoxPreference -> {
                            val value = sharedPreferences.getBoolean(it.key, false)
                            setPreferenceSummery(it, value)
                        }
                        else -> {
                            val value = sharedPreferences.getString(it.key, "")
                            setPreferenceSummery(it, value)
                        }
                    }
                }
    }

    override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {

        val preference = findPreference(key)

        if (preference != null) {

            if (preference !is CheckBoxPreference) {
                val value = sharedPreferences?.getString(preference.key, "") ?: ""
                setPreferenceSummery(preference, value)
            }
        }
    }

    private fun setPreferenceSummery(preference: Preference, value: Any) {

        val stringValue = value.toString()

        if (preference is ListPreference) {

            val prefIndex = preference.findIndexOfValue(stringValue)

            if (prefIndex >= 0) {
                preference.summary = preference.entries[prefIndex]
            }
        } else {
            // For other preferences, set the summary to the value's simple string representation.
            preference.summary = stringValue
        }
    }

    override fun onStart() {
        super.onStart()
        preferenceScreen.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
    }
}
Note: For this section only, I don't explain any code. For code explanation, you can check this post-Series Android Settings Series



This is an opensource library. check the GitHub
Check readme file

If you face any bug or any problem with this library let me know in the comment section.

This library is designed for saving time. Hope it can save you time.
Happy coding.

About Author:

I am Shudipto Trafder,
Since 2015, I write android code. I love to implement new ideas. I use java and also kotlin. Now I am learning Flutter. I love to learn new things and also love to share. And that is the main reason to run this blog.


Let's Get Connected: Facebook Twitter Linkedin Github

No comments :