Monday, July 27, 2015

Most Used Intents in Android

These intents are called Explicit Intents in Android, because you make a call that indicates exactly which activity class to work with. Remember these as Explicit Activity Calls.

Launch Another Activity

 Intent intent = new Intent(getApplicationContext(), NextActivity.class);
startActivity(intent);


Pass value to another activity via Intent putExtra


pass value:


Intent intent = new Intent(getApplicationContext(), NextActivity.class);
intent.putExtra("user_id", 10);
startActivity(intent);


receive value onCreate of NextActivity:


String user_id = "";
Bundle extras = getIntent().getExtras();

if(extras != null) {
    user_id = extras.getString("user_id", null);
}


Open Dialer with Phone Intent

Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:"+phone.getText().toString()));
startActivity(intent);

Open Google Maps Intent from address:

 String address = tvaddress.getText().toString(); // Get addressaddress = address.replace(" ", "+");
Intent geoIntent = new Intent (android.content.Intent.ACTION_VIEW, Uri.parse ("geo:0,0?q=" + address)); // Prepare intentstartActivity(geoIntent); // Initiate lookup

Open Google Maps Intent from lat long


String uri = String.format(Locale.ENGLISH, "geo:%f,%f", lat, lng);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);

or

String uri = "http://maps.google.com/maps?q=loc:" + lat + "," + lng + " (" + youraddress + ")";

or

String uri = "http://maps.google.com/maps?q=geo:0,0?q=" + youraddress


Open Google Maps Intent given address string

String uri = "http://maps.google.co.in/maps?q=" + youraddress;


Open Email Programs, Specify email address and / or subejct:


Intent emailIntent = new Intent(Intent.ACTION_SENDTO);
emailIntent.setData(Uri.parse("mailto:")); // only email apps should handle thisemailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"info@semicolondev.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Feedback to Semicolon Developers");
emailIntent.putExtra(Intent.EXTRA_TEXT, "Hey,\n\n");
startActivity(Intent.createChooser(emailIntent, "Send Feedback..."));


Share Dialog Intent:

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "this is your text to share");
startActivity(Intent.createChooser(intent, "Share with"));


Open Website URL

String url = "http://semicolondev.com";
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse(url));
startActivity(i);



Tuesday, July 21, 2015

Launcher Activity without UI login / logout case


Redirect user to different activities based on login logout stats or other intro activities on first run of the app. Launcher activity without UI helps achieve this with no UI glitches.

SET:  android:theme="@android:style/Theme.NoDisplay"
In your manifest file

        <activity
            android:name=".LauncherActivity"
            android:screenOrientation="portrait"
            android:theme="@android:style/Theme.NoDisplay">

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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


        </activity>

Use Activity Like this

package com.semicolondev.app;


import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;

public class LauncherActivity extends Activity {

SharedPreferences preferences;


@Override
protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

preferences = getSharedPreferences("MyApp", 0);


String firstRun = preferences.getString("first_run", "yes");
String isLogin = preferences.getString("login", "no");

if (firstRun.equals("no") && isLogin.equals("no")){

finish();
startActivity(new Intent(getApplicationContext(), LoginActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));

} else if ( firstRun.equals("no") && isLogin.equals("yes")){

finish();
startActivity(new Intent(getApplicationContext(), MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));

} else {

finish();
startActivity(new Intent(getApplicationContext(), IntroActivity.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK));

}



//setContentView(R.layout.activity_main);


}




}

Tuesday, October 21, 2014

Android Services - Introduction

What is Service?

A service is a component that runs in background to run operation/tasks without user interaction.
i.e, a service might play music in the background while the user is in a different application, or it might fetch data over the server without blocking user interaction with in an activity.

Many Android apps need to do some things in the background when your application isn't open .
Maybe we need to periodically abstract data from server or maybe we need to have certain tasks run on an interval that is specified by users. Android Service is the best for these tasks.

Is service different from thread??

