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