XML Layouting - The anddev.org BoardSearcher

Basic Tutorials concerning: GUI, Views, Activites, XML, Layouts, Intents, ...

XML Layouting - The anddev.org BoardSearcher

Postby plusminus » Sun Nov 18, 2007 6:16 pm

XML Layouting - The anddev.org BoardSearcher


What is this: This tutorial shows how to create resolution "independent" XML based Layouts (here: RelativeLayout).

What this tutorial includes:
  • Create XML-Based Layouts/User Interfaces (TextView, EditText, Buttons, Backgrounds)
  • Find the Views from the xyz.XML manipulate them in your code (i.e. set an OnClickListener).
  • Sending Intents to the System (i.e. Open the Webbrowser)
  • React on Button-Clicks
See also: Hello Android - The XML Way

:?: Problems/Questions: post here

Difficulty: 1.5 of 5 :)

What it will look like:
Image


Description:
What we will do is:
  1. Define our Layout in XML (this is 100% easier as I thought !)
  2. Add some Listeners (here: OnClickListeners) to react on the user-input.
  3. Open a webpage (anddev.org) and search for the keyword the user typed in the EditText.
As some of you have probably coded GUIs with Swing before here are some Equivalents between Android and Swing.
Equivalents between Android -UserInterface stuff and Swing.
What is called Activity in Android refers almost to a (J)Frame in Swing.
What is called View in Android refers to a (J)Component in Swing.
What is called TextView in Android refers to a (J)Label in Swing.
What is called EditText in Android refers to a (J)TextField in Swing.
What is called Button in Android refers to a (J)Button in Swing. <--- Similarity :shock:
... we do not need more in this example.

Most interesting:
Lets think about what we need...
  1. 2 Labels for showing what our app does...
  2. 1 EditText, where the user can type his search-keyword
  3. 1 Clear-Button, to reset the EditBox
  4. 1 OK-Button, to send the "VIEW"-Intent (contains the baseurl merged with the keyword)
We want to accomplish that by using a RelativeLayout.
This is the first step of designing a XML-based UI: Describe what you need (not yet actual layouting!).
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- Demonstrates using a relative layout to create a form -->
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android">
  4.  
  5.     <TextView android:text="anddev.org - boardsearcher" />
  6.              
  7.     <TextView android:text="Type search-keyword here:" />
  8.  
  9.     <EditText android:singleLine="true" />
  10.  
  11.     <Button android:text="OK" />
  12.  
  13.     <Button android:text="Clear" />
  14. </RelativeLayout>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4


So as you probably see, designing an UI (User Interface) in XML is pretty easy and almost like any HTML-code. I'll explaing below, what exactly an RelativeLayout is...
Important wrote:Note: The outermost tag always :!: has to contain the xmlns:android="http://schemas.android.com/apk/res/android"-Attribute, to tell the Android tools that we are going to refer to common attributes defined in the Android namespace!


To make all these Views accessible from our code we have to give them ids, to recognize them later :!:.
We do that by adding and ID-Attribute that has to look like the following:
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1.     <ANYVIEW id="@+id/FUNNYNAME" />
Parsed in 0.000 seconds, using GeSHi 1.0.8.4

So lets give the Views of our layout some nice ids...
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- Demonstrates using a relative layout to create a form -->
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4.                android:background="@drawable/icon" >
  5.  
  6.     <TextView id="@+id/main_label"
  7.              android:text="anddev.org - boardsearcher" />
  8.              
  9.     <TextView id="@+id/info_label"
  10.              android:text="Type search-keyword here:" />
  11.  
  12.     <EditText id="@+id/keyword_entry"
  13.              android:singleLine="true" />
  14.  
  15.     <Button id="@+id/ok_button"
  16.            android:text="OK" />
  17.  
  18.     <Button id="@+id/clear_button"
  19.            android:text="Clear" />
  20. </RelativeLayout>
Parsed in 0.002 seconds, using GeSHi 1.0.8.4

