Sunday, 24 March 2013

Example On ListActivity With showing twits from twitter by using JSON

Hello Friends Today, I'l share my few knowledge about android & its concepts.

Today , i am gonna tell how to use ListActivity, JSON data, AQuery in android app.So,lets get started

As i told you above ,ListActivity..... as it name suggest above.. it shows all your data in list view manner... but question is how data is come to u .. so we need to specify adapter for your list.. as it way... it manages data.in user screen. 




* What is JSON Data ?
JSON (JavaScript Object Notation) is an independent data exchange format. It is limited to text and numeric values. Binary values are not supported.
                      JSON is a subset of the JavaScript Specification (ECME-Script) and it is therefore directly supported in JavaScript.
Data structures in JSON are based on key / value pairs. The key is a string, the value can be a numerical value, a boolean value (true or false) or an object.
                    An JSON object is a set of key / value pairs which starts with "{" and ends with "}".
example----
{
 firstName:'Sushant',
 lastName:'Patekar',
 address: {
   Street:'Achole Street.',
   number: '304'
 }
} 
How To View Json Data------- 
if you want view json data from url......... just put that link on any browser ,
here we have link is.. for our app..

http://search.twitter.com/search.json?q=@Android

collect data. & put it data.... on the free space of these link

then,click on Format & You will get availible your json data




Here, we trying to fetch posts of different user relates to "Android" on twitter.
its simple.
while playing with ListActivity, you have to take care of these below things,

>> extends Your class with ListActivity(--------not With Activity------------)

                             * as we know now,when we extending our activity we need to set desirable view as layout in OnCreate()... by using setContentView(R.layout.main).
            but, in ListActivity we need Adapter.. for specifying lookup of your ListActivity. 
   where,Adapter is use for different types with different purpose in android app. here we use arrayadapter to design our row for list.that will be done by simple layout .xml file.

                               * Difference between ListView & ListActivity... 
                   ListView is UI componet which will added layout .xml files. we have to spcify id for it in xml file . & then in .java class ,


                     ListView myListView=(ListView) findViewById(R.id.listview1);
                     myListView.setAdapter(myNewAdapter);

          But, in ListView code will just Simply changes as,
 extends your class with ListActivity
 create adapter for (row) for it... & then 

                          setListAdapter(myNewAdapter);

>> create An .xml file which will specifying view for adapter.. 
here, i am supposed to show user profile pic, with his name & his tweet.. so i need one imageview, & two textview ,so my .xml will look like .......

------------------------list_item.xml------------------------------------


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="left|center"
    android:paddingBottom="5px"
    android:paddingLeft="5px"
    android:paddingTop="5px" >

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="0dip"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="15dp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10px"
            android:textColor="#0099CC" />

        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" >
        </TextView>
    </LinearLayout>

</LinearLayout>


& now our layout is ready... but have you know that we wil going to play with lots of data ... here, i mean.. we will fetching each users tweet.. with his name,& profile-pic via.. Internet... so if we write code for it .. onCreate() ... so our app will crash ...  so for make it comfort we will all these stuff from background thread by using AsyncTask<> . AsyncTask is use to perform background task along ur app & onCreate method.. without disturbing it.
so..untill,its clear that.. will pulling data by using AsyncTask & put in on List by using ArrayAdapter... but.. while pulling tweets,& user name.. we will not having issue... but at the time of pulling image.. over Internet.. it causes time consuming.. & which results rough scrolling appearance.. for list items.
to avoid it, we use Aquery....


What is Aquery?
Android-Query (AQuery) is a light-weight library for doing asynchronous tasks and manipulating UI elements in Android. its simple to use it.. just download these library ,from here, & add it as library to your project.


>> Inside Class  we will using AsyncTask & then pulling data using JSON. 



so our full code will look like as below,

----------------------------- Twits.java---------------------------------



package com.examples.Twits;

import java.net.URI;
import java.net.URL;
import java.util.ArrayList;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.SystemClock;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;

import com.androidquery.AQuery;
import com.examples.Twits.Twits.myAsyncs.CustomAdapter;

public class Twits extends ListActivity {
HttpClient client;
ListView listview;
String widget_data, profile_Img_url;
ArrayList<TwitsModel> listItems;
ProgressDialog progressDialog;
ImageView img;
JSONObject newJsonObject;
JSONObject jsonObject;
TextView username, message, time;
ImageView image;
AQuery aq;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
aq = new AQuery(this);

new myAsyncs().execute();

// TODO Auto-generated method stub

}

