Lets start with the layouts. We need two of them here one for the main activity where the listview is populated and another for the web view activity where the page corresponding to the title will be displayed.
activity_main.xml
<RelativeLayout 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"
tools:context=".MainActivity" >
<ListView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/listView"/>
</RelativeLayout>
web_view.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<WebView
android:id="@+id/webview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
We will have two activities corresponding these two layouts and a jsonparser class.
MainActivity.java
package com.peshal.jsonfeedtest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.client.ClientProtocolException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.app.Activity;
import android.content.Intent;
public class MainActivity extends Activity {
ListView lv;
JSONArray items;
JSONObject jsonObject;
List<String> titleCollection = new ArrayList<String>();
List<String> urlCollection = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.listView);
new NetworkOperation().execute();
lv.setOnItemClickListener(new OnItemClickListener(){
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
String photoUrl = urlCollection.get(arg2);
Intent webViewIntent = new Intent(MainActivity.this, WebViewActivity.class);
webViewIntent.putExtra("url", photoUrl);
startActivity(webViewIntent);
}
});
}
public void loadContents() {
ArrayAdapter<String> adapter =new ArrayAdapter<String>(getBaseContext(), android.R.layout.simple_list_item_1,titleCollection);
lv.setAdapter(adapter);
}
public class NetworkOperation extends AsyncTask<Void, Void, Void> {
@Override
protected Void doInBackground(Void... arg0) {
JsonParser parser = new JsonParser();
try {
String result = parser.getHttpConnection();
String removedString = result.trim().substring(15, result.trim().length()-1);
JSONObject jsonObject = new JSONObject(removedString);
items = jsonObject.getJSONArray("items");
for (int i = 0; i<items.length(); i++) {
jsonObject = items.getJSONObject(i);
titleCollection.add(jsonObject.getString("title"));
urlCollection.add(jsonObject.getString("link"));
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
loadContents();
super.onPostExecute(result);
}
}
}
NetworkOperation class is used for Asynchronous data loading as android doesnot allow network operations in main thread starting android 2.3 gingerbread. AsyncTask invokes the onPostExecute() method
when the background task is complete. This is when we will populateour listviews. As you can see in this method we redirect to loadContents() method where we populate our listview.
JsonParser.java
package com.peshal.jsonfeedtest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONObject;
public class JsonParser {
BufferedReader in = null;
JSONObject jsonObject=null;
String result="";
public String getHttpConnection() throws ClientProtocolException, IOException {
HttpClient httpClient = new DefaultHttpClient();
HttpGet request = new HttpGet("http://www.flickr.com/services/feeds/photos_public.gne?tags=punctuation,atsign&format=json");
HttpResponse response = httpClient.execute(request);
in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
StringBuffer sb = new StringBuffer("");
String line="";
String lineSeparator=System.getProperty("line.separator");
while ((line=in.readLine())!=null) {
sb.append(line + lineSeparator);
}
in.close();
result = sb.toString();
try{
jsonObject = new JSONObject(result);
}
catch(Exception e) {
}
return result;
}
}
This class is mainly responsible for making a HTTP GET request to the url where the json feed is located and loading the contents from the page to a string buffer and returns the string. This string is parsed to ArrayList in the doInBackground method of AsyncTask from the MainActivity class. One more note here, the json feed contains some unwanted information which are removed using the substring method.
WebViewActivity
package com.peshal.jsonfeedtest;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnKeyListener;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.app.Activity;
public class WebViewActivity extends Activity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.web_view);
webView = (WebView)findViewById(R.id.webview);
webView.setWebViewClient(new WebViewClient());
String url=getIntent().getExtras().getString("url");
webView.canGoBack();
webView.loadUrl(url);
webView.setOnKeyListener(new OnKeyListener() {
@Override
public boolean onKey(View arg0, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && webView.canGoBack()) {
webView.goBack();
return true;
}
else {
return false;
}
}
});
}
}
This activity is responsible to load the url corresponding to the title into the web view. The url is passed from MainActivity using Intent.putExtra method. The parameters passed is retrieved in this activity using getIntent().getExtras().getString() method.
Dont forget to add Internet permission in the manifest since we are using the HTTP request as well as webview. Complete source code is available here.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.INTERNET" />