Friday, April 13, 2018

Android ThemeLibrary

April 13, 2018

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-

Read More

Tuesday, November 14, 2017

Android Settings Series (part 2)

November 14, 2017

Welcome to this series post.
In this series post, we are going to create a complete Settings for a productive app.

We already published a post-
Now I am starting where I left in the previous post.

Now we need to create other 2 XML file. (In our final settings we need 3 XML file, we already have done one.)

Read More

Saturday, November 11, 2017

Android Settings Series (part 1)

November 11, 2017

Welcome to this Series post.
In this series post, we are going to create a complete Settings for a productive app.

Basic overview of our final settings?

Our final settings contains-
  •  multiple preference screen 
In a previous post, I  cover android settings with a single preference screen (Android App Settings with Preference Fragment Compat).

we create 3 screen that's are-
  • General
  • Backup 
  • Advance
So we create multiple preference screen in the same XML file and after user click, we replace the fragment.
That's the deal,
Lets Start-

Read More

Monday, May 15, 2017

Android App Settings with Preference Fragment Compat

May 15, 2017

In this post, we will make Android app settings with new Style.
We use PreferenceFragmentCompat.

Why Preference fragment compact? 
Because by using this we can show toolbar on settings activity easily.
Before starting to take a look at documentation click here.

So we need a separate fragment class. Settings is an activity just like others but we implement fragment here.
 Ok, that's our today goal.
Let's start.
Create an Activity name Settings Activity -

public class SettingsActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_settings);

  if (getSupportActionBar() != null) {
  getSupportActionBar().setDisplayHomeAsUpEnabled(true);
     }

  }

Now set it on Manifest.XML

<activity
  android:name=".settings.SettingActivity"
  android:label="@string/action_settings" />

Note: don't set-


android:parentActivityName=".MainActivity"

if you set this, after pressing the back arrow button on the toolbar it's launch MainActivity again. Now add dependencies to your build.gradle file

compile 'com.android.support:preference-v7:25.3.1'

After that Create a Fragment Class Name SettingFragment.java and extend it to PreferenceFragmentCompat and implements. SharedPreferences.OnSharedPreferenceChangeListener Let me Show-

public class SettingsFragment extends PreferenceFragmentCompat implements
  SharedPreferences.OnSharedPreferenceChangeListener{

  @Override
  public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
  
  }

  @Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

  }

Now add a method on this class name setPreferenceSummery. If we use ListPreference then we set to list selected value. for doing this, add this code-

private void setPreferenceSummery(Preference preference,Object value){

  String stringValue = value.toString();

  if (preference instanceof ListPreference){
  // For list preferences, look up the correct display value in
  // the preference's 'entries' list (since they have separate labels/values).
  ListPreference listPreference = (ListPreference) preference;
  int prefIndex = listPreference.findIndexOfValue(stringValue);
  //same code in one line
  //int prefIndex = ((ListPreference) preference).findIndexOfValue(value);

  //prefIndex must be is equal or garter than zero because
  //array count as 0 to ....
  if (prefIndex >= 0){
  listPreference.setSummary(listPreference.getEntries()[prefIndex]);
  }
  } else {
  // For other preferences, set the summary to the value's simple string representation.
  preference.setSummary(stringValue);
     }
 }

Note: For understanding code, you see comment on the code.

Now time the fulfill the methods onCreatePreferences.
In this methods, we add our XML file for settings option. But we don't create yet. So it's show error status. But don't worry we will add this later. Code-

@Override
  public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
  // Add 'general' preferences, defined in the XML file
  addPreferencesFromResource(R.xml.pref_general);

  SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences();

  PreferenceScreen preferenceScreen = getPreferenceScreen();

  int count = preferenceScreen.getPreferenceCount();

  for (int i = 0; i < count ; i++) {
  Preference p = preferenceScreen.getPreference(i);
  if (!(p instanceof CheckBoxPreference)) {
  String value = sharedPreferences.getString(p.getKey(), "");
  setPreferenceSummery(p, value);
       }
     }
  }

Now time to work with onSharedPreferenceChanged-

@Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

  Preference preference = findPreference(key);

  if (preference != null) {

  if (!(preference instanceof CheckBoxPreference)) {
  String value = sharedPreferences.getString(preference.getKey(), "");
  setPreferenceSummery(preference, value);
        }
     }
  }


Optional code: 
if you want to use the content provider to access database then you set a notification for change value-
Activity activity = getActivity();
activity.getContentResolver().notifyChange(CONTENT_URI, null);
After doing that we should register and unregister the shared preference listener with activity life cycle.

Let's do this-
//register and unregister on lifecycle
  @Override
  public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  getPreferenceScreen().getSharedPreferences()
  .registerOnSharedPreferenceChangeListener(this);
  }

  @Override
  public void onDestroy() {
  super.onDestroy();
  getPreferenceScreen().getSharedPreferences()
  .unregisterOnSharedPreferenceChangeListener(this);
  }