Well done. What we now need to do is specify the "look" of our views a bit more exactly.
If you do not know, what attributes are available to the View you want to edit, take a look at googles... (click)
You can define widths/heights/paddings/backgrounds/textStyle/texts/alignments/everything.....................!
As we are using an Relative-Layout, what we also have to do is defining the 'relativity' between all the views.
Thats like saying: "The OK-Button should be right below the EditText, AND the Cancel-Button should be right to the left of the OK-Button, AND ........"
You do that by adding an attribute to the specific <View-Tag> like:
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <ANYVIEW id="@+id/FUNNYNAME"
  2.     android:layout_below="@id/ANOTHERVIEW" />
Parsed in 0.000 seconds, using GeSHi 1.0.8.4

where the @ means that we are referring to an relative view, a view we created before(wrote above)!
Note: you can see, what you can referr to in the R.java-file (which is created autonomously).
Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!-- Demonstrates using a relative layout to create a form -->
  3. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4.                android:layout_width="fill_parent"
  5.                android:layout_height="fill_parent"
  6.                android:background="@drawable/icon"
  7.                android:padding="10px">
  8.  
  9.     <TextView id="@+id/main_label"
  10.              android:layout_width="fill_parent"
  11.              android:layout_height="wrap_content"
  12.              android:text="anddev.org - boardsearcher"
  13.              android:textStyle="bold" />
  14.              
  15.     <TextView id="@+id/info_label"
  16.              android:layout_width="fill_parent"
  17.              android:layout_height="wrap_content"
  18.              android:text="Type search-keyword here:"
  19.              android:layout_below="@id/main_label" />
  20.  
  21.     <EditText id="@+id/keyword_entry"
  22.              android:layout_width="fill_parent"
  23.              android:layout_height="wrap_content"
  24.              android:background="@android:drawable/editbox_background"
  25.              android:layout_below="@id/info_label"
  26.              android:singleLine="true" />
  27.  
  28.     <Button id="@+id/ok_button"
  29.            android:layout_width="wrap_content"
  30.            android:layout_height="wrap_content"
  31.            android:layout_below="@id/keyword_entry"
  32.            android:layout_alignParentRight="true"
  33.            android:layout_marginLeft="10px"
  34.            android:text="OK" />
  35.  
  36.     <Button id="@+id/clear_button"
  37.                 android:layout_width="wrap_content"
  38.            android:layout_height="wrap_content"
  39.            android:layout_toLeft="@id/ok_button"
  40.            android:layout_alignTop="@id/ok_button"
  41.            android:text="Clear" />
  42. </RelativeLayout>
Parsed in 0.005 seconds, using GeSHi 1.0.8.4


So we did the layout. Lets get to the real code :wink:
I summarize what the code does, the comments should explain the rest.
At first, we grab the buttons that were defined in the xml file ( in lines 33/34 ).
After that, we add anonymous OnClickListeners to them (in lines 41/87 ).
Wihtin them we create an Intent to go to the anndev.org/search.php-thing (OK-Button) or clear the EditText (Clear-Button).