As we know services and thread are both run on background and both are run without user interaction. But they are very different in how they are applied in android application, and most importantly services is not a thread. It runs on the UI thread(User Interface thread) along with our application. Some time we have to use thread inside of services while lifting some heavy data from server in our application.

A service is usually take two state

1. Started:
It is started by activity by calling startService(), once it is started it runs on background indefinitely. It is basically used for downloading/uploading file over server (which is done for one time operation).
After its done it should stop itself.


2. Bound:

It is started by activity by calling bindService(). A bount service offers client-server interface that allow component to interact with service, send request , get result, and even do so across processes with interprocess communication(IPC).

There are two type of services 

1. Platform services:
The android Platform Services are default android system services. The Android platform provides and runs predefined system services and every Android application can use them, given the right permissions. These system services are usually exposed via a specific Manager class. To access them we need  getSystemService() method. The Context class defines several constants for accessing these services.

2. Custom Services:
Custom services allows us to design responsive applications.We can fetch the application data via it and once the application is started by the user, it can present fresh data to the users.

How to create a custom services in android app, its so simple look below.

//creating a new class for service
public class MyService extends Service {
  @Override
  public IBinder onBind(Intent arg0) {
            //TODO for communication return IBinder implementation
           return null;
  }

  @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
     // Let it continue running until it is stopped.
     Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
     return START_STICKY;
  }

  @Override
  public void onDestroy() {
     super.onDestroy();
     Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
  }
}

 Calling  services in our activity....

public class MainActivity extends Activity {
@Override 

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

             //Start service 
startService(new Intent(getBaseContext(), MyService.class));
     }

Finally a service needs to be declared in the AndroidManifest.xml file...like below
 <service android:name=".MyService" />


How to start Services regularly via AlarmManager?

Here is the complete example of starting Service regularly via AlarmManager to notify user through NotificationManager. For this we need to create MyService (extends IntentService), AlarmNotificationReceicer (extends BroadcastReceiver), MainActivity (extends Activity) and declare service and receiver in AndroidMinfeast.xml file...See  below.....

1. Make a Class for Service which Extends IntentService.

package com.examples.semicolon.Alarms;

import android.app.AlarmManager;
import android.app.IntentService;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.SystemClock;

public class MyService extends IntentService {

private AlarmManager mAlarmManager;
private Intent mNotificationReceiverIntent, mLoggerReceiverIntent;
private PendingIntent mNotificationReceiverPendingIntent,
mLoggerReceiverPendingIntent;
private static final long INITIAL_ALARM_DELAY = 1 * 60 * 1000;

public MyService() {


super("Semicolon");
}

@Override
protected void onHandleIntent(Intent intent) {

// Get the AlarmManager Service(platform services)
mAlarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

// Create PendingIntent to start the AlarmNotificationReceiver
mNotificationReceiverIntent = new Intent(MyService.this,
AlarmNotificationReceiver.class);
mNotificationReceiverPendingIntent = PendingIntent.getBroadcast(
PlayService.this, 0, mNotificationReceiverIntent, 0);

// seting repeated alarm
mAlarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime() + INITIAL_ALARM_DELAY,
INITIAL_ALARM_DELAY, mNotificationReceiverPendingIntent);

}

}


2. Make a class for Notification which extends BroadcastReceiver

package com.examples.semicolon.Alarms;

import java.text.DateFormat;
import java.util.Date;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import course.examples.Alarms.AlarmCreate2.R;

