Sunday, July 11, 2010

Splashscreen, Customizing List, Connecting Internet, XML Parsing,Downloading Images, Updating the User Interface Images at Runtime

Hi Friends,

              Here is the next part of my blog. Here I am going to discuss about the important things today. Every project will starts with a splash in first page. So let’s discuss about the splash.

 

Splash Screen

              We need to display the logo at the middle of the screen, whatever the screen mode it may be. So in order to handle this we will use the below XML file.

 

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

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    android:background="@color/white">

 

<ImageView android:id="@+id/ImageView01"

android:scaleType="center"

android:layout_height="fill_parent"

android:layout_width="fill_parent"

android:layout_centerInParent="true" android:src="@drawable/sun">

</ImageView>

</LinearLayout>

 

In the above XML file we have a layout with an ImageView which is centered in parent, without stretching it completely to its parent. Here according to the background of the logo we need to change the background color of the layout. Here it is “@color/White” in the above example. These colors will be maintained in project\res\values\color.xml folder. We can add new colors, which are needed for our project over there. That’s it, our layout is ready now. Let’s go to source.

 

 

             

              There is a class named Handler in android which will be going to handle the assigned work to do after some particular time. You may already know that we can start the Activities by using the Intents, we will start the activity after a period of splashTime as shown below.

 

 

 

new Handler().postDelayed(new Runnable(){

            public void run() {

                          startActivity(new Intent(MainActivity.this, MainMenu.class));

                finish();

            }

        }, _splashTime);

 

              Finally we are moving to the main menu from splash. The whole above process works perfectly if and only if the logo doesn’t have designs and different colors on the background screen. If you have different kinds of logo with lot of background colors  then let’s go for the second option.

              Here we need to prepare two images of splash one is for portrait and another is for landscape.  Create a xml file in the folder project\res\layout-land\menu.xml with the same name in the layout folder. According to the screen mode the xml files will be used. But don’t forget to maintain the same names just like in \layout folder.

 

If we want Fade-in or fade-out effects for our splash then we need to create xml files with desired effects as shown below and need to place it in \anim folder.

 

 

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

<set>

  <alpha xmlns:android="http://schemas.android.com/apk/res/android"

              android:interpolator="@android:anim/accelerate_interpolator"

              android:fromAlpha="0.0"

              android:toAlpha="1.0"

              android:duration="1000" />

</set>

fromAlpha, toAlpha and duration will be used according to your requirements. If we change the values fromAlpha to toAlpha then we will get fadeout effect.

The total source with Fadein and Fadeout effects  can be downloaded from below link.

You can download the project with source from here. or You can download the project with source from here.

Customizing List, Connecting Internet, XML Parsing,Downloading Images, Updating the User Interface Images at Runtime, Handling UI without specifying height and width of any view in the layout

 

Connecting to the internet

              We have two methods in connecting the internet server.

1.      Get

2.      Post

In first method as you already know all the values will be appended to the url . In the second (Post) method we will send the data separately which is secured. I am going to give both the methods to connect the net.

1)Get Method

 

 

 

 

 

 

 

 

 

 

 

private InputStream openHttpConnection(String urlStr) {

                            InputStream in = null;

                            int resCode = -1;

                           

                            try {

                            Log.d("openHttpConnection", "URL:"+urlStr);

                            URL url = new URL(urlStr);

                            URLConnection urlConn = url.openConnection();//Opening Connection

                                         

                            if (!(urlConn instanceof HttpURLConnection)) {

                                          throw new IOException ("URL is not an Http URL");

                            }

                            Log.d("openHttpConnection", "httpConn:1");

                            HttpURLConnection httpConn = (HttpURLConnection)urlConn;

                            httpConn.setAllowUserInteraction(false);

            httpConn.setInstanceFollowRedirects(true);

            httpConn.setRequestMethod("GET");

            httpConn.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; U; Linux "+"i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)");

            httpConn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");

            Log.d("openHttpConnection", "setting requests and properties");

            httpConn.connect();

            Log.d("openHttpConnection", "Connected successfully");

           

            resCode = httpConn.getResponseCode();   

           

            Log.d("openHttpConnection", "resCode"+resCode);

            if (resCode == HttpURLConnection.HTTP_OK) {

                in = httpConn.getInputStream();

                Log.d("openHttpConnection", "Fetchinf data done");

            }        

                            } catch (MalformedURLException e) {

                                          e.printStackTrace();

                                          Log.d("openHttpConnection", "1"+e);

                            } catch (IOException e) {

                                          e.printStackTrace();

                                          Log.d("openHttpConnection", ""+e);

                            }

                            return in;

              }

 