So this is the code:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. package org.anddev.android.firstxmlbasedform;
  2.  
  3. import java.net.URISyntaxException;
  4.  
  5. import android.app.Activity;
  6. import android.content.Intent;
  7. import android.net.ContentURI;
  8. import android.os.Bundle;
  9. import android.view.View;
  10. import android.view.View.OnClickListener;
  11. import android.widget.Button;
  12. import android.widget.EditText;
  13.  
  14. public class FirstXMLBasedForm extends Activity {
  15.     /** Called when the activity is first created. */
  16.     @Override
  17.     public void onCreate(Bundle icicle) {
  18.         super.onCreate(icicle);
  19.         // Loads the whole main.xml layout-structure and displays it
  20.         setContentView(R.layout.main);
  21.        
  22.         // ################### BUTTONS #####################
  23.         // -------------------------
  24.         // We need to FIND the buttons, because we didn't
  25.         // create it "here in code", but in the main.xml!
  26.         // Having found it, we set an anonymous OnClickListener
  27.         // to perform our search.
  28.         // -------------------------
  29.         // public View findViewById(int id):
  30.         // Finds a view that was identified
  31.         // by the id attribute from the XML
  32.         // that was processed in onCreate(Bundle).
  33.         Button okButton = (Button)findViewById(R.id.ok_button);
  34.         Button clearButton = (Button)findViewById(R.id.clear_button);
  35.  
  36.         if(okButton == null){
  37.             // if okButton was null, then sth.
  38.             // is wrong with our xml-definitons
  39.                 // call   kernelPanic();   =D
  40.         }else{
  41.                 okButton.setOnClickListener(new OnClickListener(){
  42.                         // @Override
  43.                         public void onClick(View viewParam) {
  44.                                 // Create an 'empty' Intent
  45.                                 Intent myIntent = null;
  46.                                 try {
  47.                                         // Find the EditText(where the user can type),
  48.                                         // that we defined in the main.xml
  49.                                         EditText keyWordEditText = (EditText)findViewById(R.id.keyword_entry);
  50.                                         if(keyWordEditText == null){
  51.                                                 showAlert("Error", "Couldn't find the 'keyword_entry'"
  52.                                                                 + "EditView in main.xml", "Damn it... OK", false);
  53.                                         }else{
  54.                                                 // Read out what the user typed into the TextView
  55.                                                 String keyword = keyWordEditText.getText().toString();
  56.                                                 if(keyword.length() == 0){
  57.                                                         showAlert("Problem", "Your keyword is not long enough!!",
  58.                                                                                 "Oops...", false);
  59.                                                         // For extreme usability, we set the Focus back to the editText.
  60.                                                         // so the user can type again immediately.
  61.                                                         keyWordEditText.requestFocus();
  62.                                                 }else{
  63.                                                         keyword = keyword.replace(" ", "%20");
  64.                                                         // The intent will open our anddev.org-board and
  65.                                                         // search for the keyword entered.
  66.                                                         myIntent = new Intent("android.intent.action.VIEW",
  67.                                                                 new ContentURI("http://anddev.org/search.php"
  68.                                                                                 + "?mode=results&search_keywords='"
  69.                                                                                 + keyword + "'"));
  70.                                                 }
  71.                                         }
  72.                                 } catch (URISyntaxException e) {
  73.                                         e.printStackTrace();
  74.                                 }
  75.                                 // Start the activity if one was created
  76.                                 if(myIntent != null)
  77.                                         startActivity(myIntent);
  78.                         }
  79.                 });
  80.             }
  81.        
  82.         if(clearButton == null){
  83.             // if clearButton was null, then sth.
  84.             // is wrong with our xml-definitons
  85.                 // call   kernelPanic();   =D
  86.         }else{
  87.                 clearButton.setOnClickListener(new OnClickListener(){
  88.                         // @Override
  89.                         public void onClick(View viewParam) {
  90.                                 // Find the EditText(where the user can type),
  91.                                 // that we defined in the main.xml
  92.                                 EditText keyWordEditText = (EditText)findViewById(R.id.keyword_entry);
  93.                                 if(keyWordEditText == null){
  94.                                         showAlert("Error", "Couldn't find the 'keyword_entry' "
  95.                                                         + "EditViewin main.xml", "Damn it... OK", false);
  96.                                 }else{
  97.                                         keyWordEditText.setText("");
  98.                                 }
  99.                         }
  100.                 });
  101.         }
  102.     }
  103. }
Parsed in 0.046 seconds, using GeSHi 1.0.8.4

Thats it :)

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top

Postby tagazok » Sun Nov 18, 2007 11:15 pm

I have an error with your code.
the two :
public void onClick(View viewParam)

