Monday, November 16, 2015

Words- Characters Counter Android Demo



Description:

It is very easy to handle words and characters counter for your application. If you are developing an app which uses EditText, It is very important to give feature like word counter / Character counter within the app. Here is the full demo code which helps you.

First add below code to your activity_main.xml file.


activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fab="http://schemas.android.com/apk/res-auto"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:layout_weight="0.4"
    android:orientation="vertical"
    android:paddingLeft="5dip"
    android:paddingRight="5dip" >

    <RelativeLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="10dp"
        android:paddingBottom="10dp" >

        <TextView
            android:id="@+id/tvCharWatcher"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_centerInParent="true"
            android:textSize="22dp"
            android:text="Characters:" />

        <TextView
            android:id="@+id/tvWordWatcher"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_centerInParent="true"
            android:textSize="22dp"
            android:text="Words:" />
    </RelativeLayout>

    <EditText
        android:id="@+id/note"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:autoText="false"
        android:background="@android:color/white"
        android:capitalize="none"
        android:ems="10"
        android:fadingEdge="none"
        android:gravity="top"
        android:scrollbars="vertical|horizontal"
        android:textColor="@android:color/black"
        android:textSize="22dp" >

        <requestFocus />
    </EditText>

</LinearLayout>


Your layout is ready, now you need to register components to MainActivity.java file and add below code step by step:

1. Create method init() to initialize needful variables,components etc.
2. TextWatcher class handles your EditText and it will call with every text you add.
3. WordCount() custom method counts words and return number of words.

Here, is the full code of MainActivity.java file

MainActivity.java

import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

EditText etText;
TextView tvWordWatcher, tvCharWatcher;

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

init();
}

private void init() {

etText = (EditText) findViewById(R.id.note);
etText.setVerticalScrollBarEnabled(true);
etText.requestFocus();

tvCharWatcher = (TextView) findViewById(R.id.tvCharWatcher);
tvWordWatcher = (TextView) findViewById(R.id.tvWordWatcher);
tvCharWatcher.setText("Characters:0");
tvWordWatcher.setText("Words:0");

etText.addTextChangedListener(textWatcher);
}

TextWatcher textWatcher = new TextWatcher() {

@Override
public void onTextChanged(CharSequence s, int start, int before,
int count) {
tvCharWatcher.setText("Characters:"
+ String.valueOf(s.length()));
tvWordWatcher.setText("Words:" + wordcount(s.toString()));
}

@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {

}

@Override
public void afterTextChanged(Editable s) {

}
};

public static long wordcount(String line) {
long numWords = 0;
int index = 0;
boolean prevWhiteSpace = true;
while (index < line.length()) {
char c = line.charAt(index++);
boolean currWhiteSpace = Character.isWhitespace(c);
if (prevWhiteSpace && !currWhiteSpace) {
numWords++;
}
prevWhiteSpace = currWhiteSpace;
}
return numWords;
}
}


Download Full Source Code: GitHub


Tuesday, July 28, 2015

How do I generate GUID / UUID in android

GUID / UUID (Globally / Universally Unique Identifier) is frequently used in programming. There are many use of these UUID / GUID like, creating random file name, application id, unique id to store in database etc.

To generate UUID, Firstly we need to import java.util.UUID class in Activity class file. This class is introduced in JDK 1.5 version. You can use randomUUID() method to generate UUID. Here is the example of code. Take a look:

UUID uuid = UUID.randomUUID();
String randomUUIDString = uuid.toString();

Log.v("Random UUID",randomUUIDString);
Log.v("UUID Version",uuid.version());
Log.v("UUID Varient",uuid.variant());


Code Explanation: 

First, We have created one uuid object and get random uuid. Its data type is also UUID. In next line of code, We have converted uuid into string format and stored in randomUUIDString object. Logs are displayed uuid,version and it's varient.

Output:

Random UUID   7dc53df5-703e-49b3-8670-b1c468f47f1f
UUID version     4
UUID variant      2


NOTE: UUID is randomly generated String so, It is not expected to get result same as above.



Tuesday, July 14, 2015

Android Reverse Geocoding using Geocoder at touched location in Google Map



Download Code



This tutorial is for plot address on Google map. You can get location in 2 different way, You can directly type address on TextField and get it's location on map OR you can press and hold on Google map and get it's physical address.

Here, is the full tutorial for both methods. It is possible with Geocoder class of Google Map. I have described step by step below:

