Sunday, 16 August 2015

How to change the layout theme of an Android Application

What is Theme?

In any mobile, we have display settings, and the option to set the entire mobile theme such as light blue colour theme, red colour theme or any other colour. This will make the entire mobile functionality with this theme setting.
One needs to understand the style in Android so as to set the theme of an Android application.
Style is an XML file that resides in "project/res/values" directory and usually comprises of settings of appearances. The basic structure of "style.xml" is as below:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="nameOfTheTheme">
        <item name="android:attributeSets">value</item>
    </style>
</resources>
We can notice here that that in the style tag, there is one attribute named "name" which has the value. This value determines the "name of theme", for example, "MyTheme".
The next is an "item" tag that comprises of several attribute sets of views like "android:textColor", " android:textSize" etc. We need to specify this attribute and then write the value corresponding to it. Here is an example of a style.xml file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyTheme">
        <item name="android:textColor">#FF0000</item>
    </style>
</resources>
It can be observed clearly that the name of the style is "My Theme" and the item tag has the attribute "Text Colour” that possesses the value "#FF0000" which is the colour "Red".
The following code needs to be written before the setting of a layout file in "setContentView". This will set the theme while your activity is loading.
activity.setTheme(R.style.MyTheme);
setContentView(R.layout.main);
The application theme will be set before loading layout using the above code. Let us follow the below steps to create the application.

Step1

An Android project needs to be created and name it "ChangeTheme". Now, do a right-click on the project. Select "New -> Android XML File". The below dialog box will get open so that the name of the XML file can be given. Select Resource Type as "Values" and name of the file as "style.xml".
Indicates the New Android Project to be created
Figure 1:Indicates the New Android Project to be created
Add the below code on opening that file:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="FirstTheme" >
        <item name="android:textColor">#FF0000</item>
    </style>
    <style name="SecondTheme" >
        <item name="android:textColor">#00FF00</item>
    </style>
    <style name="Thirdheme" >
        <item name="android:textColor">#0000F0</item>
    </style>
</resources>
It can be seen that, we have created 3 styles namely "FirstThem", "SecondTheme" and "ThirdTheme" with the same attribute "Text Colour". However the colour values are different.

Step 2

Now open your "main.xml" layout file that is residing in "res/layout" directory.
The following code needs to be entered in so as to add 3 buttons and 1 label in it.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello C-Sharp"
 android:textAppearance="?android:attr/textAppearanceLarge" />
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="First Theme" />
    <Button
        android:id="@+id/button2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Second Theme" />
    <Button
        android:id="@+id/button3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Third Theme" />
</LinearLayout>
After the completion of this code, you need to go to "graphical" view and the following screen will be displayed.
Indicates the screen post navigating to Graphical view
Figure 2: Indicates the screen post navigating to Graphical view

Step3

Open your activity file which in this case is the "ChangeThemeActivity.java" file. This file is located in the "src/package" directory.
The buttons need to be bind and give “OnClickListener” so as to set the theme at runtime. Write the subsequent code in that file in order to do that.
Listing 1: ChangeThemeActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
public class ChangeThemeActivity extends Activity implements OnClickListener
{
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        Utils.onActivityCreateSetTheme(this);
        setContentView(R.layout.main);
          
                    findViewById(R.id.button1).setOnClickListener(this);
          findViewById(R.id.button2).setOnClickListener(this);
          findViewById(R.id.button3).setOnClickListener(this);
    }
     @Override
     public void onClick(View v) 
     {
          // TODO Auto-generated method stub
          switch (v.getId())
          {
          case R.id.button1:
          Utils.changeToTheme(this, Utils.THEME_DEFAULT);
          break;
          case R.id.button2:
          Utils.changeToTheme(this, Utils.THEME_WHITE);
          break;
          case R.id.button3:
          Utils.changeToTheme(this, Utils.THEME_BLUE);
          break;
          }
     }
}

Let us write the below code in the "Utils" file:
Listing 2: Utils.java
import android.app.Activity;
import android.content.Intent;
public class Utils
{
     private static int sTheme;
     public final static int THEME_DEFAULT = 0;
     public final static int THEME_WHITE = 1;
     public final static int THEME_BLUE = 2;
     /**
      * Set the theme of the Activity, and restart it by creating a new Activity of the same type.
      */
     public static void changeToTheme(Activity activity, int theme)
     {
          sTheme = theme;
          activity.finish();
activity.startActivity(new Intent(activity, activity.getClass()));
     }
     /** Set the theme of the activity, according to the configuration. */
     public static void onActivityCreateSetTheme(Activity activity)
     {
          switch (sTheme)
          {
          default:
          case THEME_DEFAULT:
              activity.setTheme(R.style.FirstTheme);
              break;
          case THEME_WHITE:
              activity.setTheme(R.style.SecondTheme);
              break;
          case THEME_BLUE:
              activity.setTheme(R.style.Thirdheme);
              break;
          }
     }
}