public class AlarmNotificationReceiver extends BroadcastReceiver {
// Notification ID to allow for future updates
private static final int MY_NOTIFICATION_ID = 1;
private static final String TAG = "AlarmNotificationReceiver";

// Notification Text Elements
private final CharSequence tickerText = "Are You Playing games Again!";
private final CharSequence contentTitle = "A Kind of Reminder";
private final CharSequence contentText = "Get back to studying!!";

// Notification Action Elements
private Intent mNotificationIntent;
private PendingIntent mContentIntent;

// Notification Sound and Vibration on Arrival
private Uri soundURI = Uri.parse("android.resource://com.examples.semicolon.Alarms/"
+ R.raw.alarm_rooster);
private long[] mVibratePattern = { 0, 200, 200, 300 };

@Override
public void onReceive(Context context, Intent intent) {

mNotificationIntent = new Intent(context, MainActivity.class);
mContentIntent = PendingIntent.getActivity(context, 0,
mNotificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);

                 // notification building
Notification.Builder notificationBuilder = new Notification.Builder(

context).setTicker(tickerText)
.setSmallIcon(android.R.drawable.stat_sys_warning)// icon from drawable
.setAutoCancel(true).setContentTitle(contentTitle)
.setContentText(contentText).setContentIntent(mContentIntent)
.setSound(soundURI).setVibrate(mVibratePattern);

// Pass the Notification to the NotificationManager:
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(MY_NOTIFICATION_ID,
notificationBuilder.build());

Log.i(TAG,"Sending notification at:" + DateFormat.getDateTimeInstance().format(new                      Date()));

}
}

3. Creating  the activity and calling the service in an activity.


package com.examples.semicolon.Alarms;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import course.examples.Alarms.AlarmCreate2.R;

public class MainActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
                //start the service
startService(new Intent(getBaseContext(), MyService.class));
}
}

4. Defined the Service and Receiver in AndroidManifest.xml file

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

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="19" />

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

    <application
        android:allowBackup="false"
        android:icon="@drawable/icon"
        android:label="@string/app_name" >
        <activity
            android:name="com.examples.semicolon.Alarms.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>

        <receiver android:name="com.examples.semicolon.Alarms.AlarmNotificationReceiver" />
        <service android:name="com.examples.semicolon.Alarms.PlayService" />

    </application>

</manifest>

The output of  above code: You will receive a notification in every 1 minute of time interval even your app is not open.



Sunday, October 12, 2014

WordPress JSON API Development

WordPress is a fully featured framework with high user friendly nature and variable option of customization. There is also an availability of rss feed but when we need to built our own customized API, it is a troubling matter. I assume you are already familiar with WordPress hooks, action and filter. In this tutorial, we are going to learn about how to built our own custom API and feed the data in well known JSON format.

To create an API, the three things are required:

  1. URI : Path for accessing API
  2. Custom Variable : Required if values is being sent using GET Method
  3. Query handler : Handling the Request

Step 1: Generating URI for the API

URI is the method of accessing API defined for particular task and addition data is send to determine the action. WordPress has a convenient way to define URL. It has a built in action for rewrite rule.

add_rewrite_rule($regex, $redirect, $after);
$regex- It is used to define the URI of API like what is to be sent and a what the receiver can expect. Eg: www.example.com/values/?[0-9]
  • $redirect- It actually takes the GET data and array-matches[] is used to get the values. Eg:  www.example.com/values/?id=matches[1]
  • $after- It has two option top and bottom. "top" does not require checking of existing WordPress rule while "bottom" requires.  

Step 2: Registering Custom Variables

Custom variables are the one which is sent through the URI as like values and id in above cases. In order to use custom variable, they must be registered so that WordPress can recognize them and we can use or get them anywhere we need.

add_filter( 'query_vars', 'function_name');
function function_name($vars){
$vars[]="values";
$vars[]="id";
return $vars;
}
Now, we have two variables "values" and "id" which can be passed through the URI and it can be accessed as

global $wp;
$wp->query_vars['id'];
$wp->query_vars['values'];

Step 3: Sniffing Request and Handling Queries

We have all the necessary backbone for API but we need one more thing i.e. Query Handler. When a URI is entered in the address bar, we need to get that address and check whether that address is for our API or not, if yes we need to perform our task otherwise let it go. WordPress has a beautiful hook for it and check if our variable is present or not.

add_action('parse_request',  'sniff_requests');
function sniff_requests(){
 global $wp;
  if (!empty($wp->query_vars['values']) AND !empty($wp->query_vars['id']) ) {
$this->handle_request();
exit;
  }
}
If the URI has our function, we can run our function(handle_request) otherwise we let WordPress handle it.

