Sunday, 29 September 2013

Android Hello World

This is the post for creating your first Android Hello World application.

Open eclipse, Right click to the project explorer window, select New-->>Others, the new wizard will be displayed like below



In new wizard select Android and expand the android option and select Android Application Project and then click Next button. The next screen will look like the below image



Application Name : Enter your application name. After entering your application name, the Project Name and the Package name will be inserted.

If you are entering Application name as "HelloWorld", then the project name will be same as your application and the package name will be displayed as "com.example.helloworld". You can change the Project name and the Package name as you like if you not go with the default values in the Project and Package name.

If you are installed latest android SDK, then the Minimum Required SDK, Target SDK, Compile With and Theme options are set by default.

Minimum Required SDK is the lowest version of Android that your app support.

Target SDK  Indicates the highest version of Android with which you have tested with your application.

Compile With is the platform version against which you will compile your app. By default, this is set to the latest Android version in your SDK.

Theme specifies the Android UI style to apply for your app.

Click Next button in wizard. The Project configure screen will be displayed.



In this screen, The check box "Create custom launcher icon" is selected. It is used to create the launcher icon of your application. You can choose your custom launcher icon for your app in next screen.

Create Activity check box is selected, used to create a Main activity of your application.

Click Next button in wizard. The Configure Launcher Icon screen will be displayed.



In this screen, you can choose your launcher icon by clicking the browse button. If no image will be selected, by default the android image will become the launcher icon for your application.

Click Next button in wizard, The Create Activity screen will be displayed.



In this screen you can choose your activity.

Blank Activity : Create a blank activity with contain header.
Full screen Activity : Create an activity without header.
Master/Detail Activity : Create an activity master on left and details on right of the screen. This activity used for tablets.

Click next button, The Blank Activity screen will be displayed.



In this screen, you should have to enter the followings.

Activity Name : Name of your Activity, By default it is MainActivity.
Layout Name : Name of your layout, By default it is activity_main. Layout name will be in lower case.
Navigation Type : None.

Click Finish button to close the wizard. After clicking the finish button, a new android project will be created in eclipse and below is the project structure of your application.



All your source code will go under the src directory. All layout will go under the layout folder. All images used in your app will go under drawable-hdpi for high density devices, drawable-ldpi for low density devices, drawable-mdpi for medium density devices, drawable-xhdpi for extra high density devices and drawable-xxhdpi for larger density devices.

All your string values will go under the strings.xml file under values folder.

For hello world application you dont need to code anything. Once you created an android project successfully, the hello world application is created by default.

Below is the code for MainActivity.java. It will coded by default.

package com.example.helloworld;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;

public class MainActivity extends Activity {

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


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }
    
}

Below is the code for activity_main.xml. It will coded by default.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</LinearLayout>

The text  android:text="@string/hello_world" will be refered from strings.xml file that are present under values directory.

Below is the code for strings.xml file. It will also coded by default.

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">HelloWorld</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>

</resources>

For each application an Android manifest xml file will be created (AndroidManifest.xml). Below is the code for AndroidManifest.xml file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.helloworld"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.helloworld.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>


Run the Android Application:

To run your android application, click the run configuration button in eclipse. the run configuration screen will be displayed like below.



Browse your project main program . Select "Launch Default Activity" radio button. Click Target tab in run configuration screen



In this screen, select the target device that you are going to run your application. Click Common tab in run configuration screen.



In this screen select the check box Run. Click Apply and Run button in Run configuration screen. your application will be launched in selected device. If device is an emulator, then your application will be launched in emulator.

The below is the result of Android Hello World Application.




Eclipse and Android Integration

This is the post for integrating Android to the eclipse. Following is the requirement for creating the hello world app.

1. Android Integration with eclipse
     To integrate android in eclipse, first download eclipse from eclipse.org/downloads/. After downloading eclipse launch the eclipse and goto Help-->>Install New Software.. The screen looks like below.



Click add button, the below image will be displayed.



Enter Name : Android
Location :  https://dl-ssl.google.com/android/eclipse/

and click OK. The available software for android will be displayed in available software window, like below



Select Developer Tools check box and click next button. The selected tools will be downloaded from the repository and integrated with eclipse. The download will may take three to four hours for slower net connection. After integration the android tool bar will be added to the eclipse like below. The three icons inside the rectangle is the android toolbar.


First icon is the Android SDK Manager.
Second icon is Android Virtual Device Manager.
Third icon is New Android XML File.

After integrating the Android ADT, you need to install the Android SDK. Click the Android SDK Manager icon to install SDK.



Note : I already installed "Tools", "Android4.3(API 18)" and "Android 4.3(API 17)". Hence the status displayed as "Installed". Otherwise the status will displayed as"Not Installed".

Select the latest android SDK (ie., Android4.3(API 18)) checkbox and click Install packages button. After clicking the Install packages button, you should have to accept the license to install the selected packages. After accepting the license the SDK downloading for selected packages will be started. The downloading will may take two to three hours for slower net connection.

After the successful completion of android SDK, you need to create Android Virtual Device(AVD). The AVD is used for running your application in emulator.

To create AVD, click the second icon in the android toolbar. The below screen will be displayed.



Click New button for creating the new AVD.



AVD Name : Enter name for AVD.
Device : Select device size of AVD.
Target : Select the target of AVD.
CPU/ABI : Select the CPU type to run the AVD and application.

The above mention details should need to enter for creating the new AVD. You can change the Internal storage details like RAM and VMHeap if your application required more than 512 MB of RAM..