The above code will connect to the specific site and will get the response and the data in the form of InputStream. The variable resCode will get the  response from the server. The value should be 200 i.e., HttpURLConnection.HTTP_OK otherwise we have some problem with server.

2)Post Method:

              This method will send the data separately .The code is as shown below.This method needs two strings. One is for URL and the other is for the data which we want to post the data.

 

 

private InputStream postPage(String url, String data) {

                  InputStream is = null;

                  ret = null;

 

                  httpClient.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2109);

 

                  httpPost = new HttpPost(url);

                  response = null;

 

                  StringEntity tmp = null;                           

 

                  httpPost.setHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux " +

                                "i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.6 (Ubuntu-feisty)");

                  httpPost.setHeader("Accept", "text/html,application/xml," +

                                "application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5");

                  httpPost.setHeader("Content-Type", "application/x-www-form-urlencoded");

 

                  try {

                                tmp = new StringEntity(data,"UTF-8");

                  } catch (UnsupportedEncodingException e) {

                                System.out.println("HTTPHelp : UnsupportedEncodingException : "+e);

                  }

 

                  httpPost.setEntity(tmp);

 

                  try {

                                response = httpClient.execute(httpPost,localContext);

                  } catch (ClientProtocolException e) {

                                System.out.println("HTTPHelp : ClientProtocolException : "+e);

                  } catch (IOException e) {

                                System.out.println("HTTPHelp : IOException : "+e);

                  }

                ret = response.getStatusLine().toString();

                HttpEntity he = response.getEntity();

                try {

                                                                      InputStream inStream = he.getContent();

                                                                      is = inStream;

                                                        } catch (IllegalStateException e) {

                                                                      // TODO Auto-generated catch block

                                                                      e.printStackTrace();

                                                        } catch (IOException e) {

                                                                      // TODO Auto-generated catch block

                                                                      e.printStackTrace();

                                                        }

                                                        return is;

                  }

 

 

 

 

Downloading Images

              Lets discuss about downloading the images. Here we have some issues with google api. Some times this is throwing decoder->decode returned false.  For this I am also trying. 95% it wont come. Most of the cases it works well and code is as shown below.

 

public Drawable downloadDrawable(String imageUrl) {

    try {

                  Log.d("downloadDrawable", "Starting Connection");

        URL url = new URL(imageUrl);

        URLConnection conn = url.openConnection();

        conn.connect();

        Log.d("downloadDrawable", "Connection Created Successfully");

        InputStream is = conn.getInputStream();

        Log.d("downloadDrawable", "InputStream created Successfully");

        d = Drawable.createFromStream(is, url.toString());

        Log.d("downloadDrawable", "Drawable created Successfully");

                is.close();

                } catch (IOException e) {

                   Log.d("ERROR3", "Ex::"+e);

                }

              return d;

                            }

 

 

Updating UI at Runtime after completion of the downloading Image using AsyncTask

              This is very important one in Android. Normally in the other Technologies we will download the images using a separate Thread. But here if we use the same separate thread then it will create issue at the time of setting the image to the ImageView.

              Android doesn’t support updating the UI in a separate  thread. So, we cannot create a separate thread for updating the UI with images after downloading it. So, Inorder to handle this Android is having a class named AsyncTask. This really helps us a lot. The code is as shown below.

Calling AsyncTask

 

try {

      DownloadFilesTask d = new DownloadFilesTask();

              d.execute(new URL(bookImageUrl));//url of the image

              d.sendObjectImageView(iv_logo);// This is the object to which the image                        //has to set

} catch (Exception e)                                                                                                  e.printStackTrace();

}

 

 