error message :
The method onClick(View) of type new View.OnClickListener(){} must override a superclass method
L'idiot ne savait pas que cela était impossible...
...alors il l'a fait.
tagazok
Junior Developer
Junior Developer
 
Posts: 12
Joined: Sun Nov 18, 2007 4:39 pm
Location: Nice / Paris

Postby plusminus » Sun Nov 18, 2007 11:27 pm

Hm works with me.
Perhaps this was an copy-paste error of yours, I disabled the line-numbering so you do not have to delete all that "#".

the lines around that should look like this:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.         // call   kernelPanic();   =D
  2.  
  3.         }else{
  4.  
  5.                 okButton.setOnClickListener(new OnClickListener(){
  6.  
  7.                         @Override
  8.  
  9.                         public void onClick(View viewParam) {
Parsed in 0.034 seconds, using GeSHi 1.0.8.4


Edit:
:idea: Simply remove the "@Override"-Annotation, as the javac 1.5 does not swallow it (1.6 does).
:idea: Or switch to JDK 1.6.

I hope that helped.

Regards,
plusminus
Last edited by plusminus on Mon Nov 19, 2007 12:02 am, edited 1 time in total.
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby tagazok » Sun Nov 18, 2007 11:44 pm

yep, ti's works if I remove @Override :)

I put version 1.6 of java by default in eclipse and that works with @Overrride now :)

thx
L'idiot ne savait pas que cela était impossible...
...alors il l'a fait.
tagazok
Junior Developer
Junior Developer
 
Posts: 12
Joined: Sun Nov 18, 2007 4:39 pm
Location: Nice / Paris

Postby bibiodp » Thu Dec 06, 2007 11:22 am

Thx a lot, xml-based GUIs are a lot much understandable now :)
I'm a poor lonesome French developper ;)
bibiodp
Junior Developer
Junior Developer
 
Posts: 12
Joined: Mon Nov 26, 2007 6:18 pm

Error with content uri...

Postby gunaztar » Thu Feb 21, 2008 5:52 am

i am using m5.... the content uri in the package declaration itself showing error....
error is "content uri-cannot find symbol"
gunaztar
Junior Developer
Junior Developer
 
Posts: 18
Joined: Wed Feb 20, 2008 12:40 pm

Top

Postby plusminus » Thu Feb 21, 2008 4:22 pm

Hello gunaztar,

since m5 its no more ContentURI, but Uri. Replacement would be similar to this:
Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. Uri.parse("http://www.google.com/search?q=" + data)
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Postby neel » Sun Mar 16, 2008 11:49 pm

still gettin the same error after changing from ContentURI to Uri

i have imported
import android.net.Uri;

if i use Uri then i get error "Cannot instantiate the type Uri"

and if i use Uri.parse then i get "Uri.parse cannot be resolved to a type"

i have imported
import android.net.Uri;
neel
Developer
Developer
 
Posts: 31
Joined: Fri Feb 15, 2008 5:09 am
Location: San Jose

hi neel

Postby gunaztar » Mon Mar 17, 2008 5:05 am

hello neel,
Give the line of coding which you use Uri.parse.... So that we get clear idea about solving your problem.
Thanks
gunaztar
Junior Developer
Junior Developer
 
Posts: 18
Joined: Wed Feb 20, 2008 12:40 pm

the code

Postby neel » Mon Mar 17, 2008 5:15 am

this is my java file

Code: Select all
package com.Form;


import java.net.URISyntaxException;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;

public class XmlForm extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);
        setContentView(R.layout.main);
       
        Button ok = (Button) findViewById(R.id.ok_button);
        Button clear = (Button)findViewById(R.id.clear_button);
       
        if(ok == null){
           
        }else{ok.setOnClickListener(new OnClickListener(){

         public void onClick(View arg0) {
            
            Intent myIntent = null;
            try{
            EditText entry = (EditText) findViewById(R.id.keyword_entry);
            
            /*      if(entry == null){
               showAlert("Error", 0, "Couldn't find the 'keyword_entry'"
                            + "EditView in main.xml", "Damn it... OK", false);
            }else{
         */      
               String s = entry.getText().toString();
               
               if(s.length()==0){
                  showAlert("Problem", 0, "Your keyword is not long enough!!",
                        "Oops...", false);
                  //entry.requestFocus();
               }else{
                  s.replace(" ", "%20");
                  
               myIntent = new Intent("android.intent.action.VIEW",
                                new Uri("http://anddev.org/search.php"
                                          + "?mode=results&search_keywords='"
                                          + s + "'"));
               }
                  

         }
          
        catch(Exception e){
           e.printStackTrace();
        }
          
        }
       }
             
       
       ); // clear ends
           // ok action
        }
       
        if(clear == null){
           
        }else{
           
           clear.setOnClickListener(new OnClickListener(){

            public void onClick(View arg0) {
               
               EditText entry = (EditText) findViewById(R.id.keyword_entry);
               String s1 = entry.getText().toString();
               if(s1.length()== 0){
                  showAlert("Cmon", 0, "dude its already empty!!!", "Damn it... OK", false);
               }else{
                  entry.setText("");
               }
               
            }
              
              
              
              
           }
                 
           
           ); // clear ends
           
           
        }
    }
}