Click OK to create the new AVD with above details.

You can create different AVD that suits for your application.

Tuesday, 10 January 2012

Creating Context Menu

For creating context menu in an activity, Create a folded called menu in the res folder, add a xml file in the res/menu folder. you can give any name to the xml file.

Below is the sample xml file for context menu in the res/menu folder.

<?xml version="1.0" encoding="utf-8"?>
<menu
  xmlns:android="http://schemas.android.com/apk/res/android">
  
    <item android:id="@+id/take_photo"
        android:title="Take New Photo ">
    </item>
   
    <item android:id="@+id/choose_gallery"
        android:title="Choose from Gallery">
    </item>
   
     <item android:id="@+id/share_cancel"
        android:title="Cancel">
    </item>
   
</menu>



Add as much of menu item by using the item tag. The item tag contain id for the menu and title for the menu.

For accessing the context menu, First register the context menu for any control. here i registered context menu for a button.

Button button01=(Button)findViewById(R.id.button01);
registerForContextMenu(button01);

The context menu will be displayed, on clicking the button01 button.

Add the following code in the activity for opening the context menu and perform some action from selected context menu option.

@Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
    {
       
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Post Image");
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.camer_menu, menu);
    }
   
    @Override
    public boolean onContextItemSelected(MenuItem item)
    {
      switch (item.getItemId())
      {
          case R.id.take_photo:
              Toast.makeText(context, "Selected Take Photo", Toast.LENGTH_SHORT).show();
              break;
         
          case R.id.choose_gallery:
                Toast.makeText(context, "Selected Gallery", Toast.LENGTH_SHORT).show();
                break;
       
          case R.id.share_cancel:
              closeContextMenu();
              break;
          default:
            return super.onContextItemSelected(item);
      }
      return true;
    }



Here i displayed Toast on selecting option from the context menu.

Below is the sample output.







Load image from camera or gallery

This post is to demonstrate how to load image from camera or from gallery.

It contain select and clear button at the title bar of the activity, and a text view will contain the title of the acticity.

On clicking select button, a context menu will be opened with three options called "Take New Photo", "Choose from Gallery" and "Cancel".

On Selecting Take New Photo option, the android camera intent will be called and camera view will be opened, the user can take photo, on clicking the capture button in the camera, the image will be stored in the folder of the sdcard, and the taken image will be loaded into the activity.

For accessing the camera hardware of the mobile, the following lines must to be add in the manifest file.

    <uses-permission android:name="android.permission.CAMERA" />
   
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />


For storing the image in the sdcard, you have to add the following permission in the manifest file.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

On Selecting Choose from Gallery option, the android gallery page will be opened, from the gallery you can select image, and the selected image will be added next to the main activity.

Below is the code for loading the image into the table layout with dynamic table row. You can take new picture and load in the table layout or you can select image from gallery and load in the table layout.