public class myAsyncs extends AsyncTask<String, Integer, ArrayList<TwitsModel>> {
int progress_status;

@Override
protected void onPreExecute() {

super.onPreExecute();
progressDialog = new ProgressDialog(Twits.this);
progressDialog.setCancelable(true);
progressDialog.setMessage("Loading...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setMax(100);
progressDialog.show();
progress_status = 0;

}

@Override
protected ArrayList<TwitsModel> doInBackground(String... params) {

listItems = new ArrayList<TwitsModel>();
client = new DefaultHttpClient();
while (progress_status < 100) {

progress_status += 1;

publishProgress(progress_status);

}
try {

URI website1 = new URI("http://search.twitter.com/search.json?q=@Android");
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(website1);
HttpResponse response = client.execute(request);
HttpEntity entity = response.getEntity();
String str = EntityUtils.toString(entity);
newJsonObject = new JSONObject(str);
try {

JSONArray JsonArrayForResult = newJsonObject.getJSONArray("results");

for (int i = 0; i < JsonArrayForResult.length(); i++) {
jsonObject = JsonArrayForResult.getJSONObject(i);
listItems.add(new TwitsModel(jsonObject));

}

} catch (JSONException e) {
e.printStackTrace();
}
} catch (Exception e) {
Log.e("log_tag", "Error in http connection: " + e.toString());
}

return listItems;

}

@Override
protected void onPostExecute(ArrayList<TwitsModel> result) {

super.onPostExecute(result);
Message message = new Message();
handler.sendMessage(message);

}

private Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {

super.handleMessage(msg);
CustomAdapter myAdapter = new CustomAdapter(getApplicationContext(), R.layout.list_item, listItems);
setListAdapter(myAdapter);
progressDialog.dismiss();
myAdapter.setNotifyOnChange(true);
}
};

class CustomAdapter extends ArrayAdapter<TwitsModel> {

ArrayList<TwitsModel> C_list;

public CustomAdapter(Context context, int textViewResourceId, ArrayList<TwitsModel> tweets) {
super(context, textViewResourceId, tweets);
this.C_list = tweets;
}

public View getView(int position, View convertView, ViewGroup parent) {

View v = convertView;
aq = new AQuery(v);
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.list_item, null);
username = (TextView) v.findViewById(R.id.username);
message = (TextView) v.findViewById(R.id.message);
image = (ImageView) v.findViewById(R.id.avatar);
time = (TextView) v.findViewById(R.id.time);

}
TwitsModel tweet = C_list.get(position);

if (tweet != null) {

if (username != null) {
username.setText(tweet.name);
}

if (message != null) {
message.setText(tweet.twit);
}
aq.recycle(v);
aq.id(R.id.avatar).image(tweet.imageUrl, false, true);

if (time != null) {
time.setText(tweet.time1);
}

}

return v;
// end of getView

}

}

@Override
protected void onCancelled() {

super.onCancelled();
}

@Override
protected void onProgressUpdate(Integer... values) {

super.onProgressUpdate(values);
progressDialog.setProgress(values[0]);
}

}
}


------------------------------------------------------------------------------------------

we require one class here for fetching JSON data ,which willl be like as,

-------------------------------------TwitsModel.java------------------------------

package com.examples.Twits;

import java.util.Date;
import org.json.JSONException;
import org.json.JSONObject;

public class TwitsModel {

public String name;
public String imageUrl;
public String twit;
public String time, time1;
Date date;

public TwitsModel(JSONObject jObject) {

try {
name = jObject.getString("from_user");
time = jObject.getString("created_at");
twit = jObject.getString("text");
imageUrl = jObject.getString("profile_image_url");
}
catch (JSONException e) {
e.printStackTrace();
}

}
}

----------------------------------------------------------------------------------------

& inside  list_item.xml 




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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:gravity="left|center"
    android:paddingBottom="5px"
    android:paddingLeft="5px"
    android:paddingTop="5px" >

    <ImageView
        android:id="@+id/avatar"
        android:layout_width="wrap_content"
        android:layout_height="fill_parent"
        android:layout_marginRight="6dip"
        android:src="@drawable/ic_launcher" />

    <LinearLayout
        android:layout_width="0dip"
        android:layout_height="fill_parent"
        android:layout_weight="1"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/username"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:textSize="15dp"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/message"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="10px"
            android:textColor="#0099CC" />

        <TextView
            android:id="@+id/time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="" >
        </TextView>
    </LinearLayout>

</LinearLayout>



------------------------------------------------------------------------------------------

& inside AndroidManifest.xml file,
 Specifey Internet permission ....................like ,


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

---------------------------------------------------------------------------------------

& Your code is now ready to compile.............& hit on Run Application,
output will look like...........




fig - AsyncTask 


fig-Twits in List


Finally,Happy Coding :)