1. Create project named "FindAddressGoogleMap" or something else, whatever you want.
2. Create android API Key for your application's package name. If you don't know how to create Google API key, Refer, http://developerandro.blogspot.in/2015/07/google-maps-v2-integration-in-android.html . It gives you full desciption, How to create Google Map API for Android and it's usage.
3. Copy below code in your project.


AndroidMenifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="demo.findaddress.com.findaddressdemo" >
 
  <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <!--
 The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but are recommended.
    -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="@string/google_maps_key" />
        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>


activity_map.xml (Layout File)


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="horizontal"
        android:padding="2dp" >

        <EditText
            android:id="@+id/etAddress"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="left|top"
            android:hint="Address"
            android:lines="4"
            android:padding="10dp"
            android:textSize="20dp" />


        <ImageButton
            android:id="@+id/btnSearch"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:gravity="center"
            android:padding="15dp"
            android:paddingLeft="5dp"
            android:paddingRight="5dp"
            android:scaleType="fitCenter"
            android:src="@android:drawable/ic_menu_search" />

        <ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:visibility="gone" />
    </LinearLayout>

    <fragment
        android:id="@+id/map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

</LinearLayout>


  • Create new Java class file and Name it "GeocodeJSONParser". Copy below code in this file:

GeocodeJSONParser.java


public class GeocodeJSONParser {

/** Receives a JSONObject and returns a list */
    public List<HashMap<String,String>> parse(JSONObject jObject){
        JSONArray jPlaces = null;
        try {
            /** Retrieves all the elements in the 'places' array */
            jPlaces = jObject.getJSONArray("results");
        } catch (JSONException e) {
            e.printStackTrace();
        }
        /** Invoking getPlaces with the array of json object
        * where each json object represent a place
        */
        return getPlaces(jPlaces);
    }
    private List<HashMap<String, String>> getPlaces(JSONArray jPlaces){
        int placesCount = jPlaces.length();
        List<HashMap<String, String>> placesList = new ArrayList<HashMap<String,String>>();
        HashMap<String, String> place = null;
        /** Taking each place, parses and adds to list object */
        for(int i=0; i<placesCount;i++){
            try {
                /** Call getPlace with place JSON object to parse the place */
                place = getPlace((JSONObject)jPlaces.get(i));
                placesList.add(place);
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }
        return placesList;
    }
    /** Parsing the Place JSON object */
    private HashMap<String, String> getPlace(JSONObject jPlace){
        HashMap<String, String> place = new HashMap<String, String>();
        String formatted_address = "-NA-";
        String lat="";
        String lng="";
        try {
            // Extracting formatted address, if available
            if(!jPlace.isNull("formatted_address")){
                formatted_address = jPlace.getString("formatted_address");
            }
            lat = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
            lng = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
            place.put("formatted_address", formatted_address);
            place.put("lat", lat);
            place.put("lng", lng);
        }catch (JSONException e) {
            e.printStackTrace();
        }
        return place;
    }
}

MapsActivity.java

public class MapsActivity extends FragmentActivity {

    private GoogleMap mMap; 

    EditText etAddress;
    ImageButton ibSearch;
    LatLng latLng;
    ProgressDialog progDailog;
    ProgressBar progressBar;

    Double latitude, longitude;
    MarkerOptions markerOptions;

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

        etAddress = (EditText) findViewById(R.id.etAddress);
        ibSearch = (ImageButton) findViewById(R.id.btnSearch);
        progressBar = (ProgressBar) findViewById(R.id.progressBar);

        ibSearch.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                String location = etAddress.getText().toString();