package cm.camera.table;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Gravity;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class LoadImage extends Activity
{
    Activity activity=null;
    Context context=null;
   
    Button header_left_btn=null;
    Button header_right_btn=null;
    TextView header_text=null;
    TableLayout image_table=null;
   
    ArrayList<String> image_list=new ArrayList<String>();
    ArrayList<Drawable> image_drawable=new ArrayList<Drawable>();
    String path="";
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.main);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.header);
       
        activity=LoadImage.this;
        context=LoadImage.this;
       
        header_left_btn=(Button)findViewById(R.id.header_left_btn);
        header_right_btn=(Button)findViewById(R.id.header_right_btn);
        header_text=(TextView)findViewById(R.id.header_text);
        image_table=(TableLayout)findViewById(R.id.image_table);
       
        header_text.setText("Image Table");
        header_left_btn.setText("Select");
        header_right_btn.setText("Clear");
        registerForContextMenu(header_left_btn);
       
        header_left_btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                openContextMenu(header_left_btn);
            }
        });
       
        header_right_btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                image_list.clear();
                image_drawable.clear();
                deletePhotos();
                updateImageTable();
            }
        });
    }
   
    public void deletePhotos()
    {
        String folder=Environment.getExternalStorageDirectory() +"/LoadImg";
        File f=new File(folder);
        if(f.isDirectory())
        {
            File[] files=f.listFiles();
            Log.v("Load Image", "Total Files To Delete=====>>>>>"+files.length);
            for(int i=0;i<files.length;i++)
            {
                String fpath=folder+File.separator+files[i].getName().toString().trim();
                System.out.println("File Full Path======>>>"+fpath);
                File nf=new File(fpath);
                if(nf.exists())
                {
                    nf.delete();
                }
            }
        }
    }
   
    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo)
    {
       
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.setHeaderTitle("Post Image");
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.camer_menu, menu);
    }
   
    @Override
    public boolean onContextItemSelected(MenuItem item)
    {
      switch (item.getItemId())
      {
          case R.id.take_photo:
              //Toast.makeText(context, "Selected Take Photo", Toast.LENGTH_SHORT).show();
              takePhoto();
              break;
         
          case R.id.choose_gallery:
              //Toast.makeText(context, "Selected Gallery", Toast.LENGTH_SHORT).show();
              Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
              photoPickerIntent.setType("image/*");
              startActivityForResult(photoPickerIntent, 1);
             
              break;
       
          case R.id.share_cancel:
              closeContextMenu();
              break;
          default:
            return super.onContextItemSelected(item);
      }
      return true;
    }
   
    public void takePhoto()
    {
         Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
         File folder = new File(Environment.getExternalStorageDirectory() + "/LoadImg");

         if(!folder.exists())
         {
             folder.mkdir();
         }        
         final Calendar c = Calendar.getInstance();
         String new_Date= c.get(Calendar.DAY_OF_MONTH)+"-"+((c.get(Calendar.MONTH))+1)   +"-"+c.get(Calendar.YEAR) +" " + c.get(Calendar.HOUR) + "-" + c.get(Calendar.MINUTE)+ "-"+ c.get(Calendar.SECOND);
         path=String.format(Environment.getExternalStorageDirectory() +"/LoadImg/%s.png","LoadImg("+new_Date+")");
         File photo = new File(path);
         intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(photo));
         startActivityForResult(intent, 2);
    }
   
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data)
    {
        super.onActivityResult(requestCode, resultCode, data);
       
        if(requestCode==1)
        {
            Uri photoUri = data.getData();
            if (photoUri != null)
            {
                String[] filePathColumn = {MediaStore.Images.Media.DATA};
                Cursor cursor = getContentResolver().query(photoUri, filePathColumn, null, null, null);
                cursor.moveToFirst();
                int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
                String filePath = cursor.getString(columnIndex);
                cursor.close();
                Log.v("Load Image", "Gallery File Path=====>>>"+filePath);
                image_list.add(filePath);
                Log.v("Load Image", "Image List Size=====>>>"+image_list.size());
               
                //updateImageTable();
                new GetImages().execute();
            }
        }
       
        if(requestCode==2)
        {
            Log.v("Load Image", "Camera File Path=====>>>"+path);
            image_list.add(path);
             Log.v("Load Image", "Image List Size=====>>>"+image_list.size());
            //updateImageTable();
             new GetImages().execute();
        }
    }
   
    public void updateImageTable()
    {
        image_table.removeAllViews();
       
        if(image_drawable.size() > 0)
        {
            for(int i=0; i<image_drawable.size(); i++)
            {
                TableRow tableRow=new TableRow(this);
                tableRow.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
                tableRow.setGravity(Gravity.CENTER_HORIZONTAL);
                tableRow.setPadding(5, 5, 5, 5);
                for(int j=0; j<1; j++)
                {
                    ImageView image=new ImageView(this);
                    image.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
                   
                    /*Bitmap bitmap = BitmapFactory.decodeFile(image_list.get(i).toString().trim());
                    bitmap = Bitmap.createScaledBitmap(bitmap,500, 500, true);
                    Drawable d=loadImagefromurl(bitmap);*/
                    image.setBackgroundDrawable(image_drawable.get(i));
                   
                    tableRow.addView(image, 200, 200);
                }
                image_table.addView(tableRow);
            }
        }
    }
   
    public Drawable loadImagefromurl(Bitmap icon)
    {
        Drawable d=new BitmapDrawable(icon);       
        return d;
    }
   
    public class GetImages extends AsyncTask<Void, Void, Void>
    {
        public ProgressDialog progDialog=null;
       
        protected void onPreExecute()
        {
            progDialog=ProgressDialog.show(context, "", "Loading...",true);
        }
        @Override
        protected Void doInBackground(Void... params)
        {
            image_drawable.clear();
            for(int i=0; i<image_list.size(); i++)
            {
                Bitmap bitmap = BitmapFactory.decodeFile(image_list.get(i).toString().trim());
                bitmap = Bitmap.createScaledBitmap(bitmap,500, 500, true);
                Drawable d=loadImagefromurl(bitmap);
               
                image_drawable.add(d);
            }
            return null;
        }   
           
        protected void onPostExecute(Void result)
        {
            if(progDialog.isShowing())
            {
                progDialog.dismiss();
            }
            updateImageTable();
        }
    }
}

Below is the layout, that are used for loading the image. The name of the layout called main.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="#BFD6E8">
   
    <ScrollView android:id="@+id/image_scroll"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
       
        <TableLayout android:id="@+id/image_table"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
        </TableLayout>
       
    </ScrollView>

</LinearLayout>


I added the Custom title bar in the activity. For creating custom title bar, please Refer the link below.

http://tjkannan.blogspot.com/2012/01/custom-title-bar.html

Below is the sample output screens.
































Custom Title Bar

For creating custom Title bar in android, For that Add styles.xml in the res/values folder.

The styles.xml file contains the following code.

<?xml version="1.0" encoding="UTF-8"?>
<resources>

    <style name="WindowTitleBackground" >   
        <item name="android:background">@android:color/transparent</item>       
    </style>
   
</resources>


Create colors.xml file in the res/values folder. Add colors that are needed for the application.

The colors.xml file contains the following code.

<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="orange">#ff5500</color>
<color name="white">#ffffff</color>
<color name="transparent">#00000000</color>
<color name="date_color">#999999</color>
<color name="black">#000000</color>
<color name="gray">#999999</color>
<color name="blue">#0066cc</color>
<color name="gold">#e6b121</color>
<color name="blueback">#99FFFF</color>
 <color name="articlecolor">#3399FF</color>
 <color name="article_title">#3399FF</color>
<color name="cachecolor">#8ad0e8</color>
<color name="red">#FF0000</color>
<color name="pink">#FF00FF</color>
<color name="green">#00FF00</color>
<color name="mycolor">#FF9900</color>
</resources>