thanks in advance
neel
Developer
Developer
 
Posts: 31
Joined: Fri Feb 15, 2008 5:09 am
Location: San Jose

Uri.parse

Postby gunaztar » Mon Mar 17, 2008 5:25 am

use this lines...
myIntent = new Intent("android.intent.action.VIEW",
new Uri.parse("http://anddev.org/search.php"
+ "?mode=results&search_keywords='"
+ s + "'"));
gunaztar
Junior Developer
Junior Developer
 
Posts: 18
Joined: Wed Feb 20, 2008 12:40 pm

Postby neel » Mon Mar 17, 2008 5:30 am

I have already tried that and keep gettin the error

"Uri.parse cannot be resolved to a type"
neel
Developer
Developer
 
Posts: 31
Joined: Fri Feb 15, 2008 5:09 am
Location: San Jose

Postby neel » Mon Mar 17, 2008 10:10 pm

hi guys its working now.

the error was in

Code: Select all
myIntent = new Intent("android.intent.action.VIEW",
new Uri.parse("http://anddev.org/search.php"
+ "?mode=results&search_keywords='"
+ s + "'"));


it has to be
Code: Select all
myIntent = new Intent("android.intent.action.VIEW",
Uri.parse("http://anddev.org/search.php"
+ "?mode=results&search_keywords='"
+ s + "'"));


the 'new' keyword is not required before Uri.parse

thanks to all who replied
neel
Developer
Developer
 
Posts: 31
Joined: Fri Feb 15, 2008 5:09 am
Location: San Jose

Regards R.id.ok_button

Postby tolpaul » Thu Apr 03, 2008 12:05 pm

Hi there

First of all i want to thank you a lot for these wonderfull tutorials man you're great.

Regarding the problem i am having:
I am having some problems when i write findViewById(R.id.something else), where "something else is anything that i wrote on the main.xml. What is the problem please?

Thanks,
Paul.
tolpaul
Freshman
Freshman
 
Posts: 2
Joined: Wed Apr 02, 2008 5:57 pm

Postby plusminus » Thu Apr 03, 2008 6:29 pm

Hello Paul,

you can only load Views with [font=Lucida Console]findViewById[/font] from the ContentView you loaded with [font=Lucida Console]setContentView[/font].

Why would you load a View that is not in the current Activity :?:

Regards,
plusminus
Image
Image | Android Development Community / Tutorials
User avatar
plusminus
Site Admin
Site Admin
 
Posts: 2688
Joined: Wed Nov 14, 2007 8:37 pm
Location: Schriesheim, Germany

Top
Next

Return to Novice Tutorials

Who is online

Users browsing this forum: No registered users and 10 guests