                if (location == null || location.equals("")) {
                    Toast.makeText(MapsActivity.this, "No place found",
                            Toast.LENGTH_SHORT).show();
                    setProgress(false);
                    return;
                }
                locationOnMap(location);
            }
        });

        mMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
            public void onMapLongClick(LatLng latLng) {
                mMap.clear();
                latitude = latLng.latitude;
                longitude = latLng.longitude;

                mMap.animateCamera(CameraUpdateFactory
                        .newLatLng(latLng));
                markerOptions = new MarkerOptions();
                markerOptions.position(latLng);
                mMap.addMarker(markerOptions);

                //---------------
                try {
                    Geocoder geocoder;
                    List<Address> addresses;
                    geocoder = new Geocoder(MapsActivity.this, Locale.getDefault());

                    addresses = geocoder.getFromLocation(latitude, longitude, 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5

                    String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
                    String city = addresses.get(0).getLocality();
                    String state = addresses.get(0).getAdminArea();
                    String country = addresses.get(0).getCountryName();
                    String postalCode = addresses.get(0).getPostalCode();
                    String knownName = addresses.get(0).getFeatureName();

                    etAddress.setText(address + "\n" + city + "\n" + state + "\n" + country +
                            "\n" + postalCode + "\n" + knownName);

                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(MapsActivity.this, "Error:" + e.getMessage(), Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }
    private void setUpMapIfNeeded() {
        // Do a null check to confirm that we have not already instantiated the map.
        if (mMap == null) {
            // Try to obtain the map from the SupportMapFragment.
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            // Check if we were successful in obtaining the map.
            if (mMap != null) {
                setUpMap();
            }
        }
    }

    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
    }

    private void locationOnMap(String location) {
        String url = "https://maps.googleapis.com/maps/api/geocode/json?";
        setProgress(true);
        try {
          location = URLEncoder.encode(location, "utf-8");
        } catch (UnsupportedEncodingException e) {
            setProgress(false);
            e.printStackTrace();
        }
   String address = "address=" + location;
    String sensor = "sensor=false";

        url = url + address + "&" + sensor;
 DownloadTask downloadTask = new DownloadTask();
 downloadTask.execute(url);
    }

    private class DownloadTask extends AsyncTask<String, Integer, String> {
        String data = null;
        @Override
        protected String doInBackground(String... url) {
            try {
                data = downloadUrl(url[0]);
            } catch (Exception e) {
                setProgress(false);
            }
            return data;
        }
        @Override
        protected void onPostExecute(String result) {
        ParserTask parserTask = new ParserTask();
            parserTask.execute(result);
        }
    }

    private String downloadUrl(String strUrl) throws IOException {
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(strUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            urlConnection.connect();
            iStream = urlConnection.getInputStream();
            BufferedReader br = new BufferedReader(new InputStreamReader(
                    iStream));
            StringBuffer sb = new StringBuffer();
            String line = "";
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            data = sb.toString();
            br.close();

        } catch (Exception e) {
            Log.d("Exception while downloading url", e.toString());
        } finally {
            setProgress(false);
            iStream.close();
            urlConnection.disconnect();
        }

        return data;
    }

     class ParserTask extends
            AsyncTask<String, Integer, List<HashMap<String, String>>> {

        JSONObject jObject;
   @Override
        protected List<HashMap<String, String>> doInBackground(
                String... jsonData) {

            List<HashMap<String, String>> places = null;
            GeocodeJSONParser parser = new GeocodeJSONParser();

            try {
                jObject = new JSONObject(jsonData[0]);
       places = parser.parse(jObject);

            } catch (Exception e) {
                setProgress(false);
                Log.d("Exception", e.toString());
            }
            return places;
        }
   @Override
        protected void onPostExecute(List<HashMap<String, String>> list) {

            // Clears all the existing markers
            mMap.clear();
            setProgress(false);
            for (int i = 0; i < list.size(); i++) {
                if (i == 0) {
                    HashMap<String, String> hmPlace = list.get(i);
                    double lat = Double.parseDouble(hmPlace.get("lat"));
                    double lng = Double.parseDouble(hmPlace.get("lng"));
                    String name = hmPlace.get("formatted_address");
                    plotMarker(lat, lng, name);
                    break;
                }
            }
        }
    }

    private void plotMarker(double lati, double longi, String name) {
        MarkerOptions markerOptions = new MarkerOptions();
        LatLng latLng = new LatLng(lati, longi);
        markerOptions.position(latLng);
        markerOptions.title(name);
        mMap.addMarker(markerOptions);
        // googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
        mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 12f));
        latitude = lati;
        longitude = longi;
    }

    private void setProgress(final boolean bol) {

        runOnUiThread(new Runnable() {

            @Override
            public void run() {
                if (bol) {
                    ibSearch.setVisibility(View.GONE);
                    progressBar.setVisibility(View.VISIBLE);
                    etAddress.setEnabled(false);
                } else {
                    ibSearch.setVisibility(View.VISIBLE);
                    progressBar.setVisibility(View.GONE);
                    etAddress.setEnabled(true);
                }
            }
        });
    }
}

  • Done ! Now run project an you should get output as above screenshots.

Download Code




Friday, July 10, 2015

Google Maps V2 Integration In Android



Download Code



