Google+

Thursday, November 1, 2012

How to Return value from Async task in android

Hi,

After bit R&D, reach on some fatastic solution to get return data from Custom AsyncTask in your activity without using onPostExecute() Method.


Following are the steps to for our Goal.


  • Create your android simple project. 
  • Write "MySampleAsyncTask.java" which extends AsyncTask class. (For example check below class)
MySampleAsyncTask.java

1:  package com.sks.asyncresultback;  
2:  import java.util.Random;  
3:  import android.os.AsyncTask;  
4:  public class MySampleAsyncTask extends AsyncTask<Void, Void, Void> {  
5:       OnAsyncResult onAsyncResult;  
6:       public void setOnResultListener(OnAsyncResult onAsyncResult) {  
7:            if (onAsyncResult != null) {  
8:                 this.onAsyncResult = onAsyncResult;  
9:            }  
10:       }  
11:       @Override  
12:       protected Void doInBackground(Void... params) {  
13:            if (onAsyncResult != null) {  
14:                 // TODO apply your business logic  
15:                 int someNumber = new Random().nextInt(999);  
16:                 if (someNumber % 2 == 0) {  
17:                      onAsyncResult.onResultSuccess(0, "Congratulations\nYou Got Success Value");  
18:                 } else {  
19:                      onAsyncResult.onResultFail(1, "Ohhhhhhhhhhh\n Your Result failed");  
20:                 }  
21:            }  
22:            return null;  
23:       }  
24:       public interface OnAsyncResult {  
25:            public abstract void onResultSuccess(int resultCode, String message);  
26:            public abstract void onResultFail(int resultCode, String errorMessage);  
27:       }  
28:  }  


Look into class

At the bottom of code created a new Interface to code.

public interface OnAsyncResult {  
            public abstract void onResultSuccess(int resultCode, String message);  
            public abstract void onResultFail(int resultCode, String errorMessage);  
       }

You are free to use this listener. Here I didn't use onPostExecute() Method. so you can use your business logic as per your way.



  • Now lets Create your "MainActivity.java" from which we are calling our MySampleAsyncTask for our purpose.

1:  public class MainActivity extends Activity {  
2:       public TextView textView;  
3:       MySampleAsyncTask asyncTask;  
4:       @Override  
5:       public void onCreate(Bundle savedInstanceState) {  
6:            super.onCreate(savedInstanceState);  
7:            setContentView(R.layout.activity_main);  
8:            textView = (TextView) findViewById(R.id.tv_Result);  
9:            findViewById(R.id.btn_clickMe).setOnClickListener(new OnClickListener() {  
10:                 @Override  
11:                 public void onClick(View v) {  
12:                      asyncTask = new MySampleAsyncTask();  
13:                      asyncTask.setOnResultListener(asynResult);  
14:                      asyncTask.execute();  
15:                 }  
16:            });  
17:       }  
18:       OnAsyncResult asynResult = new OnAsyncResult() {  
19:            @Override  
20:            public void onResultSuccess(final int resultCode, final String message) {  
21:                 // need to add this part in ui thread.  
22:                 // as you will then thread exception.  
23:                 runOnUiThread(new Runnable() {  
24:                      public void run() {  
25:                           textView.setText("Code : " + resultCode + "\nMessage : " + message);  
26:                      }  
27:                 });  
28:            }  
29:            @Override  
30:            public void onResultFail(final int resultCode, final String errorMessage) {  
31:                 // need to add this part in ui thread.  
32:                 // as you will then thread exception.  
33:                 runOnUiThread(new Runnable() {  
34:                      public void run() {  
35:                           textView.setText("Code : " + resultCode + "\nMessage : " + errorMessage);  
36:                      }  
37:                 });  
38:            }  
39:       };  

at the last block we have create instance of OnAsynkResult listener and set to our MySampleAsyncTask object on Button Click.


18:      OnAsyncResult asynResult = new OnAsyncResult() {  
19:            @Override  
20:            public void onResultSuccess(final int resultCode, final String message) {  
21:                 // need to add this part in ui thread.  
22:                 // as you will then thread exception.  
23:                 runOnUiThread(new Runnable() {  
24:                      public void run() {  
25:                           textView.setText("Code : " + resultCode + "\nMessage : " + message);  
26:                      }  
27:                 });  
28:            }  
29:            @Override  
30:            public void onResultFail(final int resultCode, final String errorMessage) {  
31:                 // need to add this part in ui thread.  
32:                 // as you will then thread exception.  
33:                 runOnUiThread(new Runnable() {  
34:                      public void run() {  
35:                           textView.setText("Code : " + resultCode + "\nMessage : " + errorMessage);  
36:                      }  
37:                 });  
38:            }  
39:       };



on each method, if you want to set values to view then you have to use runOnUiThread methods.
as this listeners are already calling from thread.




Download Source Code

Check our Source code 

svn checkout 
http://smartphone-app-by-sachin-shelke.googlecode.com/svn/trunk/


Comments are always welcome.




Monday, September 10, 2012

How to find Screen Size and Density of Device in Android programatically

Hi add this below code in on Create method and check your device or emulator screen configuration.




if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_LARGE) {
Toast.makeText(Util.mContext, "Large Screen", Toast.LENGTH_SHORT).show();
Util.v("Screen Size : Large ");

} else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
Toast.makeText(Util.mContext, "X Large Screen", Toast.LENGTH_SHORT).show();
Util.v("Screen Size : X Large ");

} else if ((getResources().getConfiguration().screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) == Configuration.SCREENLAYOUT_SIZE_NORMAL) {
Toast.makeText(Util.mContext, "Normal Screen", Toast.LENGTH_SHORT).show();
Util.v("Screen Size : Normal ");

}