Description

  1. changeToTheme ( Activity activity, int theme )
  2. There are two arguments in this method, one is "Activity", that provides this method to identify the activity that has called this method and which theme to change. The other argument is “Theme" id. This is already declared in the beginning of the class and is written below:
    public final static int THEME_DEFAULT = 0;
    public final static int THEME_WHITE = 1;
    public final static int THEME_BLUE = 2;
    We declare three constants to identify each of them since we have 3 themes.
  3. onActivityCreateSetTheme ( Activity activity )
  4. The method holds the responsibility for setting the theme to the activity. After this, the method will verify which theme to set. It will identify the same by making use of a switch case and will call the "setTheme" method.

    Step 4

    We are prepared now to run the application. Before that, do have "AVD" (Android Virtual Device) added in your eclipse else go to "Window -> AVD Manager" and add a new AVD device to it.
    To begin with the execution, right-click on your "project" and select "Run As -> Android Application" thereby making your application run in the emulator.
    Both screens referring to the application executed in the emulator
    Both screens referring to the application executed in the emulator
    Figure 3: Both screens referring to the application executed in the emulator

    Conclusion

    The tutorial briefed about the process to create styles, to use it as a theme of an application and finally on the way to alter the theme of an application at the time of execution.

Thursday, 13 August 2015

finish activity when back button twice pressed? [duplicate]

1) Make a global vairable in your class like...
private boolean backPressedToExitOnce = false;
private Toast toast = null;
2) Then implement onBackPressed of activity like this...
@Override
public void onBackPressed() {
    if (backPressedToExitOnce) {
        super.onBackPressed();
    } else {
        this.backPressedToExitOnce = true;
        showToast("Press again to exit");
        new Handler().postDelayed(new Runnable() {

            @Override
            public void run() {
                backPressedToExitOnce = false;
            }
        }, 2000);
    }
}
3) Use this trick to handle this toast efficiantly...
/**
 * Created to make sure that you toast doesn't show miltiple times, if user pressed back
 * button more than once. 
 * @param message Message to show on toast.
 */
private void showToast(String message) {
    if (this.toast == null) {
        // Create toast if found null, it would he the case of first call only
        this.toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);

    } else if (this.toast.getView() == null) {
        // Toast not showing, so create new one
        this.toast = Toast.makeText(this, message, Toast.LENGTH_SHORT);

    } else {
        // Updating toast message is showing
        this.toast.setText(message);
    }

    // Showing toast finally
    this.toast.show();
}
4) And use this trick to hide toast when you activity is closed...
/**
 * Kill the toast if showing. Supposed to call from onPause() of activity.
 * So that toast also get removed as activity goes to background, to improve
 * better app experiance for user
 */
private void killToast() {
    if (this.toast != null) {
        this.toast.cancel();
    }
}
5) Implement you onPause() like that, to kill toast immidiatly as activity goes to background
@Override
protected void onPause() {
    killToast();
    super.onPause();
}

Monday, 20 July 2015

Android ActionBar Tab Color




For anyone wants to change actionbar color/background in code, you can do something like this
final ActionBar actionBar = getActionBar();
actionBar.setBackgroundDrawable(getResources().getDrawable(R.drawable.action_bar_bg));
To change the tab bar color under the actionbar:
actionBar.setStackedBackgroundDrawable(new ColorDrawable(getResources().getColor(R.color.color_brown_dark)));
To change tab bar background:
actionBar.setStackedBackgroundDrawable(getResources().getDrawable(
            R.drawable.coupon_header));


GridView with Auto Resized Images on Android





<?xml version="1.0" encoding="utf-8"?>
<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <GridView
        android:id="@+id/gridview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:verticalSpacing="0dp"
        android:horizontalSpacing="0dp"
        android:stretchMode="columnWidth"
        android:numColumns="2" />
</FrameLayout>
package com.rogcg.gridviewexample;

import android.content.Context;
import android.util.AttributeSet;
import android.widget.ImageView;

public class SquareImageView extends ImageView
{
    public SquareImageView(Context context)
    {
        super(context);
    }