Add themes.xml file in the res/values folder.
themes.xml file contains the following code.

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="MyTheme" parent="android:Theme">
        <item name="android:windowTitleSize">60px</item>
        <item name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item>         
       
    </style>
</resources>


The created style will be added into the theme file.
After creating these files open android manifest file and apply the theme into the whole application or an activity.

manifest file code

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="cm.camera.table"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />
   
        <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".LoadImage" android:label="@string/app_name" android:screenOrientation="portrait" android:theme="@style/MyTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>
</manifest>


The yellow highlighted code is the code for applying the created theme for an activity.

Create a layout for the custom title bar, the layout contain any android controls.

The below layout cobe is the sample layout for the custom title bar.

<?xml version="1.0" encoding="UTF-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="60px"
    android:layout_gravity="fill_horizontal"
    android:layout_width="fill_parent"
    android:background="#095C9B"
    android:orientation="horizontal">

        <Button  android:id="@+id/header_left_btn"
            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="5dp"
             android:layout_centerVertical="true"
             android:text=" Back"
             android:textColor="#000000"/>
       

        <TextView android:id="@+id/header_text"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_toRightOf="@+id/header_left_btn"
            android:layout_toLeftOf="@+id/header_right_btn"
            android:text="Header Text"
            android:textSize="20sp"
            android:textStyle="bold"
            android:textColor="#FFFFFF"
            android:gravity="center"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"
            android:singleLine="true" />
           
        <Button  android:id="@+id/header_right_btn"
            android:layout_width="wrap_content"
             android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="5dp"
             android:layout_centerVertical="true"
             android:text=" Share"  
             android:textColor="#000000"/>
       
</RelativeLayout>


I used two buttons and one text view in the layout.

Add the following lines in the on create method.

        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.header);


The onCreate method in the activity will look like the below.

@Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
        setContentView(R.layout.main);
        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,R.layout.header);
    }


The yellow Highlighted line replaces the default title bar to the custom title bar.

Run the application, you will get the output like below.


Number Puzzle

The Below program is the Splash Screen, After finishing the splash screen activity, the options page will be displayed.


package com.dynamic.layout;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;

public class Splash_Screen extends Activity
{
    public static final String PREFS_NAME = "ScorePrefs";
    static SharedPreferences settings;
    SharedPreferences.Editor editor;
   
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);
       
        new CountDownTimer(5000,1000){

            @Override
            public void onFinish()
            {
                // TODO Auto-generated method stub
                finish();
                Intent ingridmenu=new Intent(Splash_Screen.this,OptionLayout.class);
                startActivity(ingridmenu);
            }

            @Override
            public void onTick(long millisUntilFinished)
            {
                Log.d("Timer Coundown", Long.toString(millisUntilFinished));
                // TODO Auto-generated method stub
               
            }
           
        }.start();
    }
}


The Below Program is the Option page Activity.

package com.dynamic.layout;

import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class OptionLayout extends Activity
{
    DBRecordHandler recHandler=null;
   
    Button start_btn=null;
    Button scores_btn=null;
    Button exit_btn=null;
   
    static int screenWidth=0,screenHeight=0;
   
    public static ArrayList<MoveListValues> scoreList=new ArrayList<MoveListValues>();
   
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.options_layout);
       
        Display display = getWindowManager().getDefaultDisplay();
        screenWidth = display.getWidth();
        screenHeight = display.getHeight();
        Log.d("screenWidth",Integer.toString(screenWidth));
        Log.d("Screen Height",Integer.toString(screenHeight));
       
        start_btn=(Button)findViewById(R.id.start_btn);
        scores_btn=(Button)findViewById(R.id.scores_btn);
        exit_btn=(Button) findViewById(R.id.exit_btn);
       
        getScoreRecords();
       
        start_btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Intent instart=new Intent(OptionLayout.this, DynamicLayout.class);
                startActivity(instart);
            }
           
        });
       
        scores_btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                Intent inscore=new Intent(OptionLayout.this, ScoreList.class);
                startActivity(inscore);
            }
           
        });
       
        exit_btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                finish();
            }
           
        });
    }
   
    public void getScoreRecords()
    {
        scoreList.clear();
       
        recHandler=new DBRecordHandler(OptionLayout.this);
        recHandler.open();
       
        Cursor cur=recHandler.getAllUser();
        startManagingCursor(cur);
        cur.moveToFirst();
        if(cur.getCount()>0)
        {
            while(cur.isAfterLast()==false)
            {   
                //Log.v("OptionLayout", "Name========>>>"+cur.getString(cur.getColumnIndex(DBRecordHandler.USERNAME)));
                //Log.v("OptionLayout", "Moves========>>>"+cur.getString(cur.getColumnIndex(DBRecordHandler.MOVES)));
                //Log.v("OptionLayout", "Time========>>>"+cur.getString(cur.getColumnIndex(DBRecordHandler.TIME)));
               
                String name=cur.getString(cur.getColumnIndex(DBRecordHandler.USERNAME));
                String moves=cur.getString(cur.getColumnIndex(DBRecordHandler.MOVES));
                String time=cur.getString(cur.getColumnIndex(DBRecordHandler.TIME));
               
                scoreList.add(new MoveListValues(name, moves, time));
               
                cur.moveToNext();
            }
        }
       
        else
        {
            Toast.makeText(OptionLayout.this, "No Scores Details", Toast.LENGTH_SHORT).show();
        }
        recHandler.close();
    }
   
    public void onResume()
    {
        super.onResume();
        Log.v("OptionLayout", "=========== Calling OnResume ============");
        getScoreRecords();
    }
}