For beginners, It is headache to integrate Google map on their android app. You can find many post regarding Google map and of course at the one point you will confused and try to pull your hair ;)

Here, is the full step by step tutorial to integrate Google maps in your android app. Take a look.

1. Integrate "google_play_services_lib" to your project if you are using Eclipse or You can select "Google Maps Activity" on create project in Android Studio.

2. After creating project, You need to fetch SHA key for your system. It is unique and will use to generate Google Hash Key. Most of the people do mistake in this point but trust me, It is very simple. I have give steps with screenshots.

3. For SHA1:

  • If you are using Eclipse you can get it from below Path:

Windows > Preferences > Android > Build
  • OR  With Command Prompt:
Go To JDK path in command Prompt and hit following code as displayed in screenshot.

"keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android "



4. Now you have your SHA key, You need to use it for generating new Google Hash Key.

  • Create New project named "Google Map Demo". After successfully project creation, Go to : APIs & Outh > APIs You will see screen as like below screenshot.


  • Enable "Google Maps Android API":


  • Now, Go to Credentials and Click on "Create New Key" button:

  • Click "Android Key", add SHA1;PACKAGE_NAME in below dialog and hit Create:
Like, 12:34:56:78:90:12:34:56:78:90:A3:16:65:0B:F0:6B:F4:EC:2B:83;demo.map.com.googlemapdemo




  • You will see your Key for Android Application:


This Key will use in your project. Lets, hit it and make project with this key.

Project (Google Map Demo)


Here is the file wise code which you can use:

  • AndroidMenifest.xml (Paste Key which you generated above to "GOOGLE_MAP_KEY")


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="demo.map.com.googlemapdemo" >

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
    <!--
 The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but are recommended.
    -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="GOOGLE_MAP_KEY" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

  • activity_maps.xml

<fragment 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:id="@+id/map" tools:context=".MapsActivity"
    android:name="com.google.android.gms.maps.SupportMapFragment" />

  • MapsActivity.Java

import android.support.v4.app.FragmentActivity;
import android.os.Bundle;
import android.util.Log;

import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity {

    private GoogleMap mMap; 

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

    @Override
    protected void onResume() {
        super.onResume();
        setUpMapIfNeeded();
    }

    private void setUpMapIfNeeded() {
        if (mMap == null) {
            mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
                    .getMap();
            if (mMap != null) {
                setUpMap();
            }
        }
    }
  
    private void setUpMap() {
        mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("0,0"));
    }
}



Done, Now You can run project and get the output as shown first image of Post. 


Download Code





Friday, September 5, 2014

3 Level Expandable ListView in android


Download Source Code


Source Code


MainActivity.java