Wednesday, September 24, 2014

My First WordPress Plugin - Tutorial Part 3

In the previous tutorials;

  • Tutorial-1 :  It describes the general idea of what a plugin is in WordPress and what are the basics to create a plugin and a simple illustration of manipulating the content using filter.

  • Tutorial-2 : It focuses on creating a simple custom post type and taxonomies and  meta boxes to input additional information providing the user a flexible way to create their own menu, pages and labels.
In this tutorial, we will go through a process to create a plugin that enables to add custom pages to the admin menu section and provide the user with an ability to create and store data in the custom designed database table.

Database Table Creation:

Our plugin stores the data in a user designed database table instead of WP database. So, as soon as plugin is activated, a check for the table availability is done with an activation hook and a database table is created.
register_activation_hook( __FILE__, 'function-to-create-database-table' );
function function-to-create-database-table(){
global $wpdb;
$table_name = $wpdb->prefix. 'table-name';
if($wpdb->get_var("SHOW TABLES LIKE '$table_name'") != $table_name) {
   $sql="CREATE TABLE $table_name(
    //tables fields
    ) ";
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
dbDelta( $sql );
}
}
Now, the table with the user defined field has been created.

Admin Pages Creation:

 Admin Pages is our custom menu where we have our freedom to create the menu as our need. In our case, we are creating two menus; one to show, edit and delete the data and another one to add the data to the user created table.
add_action('admin_menu','page-to-view-items');
add_action('admin_menu','page-add-items');
function page-to-view-items(){
add_menu_page();
}
function page-add-items(){
add_submenu_page();
}
Now that we have created a admin menu and sub-menu. Suppose if we are creating the plugin for products, lets include a  menu Product and and sub-menu Add Products. Menu-Product is linked to a php file to represent all the data in table and an option to edit them while sub-menu Add Product contains the product add form. Lets have a peek to the add form.

Sub-Menu (Data Addition Form):

It contains normal html form to submit the data and you can create a custom css as per the design requirement. Inorder to insert the form data into the custom database table, the code is as below:
global $wpdb;
$table_name = $wpdb->prefix. 'table-name';
$field1=$_POST["field1"];//retrieving the data from the form using post method
$field2=$_POST["field2"];
$field3=$_POST["field3"];
  $wpdb->insert(
$table_name,
array(
'table-field-1' =>$field1,
'table-field-2' => $field2,
'table-field-3' => $field3
)
);

Displaying Data In Table:

For displaying the data, the easiest way is to use the default WordPress table so that the look and nature of the table is similar to the WordPress post display UI. 
<div class="wrap">
  <div class="icon32" id="icon-edit"><br></div>
  <h2><?php _e('Title') ?></h2>
<form method="post" action="" id="update_action">
<table class="widefat page fixed" cellpadding="0">
      <thead>
        <tr>
        <th id="cb" class="manage-column column-cb check-column" style="" scope="col">
          <input type="checkbox"/>
        </th>
          <th class="manage-column"><?php _e('title 1')?></th>
          <th class="manage-column"><?php _e('title 2')?></th>
          <th class="manage-column"><?php _e('title 3')?></th>
          <th class="manage-column"><?php _e('title 4')?></th>
        </tr>
      </thead>
      <tfoot>
        <tr>
        <th id="cb" class="manage-column column-cb check-column" style="" scope="col">
          <input type="checkbox"/>
        </th>
          <th class="manage-column"><?php _e('title 1')?></th>
          <th class="manage-column"><?php _e('title 2')?></th>
          <th class="manage-column"><?php _e('title 3')?></th>
          <th class="manage-column"><?php _e('title 4')?></th>
        </tr>
      </tfoot>
      <tbody>
        <?php
          $table = function-to-call-all-data();
          if($table){
           $i=0;
           foreach($table as $data) {
               $i++;
        ?>
      <tr class="<?php echo (ceil($i/2) == ($i/2)) ? "" : "alternate"; ?>">
        <th class="check-column" scope="row">
          <input type="checkbox" value="<?php echo $data->id?>" name="bor_id[]" />
        </th>
          <td>
          <strong><?php echo $data->db-table-field-1?></strong>
          <div class="row-actions-visible">
          <span class="edit"><a href="?page=redirect -to-edit-function-page-(page-title)">Edit</a> | </span>
          <span class="delete"><a href="?page=redirect -to-delete-function-page-(page-title)" onclick="return confirm('Are you sure you want to delete this software?');">Delete</a></span>
          </div>
          </td>
          <td><?php echo $data->db-table-field-2?></td>
          <td><?php echo $data->db-table-field-3?></td>
          <td><?php echo $data->db-table-field-4 ?></td>
        </tr>
        <?php
           }
        }
        else{
      ?>
        <tr><td colspan="4"><?php _e('There are no data.')?></td></tr>
        <?php
      }
        ?>
      </tbody>
    </table>
 </form>