//Determine density
   DisplayMetrics metrics = new DisplayMetrics();
       getWindowManager().getDefaultDisplay().getMetrics(metrics);
       int density = metrics.densityDpi;

       if (density==DisplayMetrics.DENSITY_HIGH) {
           Toast.makeText(this, "DENSITY_HIGH... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
           Util.v("DENSITY_HIGH... Density is " + String.valueOf(density));
       }
       else if (density==DisplayMetrics.DENSITY_MEDIUM) {
           Toast.makeText(this, "DENSITY_MEDIUM... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
           Util.v("DENSITY_MEDIUM... Density is " + String.valueOf(density));
       }
       else if (density==DisplayMetrics.DENSITY_LOW) {
           Toast.makeText(this, "DENSITY_LOW... Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
           Util.v("DENSITY_LOW... Density is " + String.valueOf(density));
       }
       else {
           Toast.makeText(this, "Density is neither HIGH, MEDIUM OR LOW.  Density is " + String.valueOf(density),  Toast.LENGTH_LONG).show();
           Util.v("Density is neither HIGH, MEDIUM OR LOW... Density is " + String.valueOf(density));
       }

Monday, July 16, 2012

How to resolve Conversion to Dalvik format failed with error 1


Many times we faced problem of "Conversion to Dalvik format failed with error 1"


When i went through Google and found many solutions but below has solved my problem.



  1. In Eclipse Package Explorer, Right Click on Project -> Select Properties -> Select "Java Build Path" -> and remove all the JARs from library. Then click OK. Project will show you an error.
  2. Then as usual your try fix project property and clean project.
  3. Then again follow the above 1st steps to add your JARs.
  4. Now follow again 2nd step to clear and clean your project.
Hurreeee,
Your problem has been resolve. Run Project and enjoy Coding



Tuesday, April 10, 2012

How to find Android Unique Device ID or UDID - Part 2

In the previous post 
http://smartphonebysachin.blogspot.in/2011/09/how-to-find-android-unique-device-id-or.html
we had seen only how to get ANDROID_D.


Now We will see the Difference Between Android ID & Device ID of Android Phone

Android ID : 
ANDROID_ID is a 64-bit number (as a hex string) that is RANDOMLY GENERATED on the device's first boot and should remain constant for the lifetime of the device.(The value may change if a factory reset is performed on the device.)
Device ID :
Returns the unique device ID, for example, the IMEI for GSM and the MEID or ESN for CDMA phones.


Here is sample Code to get UDID


public class DemoActivity extends Activity {


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);


    TelephonyManager tm = (TelephonyManager)           this.getSystemService(Context.TELEPHONY_SERVICE);


    Log.d("ID", "Android ID: " + Secure.getString(getContentResolver(), Secure.ANDROID_ID));
    Log.d("ID", "Device ID : " + tm.getDeviceId());


}
}


For getting Device ID you have to set following permission in AndroidMenifest.xml


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


For getting ANDROID_ID you don't need to set any permission.








ANDROID_ID seems a good choice for a unique device identifier.

Thursday, April 5, 2012

How to create iPhone like Custom Dialog / Alert View or Box in Android

Hi,


Its very interesting to create iPhone Like AlertView (Dialog Box) in Android.



Follow the steps to create iPhone Like AlertView (Dialog Box) in Android

Step 1 : Create android Project in Eclipse as shown below






Step 2 : Create New Class for Custom Dialog as given below



After creating CustomizeDialog.java write following code into it.

 package com.sks.dialog.custom;  
 import android.app.Dialog;  
 import android.content.Context;  
 import android.text.method.ScrollingMovementMethod;  
 import android.view.View;  
 import android.view.View.OnClickListener;  
 import android.view.Window;  
 import android.widget.Button;  
 import android.widget.TextView;  
 /** Class Must extends with Dialog */  
 /** Implement onClickListener to dismiss dialog when OK Button is pressed */  
 public class CustomizeDialog extends Dialog implements OnClickListener {  
     Button okButton;  
     Context mContext;  
     TextView mTitle = null;  
     TextView mMessage = null;  
     View v = null;  
     public CustomizeDialog(Context context) {  
         super(context);  
         mContext = context;  
         /** 'Window.FEATURE_NO_TITLE' - Used to hide the mTitle */  
         requestWindowFeature(Window.FEATURE_NO_TITLE);  
         /** Design the dialog in main.xml file */  
         setContentView(R.layout.main);  
         v = getWindow().getDecorView();  
         v.setBackgroundResource(android.R.color.transparent);  
         mTitle = (TextView) findViewById(R.id.dialogTitle);  
         mMessage = (TextView) findViewById(R.id.dialogMessage);  
         okButton = (Button) findViewById(R.id.OkButton);  
         okButton.setOnClickListener(this);  
     }  
     @Override  
     public void onClick(View v) {  
         /** When OK Button is clicked, dismiss the dialog */  
         if (v == okButton)  
             dismiss();  
     }  
     @Override  
     public void setTitle(CharSequence title) {  
         super.setTitle(title);  
         mTitle.setText(title);  
     }  
     @Override  
     public void setTitle(int titleId) {  
         super.setTitle(titleId);  
         mTitle.setText(mContext.getResources().getString(titleId));  
     }  
     /**  
      * Set the message text for this dialog's window.  
      *   
      * @param message  
      *      - The new message to display in the title.  
      */  
     public void setMessage(CharSequence message) {  
         mMessage.setText(message);  
         mMessage.setMovementMethod(ScrollingMovementMethod.getInstance());  
     }  
     /**  
      * Set the message text for this dialog's window. The text is retrieved from the resources with the supplied  
      * identifier.  
      *   
      * @param messageId  
      *      - the message's text resource identifier <br>  
      * @see <b>Note : if resourceID wrong application may get crash.</b><br>  
      *   Exception has not handle.  
      */  
     public void setMessage(int messageId) {  
         mMessage.setText(mContext.getResources().getString(messageId));  
         mMessage.setMovementMethod(ScrollingMovementMethod.getInstance());  
     }  
 }  


Very Important part to hide dialog default background.
below code is used to set transparant background of dialog.


v = getWindow().getDecorView();  
v.setBackgroundResource(android.R.color.transparent);



Step 3 : Now We have to create custom Layout for Dialog. 
edit main.xml (you can select layout file name as per your specifications)


 <?xml version="1.0" encoding="utf-8"?>  
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
   android:id="@+id/LinearLayout"  
   android:layout_width="fill_parent"  
   android:layout_height="wrap_content"  
   android:layout_gravity="center"  
   android:layout_margin="0dip"  
   android:background="@drawable/alert_bg"  
   android:orientation="vertical"  
   android:paddingBottom="15dip"  
   android:paddingLeft="0dip"  
   android:paddingRight="0dip"  
   android:paddingTop="0dip" >  
   <TextView  
     android:id="@+id/dialogTitle"  
     android:layout_width="fill_parent"  
     android:layout_height="wrap_content"  
     android:layout_marginTop="20dip"  
     android:background="#00000000"  
     android:gravity="center"  
     android:text=""  
     android:textColor="#fff"  
     android:textSize="22sp"  
     android:textStyle="bold" >  
   </TextView>  
   <TextView  
     android:id="@+id/dialogMessage"  
     android:layout_width="fill_parent"  
     android:layout_height="wrap_content"  
     android:layout_below="@+id/dialogTitle"  
     android:focusable="true"  
     android:focusableInTouchMode="true"  
     android:gravity="center"  
     android:maxLines="10"  
     android:padding="10dip"  
     android:scrollbars="vertical"  
     android:text=""  
     android:textColor="#fff"  
     android:textSize="18sp" >  
   </TextView>  
   <Button  
     android:id="@+id/OkButton"  
     android:layout_width="fill_parent"  
     android:layout_height="wrap_content"  
     android:layout_below="@+id/dialogMessage"  
     android:layout_centerHorizontal="true"  
     android:layout_marginLeft="10dip"  
     android:layout_marginRight="10dip"  
     android:background="@drawable/button"  
     android:text="OK"  
     android:textColor="#FFFFFF" >  
   </Button>  
 </RelativeLayout>  


Step 4 : Add 9 patch image in res->drawable folder given below. You can modify image.
alert_bg.9.png
  
button_bg_normal.9.png

button_bg_pressed.9


titlebg.png
Note : this image transparency is 90% that's why invisible
Step 5 : For adding Focus Effect on Dialog Button create button.xml in drawable folder as given below
 <?xml version="1.0" encoding="utf-8"?>  
 <selector xmlns:android="http://schemas.android.com/apk/res/android">  
     <item android:state_pressed="true" android:drawable="@drawable/button_bg_pressed" /> <!-- pressed -->  
     <item android:state_focused="true" android:drawable="@drawable/button_bg_pressed" /> <!-- focused -->  
     <item android:drawable="@drawable/button_bg_normal" /> <!-- default -->  
 </selector>  


Step 6 : Now Come to our First Activity i.e. CustomDialogExample.java and Modify file as given Below
 package com.sks.dialog.custom;  
 import android.app.Activity;  
 import android.content.Context;  
 import android.os.Bundle;  
 import android.view.View;  
 import android.view.View.OnClickListener;  
 import android.widget.Button;  
 public class CustomDialogExample extends Activity {  
     Context context;  
     CustomizeDialog customizeDialog = null;  
     /** Called when the activity is first created. */  
     @Override  
     public void onCreate(Bundle savedInstanceState) {  
         super.onCreate(savedInstanceState);  
         /** Display Custom Dialog */  
         context = this;  
         setContentView(R.layout.home);  
         Button btn1 = (Button) findViewById(R.id.btnDialog1);  
         btn1.setOnClickListener(new OnClickListener() {  
             @Override  
             public void onClick(View v) {  
                 customizeDialog = new CustomizeDialog(context);  
                 customizeDialog.setTitle("My Title");  
                 customizeDialog.setMessage("My Custom Dialog Message from \nSmartPhoneBySachin.Blogspot.com ");  
                 customizeDialog.show();  
             }  
         });  
     }  
 }  
Now you are ready to Run Project and you will get result as image below




Download Source Code and  Installer Apk

Comments are always welcome.

Enjoy Customization in Android





Friday, March 2, 2012

Custom ListView With Separator and Section in Android



Here we will have a very simple tutorial for Custom ListView in android with Section Header.
We will able to display final view as per below images


 




Steps to Create Custom List View


  1. Open Eclipse to Create New Project.
  2. Create New Project with package name com.sks.demo.custom_list
  3. Add following images in reg->drawable folder



    list_header_bg.9.png
  4. Create a new List Section Header Layout (find the below item_composer_header.xml file)


     <?xml version="1.0" encoding="utf-8"?>  
     <TextView xmlns:android="http://schemas.android.com/apk/res/android"  
       android:id="@+id/list_section_header"  
       android:layout_width="fill_parent"  
       android:layout_height="wrap_content"  
       android:background="@drawable/list_header_bg"  
       android:padding="4dp"  
       android:paddingLeft="10dp"  
       android:shadowColor="#000"  
       android:shadowDx="1"  
       android:shadowDy="1"  
       android:shadowRadius="1"  
       android:text="Header"  
       android:textColor="#FFF"  
       android:textSize="16sp"  
       android:textStyle="bold"  
       android:typeface="serif" />  
    


     
  5. Create a new List Item Custom Layout (find the below item_composer.xml file)
  6.  <?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" >  
       <include  
         android:layout_width="fill_parent"  
         android:layout_height="wrap_content"  
         layout="@layout/item_composer_header" />  
       <LinearLayout  
         android:layout_width="fill_parent"  
         android:layout_height="wrap_content"  
         android:layout_marginLeft="5dp"  
         android:layout_marginRight="5dp"  
         android:background="@drawable/custom_list_item_bg"  
         android:orientation="vertical"  
         android:paddingBottom="3dp"  
         android:paddingLeft="10dp"  
         android:paddingRight="10dp"  
         android:paddingTop="3dp" >  
         <TextView  
           android:id="@+id/list_section_title1"  
           android:layout_width="wrap_content"  
           android:layout_height="wrap_content"  
           android:text="Full Name"  
           android:textColor="@color/white"  
           android:textStyle="bold" />  
         <TextView  
           android:id="@+id/list_section_title2"  
           android:layout_width="wrap_content"  
           android:layout_height="wrap_content"  
           android:text="1500-1600"  
           android:textColor="@color/white" />  
       </LinearLayout>  
     </LinearLayout>  
    


  7.   Now Edit your main.xml to set Custom ListView

     <?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="fill_parent"  
       android:background="@drawable/background" >  
       <TextView  
         android:id="@+id/title"  
         android:layout_width="fill_parent"  
         android:layout_height="wrap_content"  
         android:text="State wise Cities in India" />  
       <com.sks.demo.custom_list.list.SKSCustomListView  
         android:id="@+id/list_services"  
         android:layout_width="fill_parent"  
         android:layout_height="fill_parent"  
         android:layout_below="@+id/title"  
         android:background="#00ffffff"  
         android:cacheColorHint="#00000000"  
         android:divider="@drawable/img_list_seperator"  
         android:dividerHeight="1dip"  
         android:drawingCacheQuality="high"  
         android:keepScreenOn="false" >  
       </com.sks.demo.custom_list.list.SKSCustomListView>  
     </RelativeLayout>  
    




    The Above code will be look like below image. You can set any background.



  8. Here we are going to create our custom list view Widget. 
    • We need to set Some Data & Composer classes for list view item
    • Following is the Data & Composer Class in Default Package

      Code : Data.java
       package com.sks.demo.custom_list;  
       import java.util.ArrayList;  
       import java.util.Arrays;  
       import java.util.List;  
       import android.os.SystemClock;  
       import android.util.Pair;  
       public class Data {  
           public static List<Pair<String, List<Composer>>> getAllData() {  
               List<Pair<String, List<Composer>>> res = new ArrayList<Pair<String, List<Composer>>>();  
               for (int i = 0; i < 4; i++) {  
                   res.add(getOneSection(i));  
               }  
               return res;  
           }  
           public static List<Composer> getFlattenedData() {  
               List<Composer> res = new ArrayList<Composer>();  
               for (int i = 0; i < 4; i++) {  
                   res.addAll(getOneSection(i).second);  
               }  
               return res;  
           }  
           public static Pair<Boolean, List<Composer>> getRows(int page) {  
               List<Composer> flattenedData = getFlattenedData();  
               if (page == 1) {  
                   return new Pair<Boolean, List<Composer>>(true, flattenedData.subList(0, 5));  
               } else {  
                   SystemClock.sleep(2000); // simulate loading  
                   return new Pair<Boolean, List<Composer>>(page * 5 < flattenedData.size(), flattenedData.subList((page) * 5,  
                           Math.min(page * 5, flattenedData.size())));  
               }  
           }  
           public static Pair<String, List<Composer>> getOneSection(int index) {  
               String[] titles =  
               {  
                       "Maharashtra",  
                       "Gujarat",  
                       "Jammu",  
                       "Punjab"  
               };  
               Composer[][] composerss =  
               {  
                       {  
                               new Composer("Amravati", "2,607,160"),  
                               new Composer("Aurangabad", "2,897,103"),  
                               new Composer("Khandala", "21,043"),  
                               new Composer("Mumbai", "11,914,398"),  
                               new Composer("Nagpur", "2,420,000"),  
                               new Composer("Pune", "4,485,000"),  
                       },  
                       {  
                               new Composer("Ahmedabad", "3,913,793"),  
                               new Composer("Surat", "3,344,135"),  
                               new Composer("Vadodara", "1,513,758"),  
                               new Composer("Rajkot", "1,395,026"),  
                               new Composer("Gandhinagar", "271,331"),  
                               new Composer("Bhavnagar", "600,594"),  
                       },  
                       {  
                               new Composer("Kathua", "550,084"),  
                               new Composer("Jammu", "1,343,756"),  
                               new Composer("Samba", "245,016"),  
                               new Composer("Udhampur", "475,068"),  
                               new Composer("Reasi", "268,441"),  
                               new Composer("Rajouri", "483,284"),  
                       },  
                       {  
                               new Composer("Amritsar", "1,183,705"),  
                               new Composer("Firozpur", "110,091"),  
                               new Composer("Ludhiana", "1,613,878"),  
                               new Composer("Chandigarh", "27,704,236"),  
                               new Composer("Jalandhar ", "873,725"),  
                               new Composer("Patiala", "445,196"),  
                       },  
               };  
               return new Pair<String, List<Composer>>(titles[index], Arrays.asList(composerss[index]));  
           }  
       }  
      

      Code : Composer.java
       package com.sks.demo.custom_list;  
       public class Composer {  
           public static final String TAG = Composer.class.getSimpleName();  
           public String name;  
           public String year;  
           public Composer(String name, String year) {  
               this.name = name;  
               this.year = year;  
           }  
       }  
      


  9. Now Create Custom List & Adapter
    • Create New Package com.sks.demo.custom_list.list
    • Create new class SKSCustomListAdapter.java
    • Write code for SKSCustomListAdapter.java

       package com.sks.demo.custom_list.list;  
       import android.view.View;  
       import android.view.ViewGroup;  
       import android.widget.AbsListView;  
       import android.widget.AbsListView.OnScrollListener;  
       import android.widget.BaseAdapter;  
       import android.widget.SectionIndexer;  
       public abstract class SKSCustomListAdapter extends BaseAdapter implements SectionIndexer, OnScrollListener {  
           public static final String TAG = SKSCustomListAdapter.class.getSimpleName();  
           public interface HasMorePagesListener {  
               void noMorePages();  
               void mayHaveMorePages();  
           }  
           /**  
            * The <em>current</em> page, not the page that is going to be loaded.  
            */  
           int page = 1;  
           int initialPage = 1;  
           boolean automaticNextPageLoading = false;  
           HasMorePagesListener hasMorePagesListener;  
           void setHasMorePagesListener(HasMorePagesListener hasMorePagesListener) {  
               this.hasMorePagesListener = hasMorePagesListener;  
           }  
         /**  
          * Pinned header state: don't show the header.  
          */  
         public static final int PINNED_HEADER_GONE = 0;  
         /**  
          * Pinned header state: show the header at the top of the list.  
          */  
         public static final int PINNED_HEADER_VISIBLE = 1;  
         /**  
          * Pinned header state: show the header. If the header extends beyond  
          * the bottom of the first shown element, push it up and clip.  
          */  
         public static final int PINNED_HEADER_PUSHED_UP = 2;  
         /**  
          * Computes the desired state of the pinned header for the given  
          * position of the first visible list item. Allowed return values are  
          * {@link #PINNED_HEADER_GONE}, {@link #PINNED_HEADER_VISIBLE} or  
          * {@link #PINNED_HEADER_PUSHED_UP}.  
          */  
         public int getPinnedHeaderState(int position) {  
             if (position < 0 || getCount() == 0) {  
                 return PINNED_HEADER_GONE;  
             }  
             // The header should get pushed up if the top item shown  
             // is the last item in a section for a particular letter.  
             int section = getSectionForPosition(position);  
             int nextSectionPosition = getPositionForSection(section + 1);  
             if (nextSectionPosition != -1 && position == nextSectionPosition - 1) {  
                 return PINNED_HEADER_PUSHED_UP;  
             }  
             return PINNED_HEADER_VISIBLE;  
         }  
         /**  
          * Sets the initial page when {@link #resetPage()} is called.  
          * Default is 1 (for APIs with 1-based page number).  
          */  
         public void setInitialPage(int initialPage) {  
               this.initialPage = initialPage;  
           }  
         /**  
          * Resets the current page to the page specified in {@link #setInitialPage(int)}.  
          */  
         public void resetPage() {  
             this.page = this.initialPage;  
         }  
         /**  
          * Increases the current page number.  
          */  
         public void nextPage() {  
             this.page++;  
         }  
           @Override  
           public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
               if (view instanceof SKSCustomListView) {  
                   ((SKSCustomListView) view).configureHeaderView(firstVisibleItem);  
               }  
           }  
           @Override  
           public void onScrollStateChanged(AbsListView view, int scrollState) {  
               // nop  
           }  
           @Override  
           public final View getView(int position, View convertView, ViewGroup parent) {  
               View res = getAmazingView(position, convertView, parent);  
               if (position == getCount() - 1 && automaticNextPageLoading) {  
                   onNextPageRequested(page + 1);  
               }  
               final int section = getSectionForPosition(position);  
               boolean displaySectionHeaders = (getPositionForSection(section) == position);  
               bindSectionHeader(res, position, displaySectionHeaders);  
               return res;  
           }  
           public void notifyNoMorePages() {  
               automaticNextPageLoading = false;  
               if (hasMorePagesListener != null) hasMorePagesListener.noMorePages();  
           }  
           public void notifyMayHaveMorePages() {  
               automaticNextPageLoading = true;  
               if (hasMorePagesListener != null) hasMorePagesListener.mayHaveMorePages();  
           }  
           /**  
            * The last item on the list is requested to be seen, so do the request   
            * and call {@link SKSCustomListView#tellNoMoreData()} if there is no more pages.  
            *   
            * @param page the page number to load.  
            */  
           protected abstract void onNextPageRequested(int page);  
           /**  
            * Configure the view (a listview item) to display headers or not based on displaySectionHeader   
            * (e.g. if displaySectionHeader header.setVisibility(VISIBLE) else header.setVisibility(GONE)).  
            */  
           protected abstract void bindSectionHeader(View view, int position, boolean displaySectionHeader);  
           /**  
            * read: get view too  
            */  
           public abstract View getAmazingView(int position, View convertView, ViewGroup parent);  
         /**  
          * Configures the pinned header view to match the first visible list item.  
          *  
          * @param header pinned header view.  
          * @param position position of the first visible list item.  
          * @param alpha fading of the header view, between 0 and 255.  
          */  
         public abstract void configurePinnedHeader(View header, int position, int alpha);  
           @Override  
           public abstract int getPositionForSection(int section);  
           @Override  
           public abstract int getSectionForPosition(int position);  
           @Override  
           public abstract Object[] getSections();  
       }  
      
    • Create new Class SKSCustomListView.java
    • Write code for SKSCustomListView.java
       package com.sks.demo.custom_list.list;  
       import android.content.Context;  
       import android.graphics.Canvas;  
       import android.util.AttributeSet;  
       import android.view.View;  
       import android.widget.ListAdapter;  
       import android.widget.ListView;  
       import com.sks.demo.custom_list.list.SKSCustomListAdapter.HasMorePagesListener;  
       /**  
        * A ListView that maintains a header pinned at the top of the list. The pinned  
        * header can be pushed up and dissolved as needed.  
        *   
        * It also supports pagination by setting a custom view as the loading  
        * indicator.  
        */  
       public class SKSCustomListView extends ListView implements HasMorePagesListener {  
           View listFooter;  
           boolean footerViewAttached = false;  
           private View mHeaderView;  
           private boolean mHeaderViewVisible;  
           private int mHeaderViewWidth;  
           private int mHeaderViewHeight;  
           private SKSCustomListAdapter adapter;  
           public void setPinnedHeaderView(View view) {  
               mHeaderView = view;  
               // Disable vertical fading when the pinned header is present  
               // TODO change ListView to allow separate measures for top and bottom  
               // fading edge;  
               // in this particular case we would like to disable the top, but not the  
               // bottom edge.  
               if (mHeaderView != null) {  
                   setFadingEdgeLength(0);  
               }  
               requestLayout();  
           }  
           @Override  
           protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
               super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
               if (mHeaderView != null) {  
                   measureChild(mHeaderView, widthMeasureSpec, heightMeasureSpec);  
                   mHeaderViewWidth = mHeaderView.getMeasuredWidth();  
                   mHeaderViewHeight = mHeaderView.getMeasuredHeight();  
               }  
           }  
           @Override  
           protected void onLayout(boolean changed, int left, int top, int right, int bottom) {  
               super.onLayout(changed, left, top, right, bottom);  
               if (mHeaderView != null) {  
                   mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);  
                   configureHeaderView(getFirstVisiblePosition());  
               }  
           }  
           public void configureHeaderView(int position) {  
               if (mHeaderView == null) {  
                   return;  
               }  
               int state = adapter.getPinnedHeaderState(position);  
               switch (state) {  
               case SKSCustomListAdapter.PINNED_HEADER_GONE: {  
                   mHeaderViewVisible = false;  
                   break;  
               }  
               case SKSCustomListAdapter.PINNED_HEADER_VISIBLE: {  
                   adapter.configurePinnedHeader(mHeaderView, position, 255);  
                   if (mHeaderView.getTop() != 0) {  
                       mHeaderView.layout(0, 0, mHeaderViewWidth, mHeaderViewHeight);  
                   }  
                   mHeaderViewVisible = true;  
                   break;  
               }  
               case SKSCustomListAdapter.PINNED_HEADER_PUSHED_UP: {  
                   View firstView = getChildAt(0);  
                   if (firstView != null) {  
                       int bottom = firstView.getBottom();  
                       int headerHeight = mHeaderView.getHeight();  
                       int y;  
                       int alpha;  
                       if (bottom < headerHeight) {  
                           y = (bottom - headerHeight);  
                           alpha = 255 * (headerHeight + y) / headerHeight;  
                       } else {  
                           y = 0;  
                           alpha = 255;  
                       }  
                       adapter.configurePinnedHeader(mHeaderView, position, alpha);  
                       if (mHeaderView.getTop() != y) {  
                           mHeaderView.layout(0, y, mHeaderViewWidth, mHeaderViewHeight + y);  
                       }  
                       mHeaderViewVisible = true;  
                   }  
                   break;  
               }  
               }  
           }  
           @Override  
           protected void dispatchDraw(Canvas canvas) {  
               super.dispatchDraw(canvas);  
               if (mHeaderViewVisible) {  
                   drawChild(canvas, mHeaderView, getDrawingTime());  
               }  
           }  
           public SKSCustomListView(Context context) {  
               super(context);  
           }  
           public SKSCustomListView(Context context, AttributeSet attrs) {  
               super(context, attrs);  
           }  
           public SKSCustomListView(Context context, AttributeSet attrs, int defStyle) {  
               super(context, attrs, defStyle);  
           }  
           public void setLoadingView(View listFooter) {  
               this.listFooter = listFooter;  
           }  
           public View getLoadingView() {  
               return listFooter;  
           }  
           @Override  
           public void setAdapter(ListAdapter adapter) {  
               if (!(adapter instanceof SKSCustomListAdapter)) {  
                   throw new IllegalArgumentException(SKSCustomListView.class.getSimpleName() + " must use adapter of type "  
                           + SKSCustomListAdapter.class.getSimpleName());  
               }  
               // previous adapter  
               if (this.adapter != null) {  
                   this.adapter.setHasMorePagesListener(null);  
                   this.setOnScrollListener(null);  
               }  
               this.adapter = (SKSCustomListAdapter) adapter;  
               ((SKSCustomListAdapter) adapter).setHasMorePagesListener(this);  
               this.setOnScrollListener((SKSCustomListAdapter) adapter);  
               View dummy = new View(getContext());  
               super.addFooterView(dummy);  
               super.setAdapter(adapter);  
               super.removeFooterView(dummy);  
           }  
           @Override  
           public SKSCustomListAdapter getAdapter() {  
               return adapter;  
           }  
           @Override  
           public void noMorePages() {  
               if (listFooter != null) {  
                   this.removeFooterView(listFooter);  
               }  
               footerViewAttached = false;  
           }  
           @Override  
           public void mayHaveMorePages() {  
               if (!footerViewAttached && listFooter != null) {  
                   this.addFooterView(listFooter);  
                   footerViewAttached = true;  
               }  
           }  
           public boolean isLoadingViewVisible() {  
               return footerViewAttached;  
           }  
       }  
      
  10. Finally We reach to create our Start-up Activity named as CustomListDemoActivity.java  
    • In main package i.e. com.sks.demo.custom_list Create new Activity  CustomListDemoActivity.java
    • Write code for CustomListDemoActivity.java
      Code :  CustomListDemoActivity.java 
       package com.sks.demo.custom_list;  
       import java.util.List;  
       import android.app.Activity;  
       import android.content.Context;  
       import android.os.Bundle;  
       import android.util.Log;  
       import android.util.Pair;  
       import android.view.LayoutInflater;  
       import android.view.View;  
       import android.view.ViewGroup;  
       import android.widget.AdapterView;  
       import android.widget.AdapterView.OnItemClickListener;  
       import android.widget.TextView;  
       import com.sks.demo.custom_list.list.SKSCustomListAdapter;  
       import com.sks.demo.custom_list.list.SKSCustomListView;  
       public class CustomListDemoActivity extends Activity {  
           SKSCustomListView lsComposer;  
           SectionComposerAdapter adapter;  
           Context context;  
           /** Called when the activity is first created. */  
           @Override  
           public void onCreate(Bundle savedInstanceState) {  
               super.onCreate(savedInstanceState);  
               setContentView(R.layout.main);  
               context = getParent();  
           }  
           @Override  
           protected void onStart() {  
               super.onStart();  
               initializedView();  
               setupFunctionality();  
               setupListeners();  
           }  
           private void initializedView() {  
               lsComposer = (SKSCustomListView) findViewById(R.id.list_services);  
           }  
           private void setupFunctionality() {  
               lsComposer.setPinnedHeaderView(LayoutInflater.from(this).inflate(R.layout.item_composer_header, lsComposer, false));  
               lsComposer.setAdapter(adapter = new SectionComposerAdapter());  
               lsComposer.setOnItemClickListener(new OnItemClickListener() {  
                   @Override  
                   public void onItemClick(AdapterView<?> parent, View view, int position, long id) {  
                       // Intent intent = new Intent(CustomListDemoActivity.this,  
                       // ServiceDestailsScreen.class);  
                       String name, address, title;  
                       title = ((TextView) view.findViewById(R.id.list_section_header)).getText().toString();  
                       name = ((TextView) view.findViewById(R.id.list_section_title1)).getText().toString();  
                       address = ((TextView) view.findViewById(R.id.list_section_title2)).getText().toString();  
                       // intent.putExtra("serviceName", title);  
                       // intent.putExtra("name", name);  
                       // intent.putExtra("address", address);  
                       Log.v(Util.TAG, "Name : " + name);  
                       Log.v(Util.TAG, "Address : " + address);  
                       Log.v(Util.TAG, "Title: " + title);  
                       // getParent().startActivity(intent);  
                   }  
               });  
           }  
           private void setupListeners() {  
               // titleBack.setOnClickListener(this);  
           }  
           class SectionComposerAdapter extends SKSCustomListAdapter {  
               List<Pair<String, List<Composer>>> all = Data.getAllData();  
               @Override  
               public int getCount() {  
                   int res = 0;  
                   for (int i = 0; i < all.size(); i++) {  
                       res += all.get(i).second.size();  
                   }  
                   return res;  
               }  
               @Override  
               public Composer getItem(int position) {  
                   int c = 0;  
                   for (int i = 0; i < all.size(); i++) {  
                       if (position >= c && position < c + all.get(i).second.size()) {  
                           return all.get(i).second.get(position - c);  
                       }  
                       c += all.get(i).second.size();  
                   }  
                   return null;  
               }  
               @Override  
               public long getItemId(int position) {  
                   return position;  
               }  
               @Override  
               protected void onNextPageRequested(int page) {  
               }  
               @Override  
               protected void bindSectionHeader(View view, int position, boolean displaySectionHeader) {  
                   if (displaySectionHeader) {  
                       view.findViewById(R.id.list_section_header).setVisibility(View.VISIBLE);  
                       TextView lSectionTitle = (TextView) view.findViewById(R.id.list_section_header);  
                       lSectionTitle.setText(getSections()[getSectionForPosition(position)]);  
                   } else {  
                       TextView lSectionTitle = (TextView) view.findViewById(R.id.list_section_header);  
                       lSectionTitle.setText(getSections()[getSectionForPosition(position)]);  
                       view.findViewById(R.id.list_section_header).setVisibility(View.GONE);  
                   }  
               }  
               @Override  
               public View getAmazingView(int position, View convertView, ViewGroup parent) {  
                   View res = convertView;  
                   if (res == null)  
                       res = getLayoutInflater().inflate(R.layout.item_composer, null);  
                   TextView lName = (TextView) res.findViewById(R.id.list_section_title1);  
                   TextView lYear = (TextView) res.findViewById(R.id.list_section_title2);  
                   Composer composer = getItem(position);  
                   lName.setText(composer.name);  
                   lYear.setText("Population : " + composer.year);  
                   return res;  
               }  
               @Override  
               public void configurePinnedHeader(View header, int position, int alpha) {  
                   TextView lSectionHeader = (TextView) header;  
                   lSectionHeader.setText(getSections()[getSectionForPosition(position)]);  
                   // lSectionHeader.setBackgroundColor(alpha << 24 | (0xbbffbb));  
                   // lSectionHeader.setTextColor(alpha << 24 | (0x000000));  
               }  
               @Override  
               public int getPositionForSection(int section) {  
                   if (section < 0)  
                       section = 0;  
                   if (section >= all.size())  
                       section = all.size() - 1;  
                   int c = 0;  
                   for (int i = 0; i < all.size(); i++) {  
                       if (section == i) {  
                           return c;  
                       }  
                       c += all.get(i).second.size();  
                   }  
                   return 0;  
               }  
               @Override  
               public int getSectionForPosition(int position) {  
                   int c = 0;  
                   for (int i = 0; i < all.size(); i++) {  
                       if (position >= c && position < c + all.get(i).second.size()) {  
                           return i;  
                       }  
                       c += all.get(i).second.size();  
                   }  
                   return -1;  
               }  
               @Override  
               public String[] getSections() {  
                   String[] res = new String[all.size()];  
                   for (int i = 0; i < all.size(); i++) {  
                       res[i] = all.get(i).first;  
                   }  
                   return res;  
               }  
           }  
       }  
      
    • Make sure the changes in AndroidMenifest.xml

      Code : AndroidMenifest.xml
       <?xml version="1.0" encoding="utf-8"?>  
       <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
         package="com.sks.demo.custom_list"  
         android:versionCode="1"  
         android:versionName="1.0" >  
         <uses-sdk android:minSdkVersion="8" />  
         <application  
           android:icon="@drawable/ic_launcher"  
           android:label="@string/app_name" >  
           <activity  
             android:name=".CustomListDemoActivity"  
             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>  
      
  11. Finally Code writing work has been complete. Start compiling Android project.
  12. Run the project.
  13. Result will be like below
  
