Thursday 23 June 2016

Designing Android Interface : Themes

Android provides various built in themes that can be applied by adding the :theme attibute to Activity together with name of Activity or to Application label in the manifest file.  Adding the theme attribute to the Activity only changes the theme for an Activity where as Adding to the Application changes theme to all those activities except the activities that has :theme attribute.

You can choose to use your own theme or the them in android:style libraries. Choosing the theme is a very difficult as we have to apply the theme each time and see it by running the app.

Let us make it Simple and Effective
The normal themes are:
1. @android:style/Theme.Dialog is the theme name that make the activity appear as a dialog box.
2. @android:style/Theme,Translucent is also a theme name that makes you activity transparent. The background is visible.
3.@:style/yourTheme is the theme that you have create in the and place in style.

So what is a Style in Android:
Style defines the look and format of the view or the window. It is composed of collection of properties like
1. Height
2. Padding
3. Font Color
4. Font Size
and more
Style once defined can be linked to other views so that you should not write the properties already described in style for in each view in layout file.

Okay thats a Syle, the what is Theme ?
The answer is simple, the theme is a other name of the style if it is applied to the whole activity and all its views. Style is also the xml file with the views name like <TextView and its properties. So all the text views in Activity will have the properties of <TextView defined in the style and their additional properties like hint.
Below is the example that will show how to create style and Apply to the specific view in layout file or to the whole Activity(ie such style is called Theme)

#Defining Style: A style is a xml file that contains a view like<TextView> and its properties. It may contain only one view or collection of views and their properties.The xml file should be placed inside res/values, Example:

Right Click in the directory res/values the style xml file then chose the filename for xml, then you get,
<?xml version="1.0" encoding="utf-8"?>
<resources></resources>
inside <resources> </resources> place the <style></style> and provide the name and parent of the style and other properties as follows.
<?xml version="1.0" encoding="utf-8"?><resources>
    <style name="myStyleEditText" parent="@style/TextAppearance.AppCompat.Title">
          <item name="android:layout_height">wrap_content</item>
        <item name="android:layout_width">match_parent</item>
        <item name="android:textColor">@android:color/holo_blue_light</item>
        <item name="android:typeface">serif</item>
        <item name="android:layout_marginLeft">10dp</item>
    </style>
</resources>
Here the name is required/must and parent is the style from which our style "myStlyeEditText" inherit the properties i.e parent="@style/TextAppearance.AppCompat.Title"or it may be also be parent="@style/TextAppearance.AppCompat.Light" or any other you like.

That's all, a style is created with a name "myStlyeEditText" . To use this style we will do something like this in the view like <TextView> in the layout file.
<EditText    android:id="@+id/editText"   
 android:hint="@string/search"    
  android:layout_marginLeft="10dp"   
 android:layout_marginRight="10dp"    
style="@style/myStyleEditText"     />
Here in the View ie <EditText> style attribute is added which is reference to the style  "myStyleEditText" which we made. We can even include <item name="android:layout_marginLeft">10dp</item> in the style and remove the android:layout_marginLeft="10dp" from<EditText> and so on for other properties like hint,layout_marginRight.

Further more this style that we made now can also be used as a parent as

<style name="myStyleEditText.Red">
    <item name="android:textColor">@android:color/holo_red_dark</item>
</style>

This style is same as "myStyleEditText" but overrides the @android:color/holo_red_dark to Red color.

#Defining Theme:
To apply the theme for whole application include in<Application together with label as
android:theme="Theme.AppCompat.Light.DarkActionBar">
Or parent="Theme.AppCompat.Light.NoActionBar"
Also you may use the your theme which is defined like
<style name="myTheme" parent="Theme.AppCompat.Light.DarkActionBar">
    <item name="android:windowBackground">@android:color/holo_blue_light</item>
    <item name="android:colorBackground">@android:color/black</item>
</style>
And use it as android:theme="@style/myTheme"> in the manifest file. for <Application> or<Activity>

That's all, you have created your theme which is inherited from parent theme.

More at: https://developer.android.com/guide/topics/ui/themes.html#DefiningStyles