</div> 

To this level, we have created a post like page UI and added the function to edit and delete the data from the table. To edit/update and delete the data, WordPress has a function to do that.
$wpdb->update(
$table_name,
array(
'db-field-1' =>$field-1-data,
'db-field-2' => $field-2-data,
'db-field-3' => $field-3-data
),
array( 'id' => $id ),
array(
'%s',
'%s',
'%d'
)
);
To delete the row, just data id is required and the rest is below.
$wpdb->delete($table_name,array('id'=>$id)); 

Android Expandable List View Tutorial

Expandable list view is used to group list data by categories. It has the capability of expanding and collapsing the groups when user touches header of list view. When u click on the header of list view it expands and when u again click on the same header it collapse. Like in below figures...

                         
                               Fig 1: Expanding Mode
Fig 2: Collapsing Mode

Some time we need to extend group header by default, for this
 we have following bits of code..
expandableList.expandGroup(0); //expand first position by default
expandableList.expandGroup(1); //expand second position by default

One more thing sometime we need to disable the collapsing feature in expandable list view for this we have ,
expandableList.setOnGroupClickListener(new OnGroupClickListener() {

@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
if(groupPosition==0)//disable collapsing feature of group header first position
                                   {
                                      return true;
}else{
return false;
}
}

});
In override the onGroupClick method. If true, the expandableListView thinks that the ability to expand and collapse has been handled. If false then it has not been handled, and will take care of the action. 

To generate expandable list view in project we need three layouts, one Adapter and one Main Activity.
The three layout goes like this....
1. main_activity.xml 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <ExpandableListView
        android:id="@+id/expandableList"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</LinearLayout>

2. list_group.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="10dp" >
    <TextView
        android:id="@+id/listHeader"
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft"
        android:textSize="16sp" />
</LinearLayout>

3. list_item.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="55dip"
    android:orientation="vertical" >
    <TextView
        android:id="@+id/listItem"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:textSize="17dip"
        android:paddingTop="5dp"
        android:paddingBottom="5dp"
        android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" />
</LinearLayout>

Now we have to create ExpandableListAdapter.java like this...
For import -> ctrl + alt +o  
public class ExpandableListAdapter extends BaseExpandableListAdapter {
   private Context context;
   private List<String> listDataHeader;   // header titles
   private HashMap<String, List<String>> listDataChild;