Download Source Code and  Installer Apk

SVN Repository


Enjoy the Code and do not forget to leave comments.

Thursday, February 23, 2012

Windows Phone 7 Design Guidelines – Cheat Sheet


Navigation, frames and pages
  • Mockup the pages and navigational map of your application and walk through them several times before coding. This will minimize or eliminate the need to add pages or change the map later, when it will be much harder.
  • Make sure to consider the back button and user interactions with the application bar when creating your navigation map.
Application Bar
  • Use the application bar button for common application tasks.
  • You are limited to four application bar buttons.
  • Place less frequently performed actions in the application bar menu.
  • If the action is difficult to clearly convey with an icon, place it in the application bar menu instead of as a button.
  • You are limited to five application bar menu items to prevent scrolling.
  • Standard application bar icons are installed as part of the Windows Phone Developer tools. Find them at C:\Program Files\Microsoft SDKs\Windows Phone\v7.0\Icons
  • Custom application bar icons should be 48 x 48 pixels and use a white foreground on a transparent background. You do not need the circle in the icon, as this is drawn by the application bar.
Back button
  • Pressing the back button from the first screen of an application must exit the application.
  • Pressing the back button must return the application to the previous page.
  • If the current page displays a context menu or a dialog, the pressing the Back button must close the menu or dialog and cancel the backward navigation to the previous page.
  • You should only implement back button behaviors that navigate back or dismiss context menus or modal dialog boxes. All other implementations are prohibited.