Wednesday 22 June 2016

Android Handling Configuration Change to Update the Layouts for Different Orientation

There are generally two used methods to provide different layout for different orientation
First is to,

  1. Override the onConfigurationChanged() method and add setContentView(R.layout.layoutname) only if you have edited the manifest file and have added android:configChanges="orientation|screenSize" or android:configChanges="orientation" together with the android:name attribute of activity.
  2. If not then you can perform action to change layout in onCreate() method replacing setContentView(R.layout.layoutname);
  3. The technique is to find the current orientation (Portrait or Landscape) and then set the Content View with the Desired layout ,Example
    if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE){
        setContentView(R.layout.landscapeLayout);
    
    }
    else if(getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT) {
       setContentView(R.layout.portraitLayout);
    }
  4. Thus load the layout designed for Potrait or Lanscape by including the above code inside either onCreate() or in onConfigurationChanged() method.. IMPORTANT refer 1 and 2 to choose the method either onCreate() or onConfigurationChanged().
  5. IMPORTANT: Make sure that the layout xml file has different name for different orientations example R.layout.landscapeLayout and R.layout.portraitLayout layout names for Landscape and Portrait layout respectively

Second is to,

  1. Create a directory for Landscape and Portrait in the Layout folder inside res folder as
  2.  Create layout-land directory by right clicking on res folder and add paste the xml layout file for Landscape mode inside it, This file will be used in Landscape mode by android itself.
  3. The default path layout is for Portrait mode, and android use the file inside this for Portrait mode.
  4. IMPORTANT: Make sure that the layout xml file has same name in both directories layout-land and layout.
  5. That's all
More at:https://developer.android.com/training/basics/supporting-devices/screens.html

Android Handling Configuration Change

Configuration Changes may include one of these behaviors
  • Changes in Screen Orientation
  • Keyboard Availability Change
  • And the Change in Language
Normally the Configuration Changes results in the call of onDestroy() and onCreate() methods in a order.

To restore the state of the data of your application android call onSaveInstanceState() before onDestroy() and onRestoreInstanceState after onCreate(). It is simple, you can save the data in onSaveInstanceState() method and restore the same in onRestoreInstanceState() or onCreate() method.

 So, how do I handle my Configuration Changed?
 There are 2 methods normally used, First one is Simple method and Second is Compex. Simple is generally preferred if the data that need to be restored during configuration change is less where as Complex is preferred when required to restore large data as the use of simple methods will result lag in the USER Experience of USER INTERFACE.

Method : Simple Method
  • Above and on API 13 add following in Manifest file inside activity with activity Name 
    android:configChanges="orientation|screenSize"
  • Below API 13 add following in Manifest file inside activity with activity Name 
    
    android:configChanges="orientation"
  • And you are done. That's all.
  • If you need to perform some actions on configuration change then only Override the onConfigurationChanged() method of the Activity class inside your Class to perform additional action on Configuration Change but make sure you always call super.onConfigurationChanged();
  • Doing this, the Configuration change event will not call for onCreate() again and application data remains same.
Method : Complex Method
  • When the Configuration Changes and if the manifest file of activity doesn't include configchanges attribute unlike Simple Method above, then the android calls onSaveInstanceState in the event of Configuration Change unspecified in Manifect Activity.
  • Override the onSaveInstanceState() method and add the values to be saved. example
    protected void onSaveInstanceState(Bundle outState) {
         String myValue="SaveValue";
        outState.putStringArrayList("RECOVER", myValue);
         super.onsaveInstanceState();
    }
  • Then the android calls for onDestroy() method, on Create() and onRestoreInstanceState() in a order.
  • Override the onRestoreInstanceState() to recover the saved data in onSaveInstanceState() ,Example
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
    
      String myValue;     
    myValue= savedInstanceState.getStringArrayList("RECOVER"); super.onRestoreInstanceState(savedInstanceState); }
  • This recovers the String named myValue having the content "SaveValue". The keyName which is RECOVER should be unique as it carry the String named myValue(a variable).
More at: https://developer.android.com/guide/topics/resources/runtime-changes.html