    public SquareImageView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
    }

    public SquareImageView(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
    {
       Context context=getContext();
     
     WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
     Display display = wm.getDefaultDisplay();
     
     Point size = new Point();
     display.getSize(size);
     int width = size.x;
     int height = size.y-80;

        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        //setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
        if(Config.orientation==1)
        setMeasuredDimension(getMeasuredWidth(), height/3); //Snap to width
        else
         setMeasuredDimension(getMeasuredWidth(), height/2); //Snap to width   }
}
And now we make a layout for a grid item using this SquareImageView class and set the scaleType to centerCrop. Let's call this filegridview_item.xml.
<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <com.rogcg.gridviewexample.SquareImageView
        android:id="@+id/picture"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        />
    <TextView
        android:id="@+id/text"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:paddingLeft="10dp"
        android:paddingRight="10dp"
        android:paddingTop="15dp"
        android:paddingBottom="15dp"
        android:layout_gravity="bottom"
        android:textColor="@android:color/white"
        android:background="#55000000"
        />
</FrameLayout>
package com.mafiree;

import java.util.ArrayList;
import java.util.List;

import com.mafiree.source.Config;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.os.Bundle;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class DashBoard extends Activity{

 @Override
 protected void onCreate(Bundle savedInstanceState) {  
  super.onCreate(savedInstanceState);
  setContentView(R.layout.dash_board_demo);
  Config.orientation=getScreenOrientation();
   GridView gridView = (GridView)findViewById(R.id.gridview);
         gridView.setAdapter(new MyAdapter(this));
  //String[] name={"Current Health","Outstanding Issues","Architecture","Tickets","Backup","Activity"};
 }
 
  private class MyAdapter extends BaseAdapter
     {
         private List<Item> items = new ArrayList<Item>();
         private LayoutInflater inflater;

         public MyAdapter(Context context)
         {
             inflater = LayoutInflater.from(context);

             items.add(new Item("Current Health", R.drawable.test));
             items.add(new Item("Outstanding Issues", R.drawable.test));
             items.add(new Item("Architecture", R.drawable.test));
             items.add(new Item("Tickets", R.drawable.test));
             items.add(new Item("Backup", R.drawable.test));
             items.add(new Item("Activity", R.drawable.test));
         }

         @Override
         public int getCount() {
             return items.size();
         }

         @Override
         public Object getItem(int i)
         {
             return items.get(i);
         }

         @Override
         public long getItemId(int i)
         {
             return items.get(i).drawableId;
         }

         @SuppressLint("NewApi")
   @Override
         public View getView(int i, View view, ViewGroup viewGroup)
         {
             View v = view;
             ImageView picture;
             TextView name;

             if(v == null)
             {
                v = inflater.inflate(R.layout.gridview_item, viewGroup, false);
                v.setTag(R.id.picture, v.findViewById(R.id.picture));
                v.setTag(R.id.text, v.findViewById(R.id.text));
             }

             picture = (ImageView)v.getTag(R.id.picture);
             name = (TextView)v.getTag(R.id.text);

             Item item = (Item)getItem(i);

             Display display = getWindowManager().getDefaultDisplay();
             Point size = new Point();
             display.getSize(size);
             int width = size.x;
             int height = size.y;
             
             int orentation=getScreenOrientation();
             System.out.println("orientation: "+getScreenOrientation());
             // picture.getLayoutParams().height = 20;
             //  picture.requestLayout();
            DashBoard.this.getResources().getConfiguration();
             System.out.println();
             android.view.ViewGroup.LayoutParams layoutParams = picture.getLayoutParams();
             if(orentation==2){
             layoutParams.width = width/3;
             layoutParams.height = 50;
             picture.setLayoutParams(layoutParams);
             System.out.println("setting orientation");
             }else{
              System.out.println("nothing");
             }
             
             
             
             System.out.println("width :"+width);
             System.out.println("height :"+height);
             picture.setImageResource(item.drawableId);
             name.setText(item.name);

             
             picture.setId(i);
             picture.setOnClickListener(new OnClickListener() {
     
     @Override
     public void onClick(View v) {
      Toast.makeText(getApplicationContext(), "click-"+v.getId(), Toast.LENGTH_SHORT).show();
     }
    });
             
             return v;
         }

         private class Item
         {
             final String name;
             final int drawableId;

             Item(String name, int drawableId)
             {
                 this.name = name;
                 this.drawableId = drawableId;
             }
         }

  
     }
  
  
  public int getScreenOrientation()
  {
      Display getOrient = getWindowManager().getDefaultDisplay();
      int orientation = Configuration.ORIENTATION_UNDEFINED;
      if(getOrient.getWidth()==getOrient.getHeight()){
          orientation = Configuration.ORIENTATION_SQUARE;
      } else{ 
          if(getOrient.getWidth() < getOrient.getHeight()){
              orientation = Configuration.ORIENTATION_PORTRAIT;
          }else { 
               orientation = Configuration.ORIENTATION_LANDSCAPE;
          }
      }
      return orientation;
  }
 }