Screen orientations
  • Portrait is the default application view-you must add code to support landscape view
  • If an application supports landscape it cannot specify only left or only right landscape views – both views must be supported.
Application icon
  • Application icon should be 62 x 62 pixels and PNG format.
Tiles and tile notification
  • Tile images should PNG format and measure 173 pixels by 173 pixels at 256 dpi
  • Make sure to change Build Action for images to Content when you add them to Visual Studio.
Themes
  • Avoid using too much white in applications, such as white backgrounds, as this may have an impact on battery life for devices that have organic LED displays.
  • If the foreground or background color of a control is explicitly set, verify that the content is visible in both dark and light themes. If the set color is not visible, also explicitly set the background or foreground color to maintain contrast or choose a more appropriate color.
Application settings
  • Application actions that overwrite or delete data, or are irreversible must have a “Cancel” button.
  • When using additional screens with commit and cancel buttons, clicking those buttons should perform the associated action and return the user to the main settings screen.
Touch input
  • All basic or common tasks should be completed using a single finger.
  • Touch controls should respond to touch immediately. A touch control that lags or that seems slow when transitioning will have a negative impact on the user experience.
  • For time consuming processes, developers should provide feedback to indicate that something is happening by using content to indicate progress, or consider using a progress bar or raw notification as a last resort. For example, show more and more of the content as it is being downloaded.
  • The touch and hold gesture should generally be used to display a context menu or options page for an item.