   public ExpandableListAdapter(Context context, List<String> listDataHeader,
           HashMap<String, List<String>> listChildData) {
       this.context = context;
       this.listDataHeader = listDataHeader;
       this.listDataChild = listChildData;
   }
   @Override
   public Object getChild(int groupPosition, int childPosititon) {
       return this.listDataChild.get(this.listDataHeader.get(groupPosition))
               .get(childPosititon);
   }
   @Override
   public long getChildId(int groupPosition, int childPosition) {
       return childPosition;
   }  
   @Override
   public View getChildView(int groupPosition, final int childPosition,
           boolean isLastChild, View convertView, ViewGroup parent) {
       final String childText = (String) getChild(groupPosition, childPosition);
       if (convertView == null) {
           LayoutInflater infalInflater = (LayoutInflater) this._context
                   .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           convertView = infalInflater.inflate(R.layout.list_item, null);
       }
       TextView txtListChild = (TextView) convertView
               .findViewById(R.id.listItem);
       txtListChild.setText(childText);
       return convertView;
   }
   @Override
   public int getChildrenCount(int groupPosition) {
       return this.listDataChild.get(this.listDataHeader.get(groupPosition))
               .size();
   }  
   @Override
   public Object getGroup(int groupPosition) {
       return this.listDataHeader.get(groupPosition);
   } 
   @Override
   public int getGroupCount() {
       return this.listDataHeader.size();
   } 
   @Override
   public long getGroupId(int groupPosition) {
       return groupPosition;
   } 
   @Override
   public View getGroupView(int groupPosition, boolean isExpanded,
           View convertView, ViewGroup parent) {
       String headerTitle = (String) getGroup(groupPosition);
       if (convertView == null) {
           LayoutInflater infalInflater = (LayoutInflater) this._context
                   .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
           convertView = infalInflater.inflate(R.layout.list_group, null);
       }
 
       TextView lblListHeader = (TextView) convertView
               .findViewById(R.id.listHeader);
       lblListHeader.setTypeface(null, Typeface.BOLD); //bold the header
       lblListHeader.setText(headerTitle);
 
       return convertView;
   }
 
   @Override
   public boolean hasStableIds() {
       return false;
   }
 
   @Override
   public boolean isChildSelectable(int groupPosition, int childPosition) {
       return true;
   }
}

Finally MainActivity.java goes like this...
For import ctrl + alt + o
public class MainActivity extends Activity {

ExpandableListAdapter listAdapter;
ExpandableListView expListView;
List<String> listDataHeader;
HashMap<String, List<String>> listDataChild;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get the listview
expListView = (ExpandableListView) findViewById(R.id.expandableList);
getPrepareListData(); // preparing list data
listAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
expListView.setAdapter(listAdapter); //set the  list adapter

// Listview Group click listener
expListView.setOnGroupClickListener(new OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
//do ur task
return false;
}
});

// Listview Group expanded listener
expListView.setOnGroupExpandListener(new OnGroupExpandListener() {

@Override
public void onGroupExpand(int groupPosition) {
//do ur task
}
});

// Listview Group collasped listener
expListView.setOnGroupCollapseListener(new OnGroupCollapseListener() {

@Override
public void onGroupCollapse(int groupPosition) {
//do ur task
}
});

// Listview on child click listener
expListView.setOnChildClickListener(new OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
// TODO Auto-generated method stub
//do ur task
return false;
}
});
}
private void getPrepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding header data
listDataHeader.add("For One Room");
listDataHeader.add("For Two Rooms");
listDataHeader.add("For Flat");
listDataHeader.add("For House");
listDataHeader.add("For Apartment");
// Adding child data
List<String> one_room = new ArrayList<String>();
one_room.add("1 room at baneshwor, kathmandu");
one_room.add("1 room at sundhara, kathmandu");
one_room.add("1 room at pulchowk, lalitpur");
one_room.add("1 room at gwarko, lalitpur");
one_room.add("1 room at sundhara, lalitpur");
one_room.add("1 room at balkumari, lalitpur");
one_room.add("1 room at lazimpat, kathmandu");

List<String> two_room = new ArrayList<String>();
two_room.add("2 rooms at baneshwor, kathmandu");
two_room.add("2 rooms at sundhara, kathmandu");

List<String> flat = new ArrayList<String>();
flat.add("1 flat at baneshwor, kathmandu");
flat.add("1 flat at sundhara, kathmandu");

listDataChild.put(listDataHeader.get(0), one_room); // Header, Child listDataChild.put(listDataHeader.get(1), two_room);
listDataChild.put(listDataHeader.get(2), flat); //you can add others here
}
}

 

© 2013 Echo "Semicolon Developers"; Kathmandu. All rights resevered @ Semicolon Developers Network Pvt. Ltd.. Designed by Templateism

Back To Top