import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.dow.lvlexplist.Product.SubCategory;
import com.dow.lvlexplist.Product.SubCategory.ItemList;
public class MainActivity extends ActionBarActivity {
private ArrayList<Product>pProductArrayList;
private ArrayList<SubCategory>pSubItemArrayList1,pSubItemArrayList2;
//private ArrayList<SubCategory>pSubItemArrayList2;
private LinearLayout mLinearListView;
boolean isFirstViewClick=false;
boolean isSecondViewClick=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mLinearListView = (LinearLayout) findViewById(R.id.linear_listview);
ArrayList<ItemList> mItemListArray=new ArrayList<ItemList>();
mItemListArray.add(new ItemList("State 1", "20"));
mItemListArray.add(new ItemList("State 2", "50"));
mItemListArray.add(new ItemList("State 3", "20"));
mItemListArray.add(new ItemList("State 4", "50"));
ArrayList<ItemList> mItemListArray2=new ArrayList<ItemList>();
mItemListArray2.add(new ItemList("Price 1", "$500"));
mItemListArray2.add(new ItemList("Price 2", "$400"));
mItemListArray2.add(new ItemList("Price 3", "$200"));
mItemListArray2.add(new ItemList("Price 4", "$100"));
pSubItemArrayList1=new ArrayList<SubCategory>();
pSubItemArrayList1.add(new SubCategory("India", mItemListArray));
pSubItemArrayList1.add(new SubCategory("US", mItemListArray));
pSubItemArrayList1.add(new SubCategory("London", mItemListArray));
pSubItemArrayList2=new ArrayList<SubCategory>();
pSubItemArrayList2.add(new SubCategory("Android", mItemListArray2));
pSubItemArrayList2.add(new SubCategory("Apple", mItemListArray2));
pSubItemArrayList2.add(new SubCategory("Windows", mItemListArray2));
pProductArrayList=new ArrayList<Product>();
pProductArrayList.add(new Product("Country", pSubItemArrayList1));
pProductArrayList.add(new Product("Mobile", pSubItemArrayList2));
//pProductArrayList.add(new Product("Garments", pSubItemArrayList2));
/***
* adding item into listview
*/
for (int i = 0; i < pProductArrayList.size(); i++) {
LayoutInflater inflater = null;
inflater = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View mLinearView = inflater.inflate(R.layout.row_first, null);
final TextView mProductName = (TextView) mLinearView.findViewById(R.id.textViewName);
final RelativeLayout mLinearFirstArrow=(RelativeLayout)mLinearView.findViewById(R.id.linearFirst);
final ImageView mImageArrowFirst=(ImageView)mLinearView.findViewById(R.id.imageFirstArrow);
final LinearLayout mLinearScrollSecond=(LinearLayout)mLinearView.findViewById(R.id.linear_scroll);
if(isFirstViewClick==false){
mLinearScrollSecond.setVisibility(View.GONE);
mImageArrowFirst.setBackgroundResource(R.drawable.arw_lt);
}
else{
mLinearScrollSecond.setVisibility(View.VISIBLE);
mImageArrowFirst.setBackgroundResource(R.drawable.arw_down);
}
mLinearFirstArrow.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(isFirstViewClick==false){
isFirstViewClick=true;
mImageArrowFirst.setBackgroundResource(R.drawable.arw_down);
mLinearScrollSecond.setVisibility(View.VISIBLE);
}else{
isFirstViewClick=false;
mImageArrowFirst.setBackgroundResource(R.drawable.arw_lt);
mLinearScrollSecond.setVisibility(View.GONE); }
return false;
}
});
final String name = pProductArrayList.get(i).getpName();
mProductName.setText(name);
 
/**
*
*/
   for (int j = 0; j < pProductArrayList.get(i).getmSubCategoryList().size(); j++) {
LayoutInflater inflater2 = null;
inflater2 = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View mLinearView2 = inflater2.inflate(R.layout.row_second, null);
 
TextView mSubItemName = (TextView) mLinearView2.findViewById(R.id.textViewTitle);
final RelativeLayout mLinearSecondArrow=(RelativeLayout)mLinearView2.findViewById(R.id.linearSecond);
final ImageView mImageArrowSecond=(ImageView)mLinearView2.findViewById(R.id.imageSecondArrow);
final LinearLayout mLinearScrollThird=(LinearLayout)mLinearView2.findViewById(R.id.linear_scroll_third);
if(isSecondViewClick==false){
mLinearScrollThird.setVisibility(View.GONE);
mImageArrowSecond.setBackgroundResource(R.drawable.arw_lt);
}
else{
mLinearScrollThird.setVisibility(View.VISIBLE);
mImageArrowSecond.setBackgroundResource(R.drawable.arw_down);
}
mLinearSecondArrow.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if(isSecondViewClick==false){
isSecondViewClick=true;
mImageArrowSecond.setBackgroundResource(R.drawable.arw_down);
mLinearScrollThird.setVisibility(View.VISIBLE);
}else{
isSecondViewClick=false;
mImageArrowSecond.setBackgroundResource(R.drawable.arw_lt);
mLinearScrollThird.setVisibility(View.GONE); }
return false;
}
});
final String catName = pProductArrayList.get(i).getmSubCategoryList().get(j).getpSubCatName();
mSubItemName.setText(catName);
/**
*
*/
 for (int k = 0; k < pProductArrayList.get(i).getmSubCategoryList().get(j).getmItemListArray().size(); k++) {
LayoutInflater inflater3 = null;
inflater3 = (LayoutInflater) getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View mLinearView3 = inflater3.inflate(R.layout.row_third, null);
 
TextView mItemName = (TextView) mLinearView3.findViewById(R.id.textViewItemName);
TextView mItemPrice = (TextView) mLinearView3.findViewById(R.id.textViewItemPrice);
final String itemName = pProductArrayList.get(i).getmSubCategoryList().get(j).getmItemListArray().get(k).getItemName();
final String itemPrice = pProductArrayList.get(i).getmSubCategoryList().get(j).getmItemListArray().get(k).getItemPrice();
mItemName.setText(itemName);
mItemPrice.setText(itemPrice);
mLinearView3.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Toast.makeText(getApplicationContext(),"Name:"+itemName+"\nID:"+itemPrice,Toast.LENGTH_LONG).show();
}
});
mLinearScrollThird.addView(mLinearView3);
 }