On-screen keyboard
  • You should set the InputScope property for a text box or other edit controls to define the keyboard type and enable the appropriate typing aides. For example, if you choose the URL input scope, a keyboard layout will be shown featuring a .com key.
Canvas/Grid for layout
  • Canvas uses a pixel-based layout and can provide better layout performance than the grid control for deeply embedded or nested controls in for applications that do not change orientations.
  • Grid control is the best choice when the application frame needs to grow, shrink, or rotate.
Panorama control/pivot considerations
  • Both panorama and pivot controls provide horizontal navigation through phone content, enabling the user to flick and pan as necessary.
  • Use panorama elements as the starting point for more detailed experiences.
  • Use a pivot control to filter large data sets, providing a view of multiple data sets, or to provide a way to switch between different views of the same data.
  • Do not use the pivot control for task-based navigation, like in a wizard application.
  • Use for vertical scrolling through a list or grid in panorama sections is acceptable as long as it is within the confines of the section and is not in parallel with a horizontal scroll.
  • Never place a pivot control inside of another pivot control.
  • Never place a pivot control inside of a panorama control.
  • Applications should minimize the number of pivot pages.
  • The Pivot control should only be used to display items or data of similar type.
Text guidelines
  • Use fonts other than Segoe sparingly
  • Avoid using font sizes that are smaller than 15 points in size.
  • Maintain consistent capitalization practices to prevent a disjointed or jagged reading experience.
  • The title bar application title should be all capitals.
  • User all lower case letters for most other application text including page titles, list titles, etc.


Enjoy Windows Phone 7 Development.
All the Best





Source : Windows MSDN
Google+