Below is the Layout that are used in the Option activity.

<?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"
  android:gravity="center"
  android:background="#112C4F">
 
  <Button android:id="@+id/start_btn"
      android:layout_width="fill_parent"
      android:layout_height="50dp"
      android:layout_marginLeft="20dp"
      android:layout_marginRight="20dp"
      android:text="Start"
      android:textColor="#FFFFFF"
      android:textStyle="bold"
      android:textSize="18sp"
      android:background="@drawable/shuffle_button_selector">
  </Button>
 
   <Button android:id="@+id/scores_btn"
      android:layout_width="fill_parent"
      android:layout_height="50dp"
      android:layout_marginLeft="20dp"
      android:layout_marginRight="20dp"
      android:layout_marginTop="10dp"
      android:text="Scores"
      android:textColor="#FFFFFF"
      android:textStyle="bold"
      android:textSize="18sp"
      android:background="@drawable/shuffle_button_selector">
  </Button>
 
   <Button android:id="@+id/exit_btn"
      android:layout_width="fill_parent"
      android:layout_height="50dp"
      android:layout_marginLeft="20dp"
      android:layout_marginRight="20dp"
      android:layout_marginTop="10dp"
      android:text="Exit"
      android:textColor="#FFFFFF"
      android:textStyle="bold"
      android:textSize="18sp"
      android:background="@drawable/shuffle_button_selector">
  </Button>
 
</LinearLayout>


Three buttons are used in the option page, first one is start to start the puzzle, second is scores to list the highscores in the puzzle and third one is exit to close the application.


OnClicking the start button, the puzzle activity will be started.

Below is the program for creating the view of the puzzle.

package com.dynamic.layout;

import java.util.ArrayList;
import java.util.Collections;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.Chronometer;
import android.widget.EditText;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Chronometer.OnChronometerTickListener;

public class DynamicLayout extends Activity implements OnClickListener
{
    public static final int LEFT_MOVE=1;
    public static final int RIGHT_MOVE=2;
    public static final int TOP_MOVE=3;
    public static final int BOTTOM_MOVE=4;
   
    TableLayout tableLayout=null;
    Button shuffle_btn=null;
    TextView moves=null;
    TextView least_moves=null;
    Chronometer time_count=null;
   
    DBRecordHandler recHandler=null;
   
    int value=0, move_count=0;
    String currentTime;
    long elapsedTime = 0;
   
    public ArrayList<String> numbers=new ArrayList<String>();
    public ArrayList<String> real_numbers=new ArrayList<String>();
    public String[][] num_array=new String[4][4];
    ArrayList<MoveListValues> nearest_list=new ArrayList<MoveListValues>();
   
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
       
        tableLayout=(TableLayout)findViewById(R.id.table_layout);
        shuffle_btn=(Button)findViewById(R.id.shuffle_btn);
        moves=(TextView)findViewById(R.id.moves_count);
        least_moves=(TextView)findViewById(R.id.least_moves);
        time_count=(Chronometer)findViewById(R.id.timer_count);
       
        try
        {
            if(OptionLayout.scoreList.size()<1)
            {
                least_moves.setText("Least Move : 0");
            }
           
            else
            {
                least_moves.setText("Least Move : "+OptionLayout.scoreList.get(0).moves.trim());
            }
        }
        catch(Exception e)
        {
           
        }
       
       
       
        for(int i=1; i<16; i++)
        {
            real_numbers.add(Integer.toString(i));
        }
        real_numbers.add("");
       
        storeNumberList();
        shuffle();
       
        //time_count.start();
       
        shuffle_btn.setOnClickListener(new OnClickListener(){

            @Override
            public void onClick(View v)
            {
                // TODO Auto-generated method stub
                storeNumberList();
                shuffle();
            }
        });
       