AsyncTask Code

This Class will take care of downloading the image. This is not only for downloading. If we want to know whenever the work completed to it then chose this. The method onPostExecute method will be called by the Asynctask then we can do what ever we want to do after completion of that work. Here we need to set the image to the object that we got from the method sendObjectImageView.

 

private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {

                  ImageView iv;

                  int id;

                  protected Long doInBackground(URL... urls) {

                      int count = urls.length;

                      long totalSize = 0;

                      downloadDrawable(urls[0].toString());

                       return totalSize;

                  }

                  public void sendObjectImageView(ImageView ivLogo) {

                                          // TODO Auto-generated method stub

                                this.iv = ivLogo;

                                id = -1;

                            }

                            public void sendObjectImageView(ImageView iv,int id) {

                                          // TODO Auto-generated method stub

                                          this.iv = iv;

                                          this.id = id;

                            }

                            protected void onProgressUpdate(Integer... progress) {

                                Log.d("DownloadFilesTask", "onProgressUpdate"+progress[0]);

                  }

                            protected void onPostExecute(Long result) {

                                          Log.d("DownloadFilesTask", "onPostExecute"+result);

                                          if(d!=null && iv!=null)

                                          {

                                                        iv.setImageDrawable(d);

                                                        if(id!=-1)

                                                        booksImagesList[id] = d;

                                          }

                  }

 

XML Parsing

              The description of these things will be displayed soon. until then check out the project.

 

Layout Handling

              The description of these things will be displayed soon. until then check out the project.

 

Customizing Lists

              The description of these things will be displayed soon. until then check out the project.

 

 

You can download the project source from here or You can download the project source from here

 

Sunday, July 4, 2010

Customizing Buttons

We can customize the buttons easily. Just change the background of it and specify the drawable images in the place of button.

<Button android:id="@+id/Button01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="@drawable/backbtn"></Button>

Weight

If we have a apple and need to divide in to 4 parts we will cut that in to 0.25 pieces. In the same way if we want to divide a parent layout in to parts then we need to specify the total layout weight for parent layout and we need to specify the each small part in the whole total weight.

For example if the total layout needs to divide into 3 equal parts we can specify the total layout as weight as 3 and the child layout weight as ‘1’ for all the three Childs.

The below example shows how to divide a layout into 3 diff sizes using weight.

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

<LinearLayout android:id="@+id/LinearLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:weightSum="4">

<Button android:text="@+id/Button01" android:id="@+id/Button01" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1"></Button>

<Button android:text="@+id/Button02" android:id="@+id/Button02" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="2"></Button>

<Button android:text="@+id/Button03" android:id="@+id/Button03" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_weight="1"></Button>

</LinearLayout>


Gravity

We can specify the Fields style over here. We have lot of properties and we can easily customize the layouts.

Absolute Layout

This layout is deprecated and only supports for a specific resolution. We cannot use this layout if we concentrated our app to work on all the resolutions.

Relative Layout

This layout is used to arrange the fields according to the other field. Here we can specify the left, right, top and bottom fields. According to which the other fields will be arranged.

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

<RelativeLayout android:id="@+id/RelativeLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">

<EditText android:text="@+id/EditText01" android:id="@+id/EditText01" android:layout_width="wrap_content" android:layout_height="wrap_content"></EditText>

<Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/Button01" android:text="@+id/Button01" android:layout_toRightOf="@+id/EditText01"></Button><CheckBox android:layout_width="wrap_content" android:id="@+id/CheckBox01" android:layout_height="wrap_content" android:layout_below="@+id/EditText01" android:text="@+id/CheckBox01"></CheckBox>

<ImageView android:layout_below="@+id/EditText01" android:id="@+id/ImageView01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@+id/CheckBox01" android:background="@drawable/icon"></ImageView>

</RelativeLayout>


Table Layout

This Layout is used when ever we want to create the screen with Table rows and columns

TabHost

This is used to create the Tabs as like as you think. But this is fully Buggy. I really worked hard on this to make it work. But, it’s having lot of issues it won’t work properly.

We are unable to work on the ADT plug-in for Tabs. Really its buggy. It will through NullpointerException, while displaying the screen. Don’t bother about the Nullpointer just run away the code and enjoy the execution.

Most of the time the XML execution Fails for TabHost and TabWidget. I tried to work on this for Android 1.5 SDK. 90% Fail.

We can handle this by using the code successfully. This one is awesome and easy to handle. I attached the code over here. You can get the both approaches i.e.,

1. XML approach

2. Code approach

TabHost is used to create the Object for Tab Manager. TabSpec Objects will be added to the TabHost in order to add the Tabs.

Code Approach:

final TabHost tabHost = getTabHost();

tabHost.addTab(tabHost.newTabSpec("TAB1")

.setIndicator("Name of the TAB")

.setContent(new Intent(this,XYZ.class)));

tabHost.addTab(tabHost.newTabSpec("TAB2")

.setIndicator("Name of the TAB")

.setContent(new Intent(this,ABC.class));

XML Approach: You can check it in the below linked source

Source Code for TabHost with source here or here
Source Code for TabHost with XML
here
or here

Android Custom Tab Handling is introdued in Android 1.6. Here you can customize each tab including heights of each tab.

Portrait and Landscape Layouts

If you want to handle landscape devices then create a “layout-land” named folder in project “res” folder and create the XML files related to landscape devices with same name just like in layout folder and customize it accordingly.

High,Medum and Low Resolution

Android sdk 1.6 supports multi dimensions. For which we need to create the below folders to handle different dimensions.

“drawable-hdpi” ---------- for higher Resolutions,

” drawable-ldpi” ---------- for lower Resolutions,

” drawable-mdpi” -------- for medium resolutions.

Here we can place the Images to different dimensions and use thw same name for them.

Activity Calls / Data Passing / Object Passing bet Activities

Setting UI to screen

Whatever the user interface you need, just create it in XML files. Specify the name of XML from source code just as shown below.

setContentView(R.layout.XML_FILE_NAME);

Calling an Activity

Starting an activity can be done by creating an intent as shown below.

Intent i = new Intent(“this activity name”.this, “activity name to start”.class);

startActivity(i);

Finishing the Activity

Use the following code, then it will finish the current Activity. If you move the Activity to the next Activity then you can easily move to the previous Activity by using Back Button. If you don’t want it to Re-appear again, then just finish the activity so that the activity doesn’t appear back.

For example if you are displaying the splash and that should be displayed only once @ starting the app only. So after completion of the splash time we need to finish it. So that it won’t appear again even though you press back on the first page of the app.

finish();

Sending string data

As we already know that we can transfer from one to other Activity by using Intents.

Intent i = new Intent(MainActivity.this,GoActivity.class);

String data = “bla bla”;// Data String to send

i.putExtra("DATA",data );

Receiving the Data

We can receive the above the string data as shown below.

Intent i = getIntent();

String data = i.getStringExtra("DATA");// you well get the String data i.e., BLA BLA

The Red Colored DATA should be same while sending and receiving the data.

Sending Object

Here is the code to send the Object from one to other class. One Important thing to send the Object is the class should implement the Serializable class.

The below Red Colored text should be same.

//MainActivity.java

Intent i = new Intent(MainActivity.this,startActivity.class);

ObjectClassName object = new ObjectClassName();

i.putExtra("THIS", Object);

Receiving Object

// startActivity.java

Intent i = getIntent();

ObjectClassName obj = (ObjectClassName) getIntent().getSerializableExtra("THIS");// TypeCasting needed

ListActivity Example

The below code is used to create the normal list with String Array .

public class MainActivity extends ListActivity {

static final String[] COUNTRIES = new String[] {

“ABC”,”DEF”,”GHI”,”XYZ”

};

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setListAdapter(new ArrayAdapter<String>(this,

android.R.layout.simple_list_item_1, COUNTRIES));

getListView().setTextFilterEnabled(true);

}

}

This won’t has customization or anything. If you want customized list with different Images or Text or anything you can get it in the next example.



Next Post will contain the Internet Connectivity and Customized List with diff Images and XML parsing with src.


Thanks Guys,