mLinearScrollSecond.addView(mLinearView2);
 
   }
 
   mLinearListView.addView(mLinearView);
} }
}

Product.java


import java.util.ArrayList;

public class Product {

private String pName;

private ArrayList<SubCategory> mSubCategoryList;

public Product(String pName, ArrayList<SubCategory> mSubCategoryList) {
super();
this.pName = pName;
this.mSubCategoryList = mSubCategoryList;
}

public String getpName() {
return pName;
}

public void setpName(String pName) {
this.pName = pName;
}

public ArrayList<SubCategory> getmSubCategoryList() {
return mSubCategoryList;
}

public void setmSubCategoryList(ArrayList<SubCategory> mSubCategoryList) {
this.mSubCategoryList = mSubCategoryList;
}

public static class SubCategory {

private String pSubCatName;
private ArrayList<ItemList> mItemListArray;

public SubCategory(String pSubCatName,
ArrayList<ItemList> mItemListArray) {
super();
this.pSubCatName = pSubCatName;
this.mItemListArray = mItemListArray;
}

public String getpSubCatName() {
return pSubCatName;
}

public void setpSubCatName(String pSubCatName) {
this.pSubCatName = pSubCatName;
}

public ArrayList<ItemList> getmItemListArray() {
return mItemListArray;
}

public void setmItemListArray(ArrayList<ItemList> mItemListArray) {
this.mItemListArray = mItemListArray;
}

public static class ItemList {

private String itemName;
private String itemPrice;

public ItemList(String itemName, String itemPrice) {
super();
this.itemName = itemName;
this.itemPrice = itemPrice;
}

public String getItemName() {
return itemName;
}

public void setItemName(String itemName) {
this.itemName = itemName;
}

public String getItemPrice() {
return itemPrice;
}

public void setItemPrice(String itemPrice) {
this.itemPrice = itemPrice;
}

}

}
}

activity_main.xml


<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:id="@+id/linear_listview"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical" />

</ScrollView>


row_first.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/linearFirst"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:padding="15dp" >

        <TextView
            android:id="@+id/textViewName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:text="TextView"
            android:textStyle="bold"
            android:textColor="@color/theme_color"
            android:textSize="17dp" />

        <ImageView
            android:id="@+id/imageFirstArrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="5dp" />
    </RelativeLayout>

     <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/theme_color" />
     
    <LinearLayout
        android:id="@+id/linear_scroll"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:background="@android:color/white"
        android:orientation="vertical" />

</LinearLayout>


row_second.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/white"
    android:orientation="vertical" >

    <RelativeLayout
        android:id="@+id/linearSecond"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@android:color/white"
        android:padding="15dp" >

        <TextView
            android:id="@+id/textViewTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_marginLeft="10dp"
            android:text="TextView"
            android:textColor="#EC5B00"
            android:textStyle="bold"
            android:textSize="17dp" />

        <ImageView
            android:id="@+id/imageSecondArrow"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true"
            android:layout_marginRight="5dp" />
    </RelativeLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/theme_color" />
    
    <LinearLayout
        android:id="@+id/linear_scroll_third"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:background="@android:color/white"
        android:orientation="vertical" />
</LinearLayout>


row_third.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@android:color/white"
    android:orientation="vertical" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/white"
        android:orientation="horizontal"
        android:padding="15dp" >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/background_light"
            android:text="@string/right_arrow"
            android:textColor="@color/theme_color"
            android:layout_marginRight="5dp"
            android:textSize="17dp" />

        <TextView
            android:id="@+id/textViewItemName"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/background_light"
            android:text="TextView"
            android:layout_weight="1"
            android:textColor="@color/theme_color"
            android:textSize="17dp" />

        <TextView
            android:id="@+id/textViewItemPrice"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@android:color/background_light"
            android:text="TextView"
            android:textColor="@android:color/black"
            android:textSize="17dp" />
    </LinearLayout>

    <View
        android:layout_width="match_parent"
        android:layout_height="1dp"
        android:background="@color/theme_color" />

</LinearLayout>


strings.xml


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

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

    <string name="right_arrow">&#9654;</string>
    <color name="theme_color">#016299</color>
</resources>


NOTE: You may get error if you don't add image for arw_down.png and arw_lt.png file in drawable folder.


Download Source Code