        time_count.setOnChronometerTickListener(new OnChronometerTickListener(){

            @Override
            public void onChronometerTick(Chronometer chronometer)
            {
                // TODO Auto-generated method stub
                long minutes = ((SystemClock.elapsedRealtime() - time_count.getBase()) / 1000) / 60;
                long seconds = ((SystemClock.elapsedRealtime() - time_count.getBase()) / 1000) % 60;
               
                String min=Long.toString(minutes);
                String sec=Long.toString(seconds);
               
                if(sec.length()<2)
                {
                    sec="0"+sec;
                }
                currentTime = min + ":" + sec;
                //Log.v("DynamicLayout", "Current Time=====>>>"+currentTime);
               
                chronometer.setText("Time : "+currentTime);
                //elapsedTime = SystemClock.elapsedRealtime();
            }
           
        });
    }
   
    public void storeNumberList()
    {
        numbers.clear();
        for(int i=1; i<16; i++)
        {
            numbers.add(Integer.toString(i));
        }
        numbers.add("");
    }
   
    public void shuffle()
    {
        //Collections.shuffle(numbers);
       
        move_count=0;
        moves.setText("Moves = "+move_count);
       
        time_count.setBase(SystemClock.elapsedRealtime());
        time_count.start();
       
        displayShuffledRows();
    }

    public void displayShuffledRows()
    {
        // TODO Auto-generated method stub
        tableLayout.removeAllViews();
        value=0;
        int ei=-1,ej=-1;
       
        for(int i=0; i<4; i++)
        {
            TableRow tableRow=new TableRow(this);
            tableRow.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            tableRow.setGravity(Gravity.CENTER_HORIZONTAL);
            for(int j=0; j<4; j++)
            {
                Button button=new Button(this);
               
                button.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
               
                num_array[i][j]=numbers.get(value);
               
                if(numbers.get(value).equals(""))
                {
                    ei=i;
                    ej=j;
                }
               
                button.setText(""+numbers.get(value));
                button.setTextSize(25.0f);
                button.setBackgroundResource(R.drawable.number_buttons_selector);
                button.setTextColor(Color.WHITE);
                button.setOnClickListener(this);
               
                value++;
               
                if(OptionLayout.screenWidth==540)
                {
                    tableRow.addView(button,120,120);
                }
                else
                {
                    tableRow.addView(button,60,60);
                }
               
               
            }
           
            tableLayout.addView(tableRow);
        }
       
        getNearestValues(ei,ej);
    }
   
    public void getNearestValues(int i, int j)
    {
        nearest_list.clear();
       
        //Log.v("Dynamic Layout", "Empty Position=============>>>"+i+","+j);
       
        if(i==0 && j==0)
        {
            nearest_list.add(new MoveListValues(num_array[i][j+1], RIGHT_MOVE, i, j+1, i, j));
            nearest_list.add(new MoveListValues(num_array[i+1][j], BOTTOM_MOVE, i+1, j, i, j));
        }
        else if(i==0 && (j==1 || j==2))
        {
            nearest_list.add(new MoveListValues(num_array[i][j-1], LEFT_MOVE, i, j-1, i, j));
            nearest_list.add(new MoveListValues(num_array[i][j+1], RIGHT_MOVE, i, j+1, i, j));           
            nearest_list.add(new MoveListValues(num_array[i+1][j], BOTTOM_MOVE, i+1, j, i, j));
        }       
        else if(i==0 && j==3)
        {
            nearest_list.add(new MoveListValues(num_array[i][j-1], LEFT_MOVE, i, j-1, i, j));
            nearest_list.add(new MoveListValues(num_array[i+1][j], BOTTOM_MOVE, i+1, j, i, j));
        }       
        else if((i==1 || i==2) && j==0)
        {
            nearest_list.add(new MoveListValues(num_array[i][j+1], RIGHT_MOVE, i, j+1, i, j));
            nearest_list.add(new MoveListValues(num_array[i-1][j], TOP_MOVE, i-1, j, i, j));
            nearest_list.add(new MoveListValues(num_array[i+1][j], BOTTOM_MOVE, i+1, j, i, j));
        }
        else if((i==1 || i==2) && (j==1 || j==2))
        {
            nearest_list.add(new MoveListValues(num_array[i][j-1], LEFT_MOVE, i, j-1, i, j));
            nearest_list.add(new MoveListValues(num_array[i][j+1], RIGHT_MOVE, i, j+1, i, j));
            nearest_list.add(new MoveListValues(num_array[i-1][j], TOP_MOVE, i-1, j, i, j));
            nearest_list.add(new MoveListValues(num_array[i+1][j], BOTTOM_MOVE, i+1, j, i, j));
        }       
        else if((i==1 || i==2) && j==3)
        {
            nearest_list.add(new MoveListValues(num_array[i][j-1], LEFT_MOVE, i, j-1, i, j));
            nearest_list.add(new MoveListValues(num_array[i-1][j], TOP_MOVE, i-1, j, i, j));
            nearest_list.add(new MoveListValues(num_array[i+1][j], BOTTOM_MOVE, i+1, j, i, j));
        }       
        else if(i==3 && j==0)
        {
            nearest_list.add(new MoveListValues(num_array[i][j+1], RIGHT_MOVE, i, j+1, i, j));
            nearest_list.add(new MoveListValues(num_array[i-1][j], TOP_MOVE, i-1, j, i, j));
        }
        else if(i==3 && (j==1 || j==2))
        {
            nearest_list.add(new MoveListValues(num_array[i][j-1], LEFT_MOVE, i, j-1, i, j));
            nearest_list.add(new MoveListValues(num_array[i][j+1], RIGHT_MOVE, i, j+1, i, j));
            nearest_list.add(new MoveListValues(num_array[i-1][j], TOP_MOVE, i-1, j, i, j));
        }       
        else if(i==3 && j==3)
        {
            nearest_list.add(new MoveListValues(num_array[i][j-1], LEFT_MOVE, i, j-1, i, j));
            nearest_list.add(new MoveListValues(num_array[i-1][j], TOP_MOVE, i-1, j, i, j));
        }
        else
        {
            Toast.makeText(DynamicLayout.this, "I and J value are Negative", Toast.LENGTH_SHORT).show();
        }   
    }

    @Override
    public void onClick(View v)
    {
        // TODO Auto-generated method stub
        String text=((Button) v).getText().toString();
       
        numbers.clear();
       
        for(int i=0; i<nearest_list.size(); i++)
        {
            if(text.equalsIgnoreCase(nearest_list.get(i).number.trim()))
            {
                move_count++;
                //Log.v("DynamicLayout", "Direction==========>>>"+nearest_list.get(i).direction);
                int empty_i=nearest_list.get(i).empty_i;
                int empty_j=nearest_list.get(i).empty_j;
               
                int move_i=nearest_list.get(i).move_i;
                int move_j=nearest_list.get(i).move_j;
               
                String temp=num_array[move_i][move_j];
                num_array[move_i][move_j]="";
                num_array[empty_i][empty_j]=temp;
            }
        }
       
        for(int i=0; i<4; i++)
        {
            for(int j=0; j<4; j++)
            {
                //Log.v("Printing Num Array", "After Values======("+i+","+j+")=========>>>"+num_array[i][j]);
                numbers.add(num_array[i][j]);
            }
        }
        moves.setText("Moves = "+move_count);
        displayShuffledRows();
        int i=0;
        comparition(i);
    }
   
    public void comparition(int i)
    {
        if(i<real_numbers.size())
        {
            //System.out.println("List 1 value=====>>>"+real_numbers.get(i) + " List 2 Value=====>>>"+numbers.get(i));
            if(real_numbers.get(i).equals(numbers.get(i)))
            {
                //System.out.println("Comparition Progress.....");
                i++;
                if(i==real_numbers.size())
                {
                    //System.out.println("Solution Obtained.....");
                    time_count.stop();
                    showAlert(DynamicLayout.this, "Solution Obtained in "+move_count+" Moves and Time is "+currentTime);
                }
                else
                {
                    comparition(i);
                }
            }
            else
            {
                //System.out.println("Solution Not Obtained.....");
            }
        }
    }
   
    public void insertRecord(String name)
    {
        recHandler=new DBRecordHandler(DynamicLayout.this);
        recHandler.open();
        long res=recHandler.insertRecord(name, move_count, currentTime);
        Log.v("Record Inserted========>>>", Long.toString(res));
        recHandler.close();
    }
   
    public void showAlert(Context context, String desc)
    {
       
        final AlertDialog alert=new AlertDialog.Builder(context).create();

        alert.setTitle("Congratulation");
        alert.setMessage(desc);
        alert.setIcon(R.drawable.smile_emotion);

        // Set an EditText view to get user input
        final EditText input = new EditText(this);
        input.setHint("Name");
        alert.setView(input);

        alert.setButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton)
            {
              String value = input.getText().toString();
              insertRecord(value);
              shuffle();
              alert.dismiss();
            }
        });


        alert.show();
    }
}