ok. our fragment is ready to use.(don't worry about the error, we will fix this letter, for now just ignore it.)
Now we add the toolbar back arrow code.
so that it's come back the previous activity. For more details use code comment-

@Override
    public boolean onOptionsItemSelected(MenuItem item) {

        /*
         * Normally, calling setDisplayHomeAsUpEnabled(true) 
         * (we do so in onCreate here) as well as
         * declaring the parent activity in the 
         * AndroidManifest is all that is required to get the
         * up button working properly. However, in this case, 
         * we want to navigate to the previous
         * screen the user came from when the up 
         * button was clicked, rather than a single
         * designated Activity in the Manifest.
         *
         * We use the up button's ID (android.R.id.home) 
         * to listen for when the up button is
         * clicked and then call onBackPressed 
         * to navigate to the previous Activity when this happens.
         */

        int id = item.getItemId();

        if (id == android.R.id.home){
            NavUtils.navigateUpFromSameTask(this);
        }

        return super.onOptionsItemSelected(item);
    }

Now in this part, we create XML code.

Are you tired of seeing the error? 
Now time to fix it. we create an XML file name pref_general.xml.
Let's add-
In our settings screen, we just add two preference,

  • List Preference,
  •  Checkbox preference. 

our list preference for text size. so we need to create two arrays on arrays.XML one is for label and others is for value. but we need to add string first (I provide all string for both preferences).

Strings-
<!-- for settings -->
  <!-- ***************START************* -->
  <!-- text size -->
  <string name="sTextSmallLabel">Small</string>
  <string name="sTextMediumLabel">Medium</string>
  <string name="sTextModerateLabel">Moderate</string>
  <string name="sTextLargeLabel">Large</string>
  <string name="sTextExtraLargeLabel">Extra Large</string>

  <!-- text size value-->
  <string name="sTextSmallValue">15</string>
  <string name="sTextMediumValue">17</string>
  <string name="sTextModerateValue">20</string>
  <string name="sTextLargeValue">23</string>
  <string name="sTextExtraLargeValue">26</string>

  <string name="textSizeKey" translatable="false">textSize</string>
  <string name="textSizeLabel">Text Size</string>

  <string name="switchKey">SwitchKey</string>
  <string name="switchLabel">Night Mode</string>
  <string name="switchON">Night Mode ON</string>
  <string name="switchOFF">Night Mode OFF</string>

  <!-- ***************FINISH************* -->

Now add arrays-

<resources>

  <string-array name="textSizeLabel">
  <item>@string/sTextSmallLabel</item>
  <item>@string/sTextMediumLabel</item>
  <item>@string/sTextModerateLabel</item>
  <item>@string/sTextLargeLabel</item>
  <item>@string/sTextExtraLargeLabel</item>
  </string-array>

  <string-array name="textSizeValue">
  <item>@string/sTextSmallValue</item>
  <item>@string/sTextMediumValue</item>
  <item>@string/sTextModerateValue</item>
  <item>@string/sTextLargeValue</item>
  <item>@string/sTextExtraLargeValue</item>
  </string-array>


</resources>

Note my full arrays.xml. Ok, that's enough waiting now add pref_general.xml


<PreferenceScreen
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="match_parent"
  android:layout_height="match_parent">

  <ListPreference
  android:defaultValue="@string/sTextModerateValue"
  android:entries="@array/textSizeLabel"
  android:entryValues="@array/textSizeValue"
  android:key="@string/textSizeKey"
  android:title="@string/textSizeLabel"/>

  <CheckBoxPreference
  android:defaultValue="false"
  android:key="@string/switchKey"
  android:summaryOff="@string/switchOFF"
  android:summaryOn="@string/switchON"
  android:title="@string/switchLabel"/>

</PreferenceScreen>

Just one more work to do left to complete Settings-
we need to update activity_settings. we need to set a fragment to on this XML file. Let's add this and this fragment will show our new settings in the settings.

<fragment
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/weather_settings_fragment"
    android:name="packageName.settings.SettingFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

Ok, that's . we finish our settings.

oh! I just forget to change the theme of styles.XML. Let's add on your main app theme.

<!-- Base application theme. -->
  <style name="AppTheme" parent="Theme.AppCompat.DayNight.DarkActionBar">
  <!-- must add this line or app will crash -->
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
  </style>

Note: if you don't add this line your app will crash. Be careful. Now you launch this SettingsActivity.java class with intent from your desired class.

See-
settings

It is single preference screen app. But If you want to add multiple screens, follow this post- Android Settings Series

That's all today.
Hope you can use this option for your app.

Happy coding

Read More