Below is the layout that are used in the puzzle view. Layout name is main.xml.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center"
    android:background="#112C4F">
   
    <RelativeLayout android:id="@+id/timer_count_rellayout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content">
       
        <TextView android:id="@+id/least_moves"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:layout_marginBottom="5dp"
            android:text="Least Moves"
            android:textStyle="bold"
            android:textSize="15sp"
            android:textColor="#FFFFFF">
        </TextView>
       
        <Chronometer android:id="@+id/timer_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@+id/least_moves"
            android:format="0:00"   
            android:textColor="#FFFFFF"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp">
        </Chronometer>
       
        <TextView android:id="@+id/moves_count"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="10dp"
            android:layout_below="@+id/least_moves"
            android:text="Moves"
            android:textStyle="bold"
            android:textSize="15sp"
            android:textColor="#FFFFFF">
        </TextView>
       
    </RelativeLayout>
   
   
   
    <TableLayout android:id="@+id/table_layout"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:gravity="center">
    </TableLayout>
   
    <Button android:id="@+id/shuffle_btn"
        android:layout_width="100dp"
        android:layout_height="50dp"
        android:layout_marginTop="10dp"
        android:background="@drawable/shuffle_button_selector"
        android:text="Shuffle"
        android:textColor="#FFFFFF">
    </Button>

</LinearLayout>


Text view for Displaying the least moves.
Chronometer for running the time.
Text view for Displaying the moves count.
Table Layout for displaying the puzzle numbers.
Button for suffle the puzzle numbers.

OnClicking the suffle button, the puzzle will be restarted, timer will also be restarted.

Sqlite database will be used for maintaining the scores details.

The following two class is used for creating the database and managing records in the database

package com.dynamic.layout;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.util.Log;

public class DataBaseHandler extends SQLiteOpenHelper
{
   
    public static String DataBase_Create="create table movecountdb(_id integer primary key autoincrement,"
        +"username text not null, moves integer not null, time text not null);";

    public DataBaseHandler(Context context, String name, CursorFactory factory,int version)
    {
        super(context, name, null, version);
        // TODO Auto-generated constructor stub
    }

    @Override
    public void onCreate(SQLiteDatabase db)
    {
        // TODO Auto-generated method stub
        System.out.println("******** Table Created ***********");
        db.execSQL(DataBase_Create);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
    {
        // TODO Auto-generated method stub
        Log.w(DataBaseHandler.class.getName(), "Upgraded Database From "+oldVersion+" to "+newVersion+" Which Will Destroy All old Data");
        db.execSQL("Drop table if exist userdetails");
        onCreate(db);
    }

}


For Managing Records, the following class is used.

package com.dynamic.layout;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class DBRecordHandler
{
    public static String USERNAME="username";
    public static String MOVES="moves";
    public static String TIME="time";
    public static String ROW_ID="_id";
   
    public SQLiteDatabase database;
    public DataBaseHandler dbhandler;
   
    public static String DataBase_Name="movesdetails";
    public static int Database_version=2;
    public static String Table_Name="movecountdb";
    public Context context=null;
   
    public DBRecordHandler(Context context)
    {
        this.context=context;
        dbhandler=new DataBaseHandler(context,DataBase_Name,null,Database_version);
        database=dbhandler.getWritableDatabase();             
    }
   
    public DBRecordHandler open()
    {
        dbhandler=new DataBaseHandler(context,DataBase_Name,null,Database_version);
        database=dbhandler.getWritableDatabase(); 
        return this;
    }
   
    public void close()
    {
        dbhandler.close();
    }
   
    public long insertRecord(String username,int moves,String time)
    {
        ContentValues conval=addDetails(username, moves, time);
        long res=database.insert(Table_Name, null, conval);
        return res;
    }
   
    /*public int updateRecord(long row_id, String username, String password, String email)
    {
        ContentValues updateValues=addDetails(username, password, email);
        int res=database.update(Table_Name, updateValues, ROW_ID+"="+row_id, null);
        return res;
    }
   
    public int deleteRecord(long row_id)
    {
        int res=database.delete(Table_Name, ROW_ID+"="+row_id, null);
        return res;
    }*/
   
    public ContentValues addDetails(String username, int moves, String time)
    {
        Log.v("Record Handler", "username==========>>>"+username);
        Log.v("Record Handler", "Moves==========>>>"+moves);
        Log.v("Record Handler", "Time==========>>>"+time);
       
        ContentValues values=new ContentValues();
        values.put(USERNAME, username);
        values.put(MOVES, moves);
        values.put(TIME, time);
        return values;
    }
   
    public Cursor getAllUser()
    {
        Cursor cur=database.query(Table_Name, new String[]{ROW_ID,USERNAME,MOVES,TIME}, null, null, null, null, MOVES+" ASC");
        return cur;
    }

}


On Clicking the score option in the option page, the score activity will be started.

Below is the class for score activity.

package com.dynamic.layout;

import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class ScoreList extends Activity
{
    ListView scorelist=null;
   
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.scores_list);
       
        scorelist=(ListView)findViewById(R.id.score_listview);
        scorelist.setAdapter(new ScoreListAdapter(this));
    }
   
    public class ScoreListAdapter extends BaseAdapter
    {
        Context mycontext=null;
       
        public ScoreListAdapter(Context c)
        {
            mycontext=c;
        }

        @Override
        public int getCount()
        {
            // TODO Auto-generated method stub
            return OptionLayout.scoreList.size();
        }

        @Override
        public Object getItem(int position)
        {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public long getItemId(int position)
        {
            // TODO Auto-generated method stub
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent)
        {
            // TODO Auto-generated method stub
            ViewHolder holder=null;
            if(convertView==null)
            {
                LayoutInflater minflater=LayoutInflater.from(mycontext);
                convertView=minflater.inflate(R.layout.score_list_row, null);
                holder=new ViewHolder();
                holder.textname=(TextView)convertView.findViewById(R.id.name_textview);
                holder.textmove=(TextView)convertView.findViewById(R.id.move_textview);
                holder.texttime=(TextView)convertView.findViewById(R.id.time_textview);
               
                convertView.setTag(holder);
            }
            else
            {
                holder=(ViewHolder)convertView.getTag();
            }
           
            holder.textname.setText(OptionLayout.scoreList.get(position).name.trim());
            holder.textmove.setText("Moves : "+OptionLayout.scoreList.get(position).moves.trim());
            holder.texttime.setText("Time = "+OptionLayout.scoreList.get(position).time.trim());
           
            return convertView;
        }
       
        class ViewHolder
        {
             TextView textname;
             TextView textmove;
             TextView texttime;
        }

    }

}


layout used in the score list class is scores_list.xml

Below is the scores_list.xml content.

<?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">
 
  <ListView android:id="@+id/score_listview"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content">
  </ListView>
 
</LinearLayout>


Below is the layout that are inflated in the score list list view. The name of the layout is score_list_row.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content">
 
  <TextView android:id="@+id/name_textview"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_alignParentLeft="true"
      android:layout_marginLeft="10dp"
      android:layout_marginTop="10dp"
      android:text="Name"
      android:textStyle="bold"
      android:textSize="20sp"
      android:textColor="#FFFFFF">
  </TextView>
 
  <TextView android:id="@+id/move_textview"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_below="@+id/name_textview"
      android:layout_alignParentLeft="true"
      android:layout_marginLeft="10dp"
      android:layout_marginTop="10dp"
      android:text="Total Moves : 200 "
      android:textStyle="bold"
      android:textSize="15sp"
      android:textColor="#FFFFFF">
  </TextView>
 
  <TextView android:id="@+id/time_textview"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_below="@+id/name_textview"
      android:layout_alignParentRight="true"
      android:layout_marginRight="10dp"
      android:layout_marginTop="10dp"
      android:text="Time = 0:00"
      android:textStyle="bold"
      android:textSize="15sp"
      android:textColor="#FFFFFF">
  </TextView>
 
</RelativeLayout>

One more class is created called MoveListValues.jave, this class is used for storing the puzzle possible moves and the corresponding numbers and the direction of the move. It also used for storing the score details. This class is used in the ArrayList Type.

package com.dynamic.layout;

public class MoveListValues
{
    public String number;
    public int direction;
    public int move_i, move_j;
    public int empty_i, empty_j;
   
    public String name, moves, time;
   
    public MoveListValues(String number, int direction, int move_i, int move_j, int empty_i, int empty_j)
    {
        this.number=number;
        this.direction=direction;
        this.move_i=move_i;
        this.move_j=move_j;
        this.empty_i=empty_i;
        this.empty_j=empty_j;
    }
   
    public MoveListValues(String name, String moves, String time)
    {
        this.name=name;
        this.moves=moves;
        this.time=time;
    }

}


Below is the sample output screens.