Android Tutorial – Shishir Kant Singh https://shishirkant.com Jada Sir जाड़ा सर :) Sat, 30 May 2020 16:15:53 +0000 en-US hourly 1 https://wordpress.org/?v=6.8.1 https://shishirkant.com/wp-content/uploads/2020/05/cropped-shishir-32x32.jpg Android Tutorial – Shishir Kant Singh https://shishirkant.com 32 32 187312365 Drawing in Android https://shishirkant.com/drawing-in-android/?utm_source=rss&utm_medium=rss&utm_campaign=drawing-in-android Sat, 30 May 2020 16:15:49 +0000 http://shishirkant.com/?p=1472 We can either draw directly on a Canvas object or to modify existing Views to customise their look and feel. Drawing is performed in the onDraw() method. Simple graphics can be created in the layout XML file too.

We use the Canvas object to perform drawing. A Canvas is an object that has drawing methods to do the drawing. Actual drawing happens in a Bitmap that is placed into a window. The Paint class holds the style and colour information about how to draw geometries, text and bitmaps. A Drawable is an object that can be drawn. Unlike a View, a Drawable does not have any facility to receive events or otherwise interact with the user.

Oval shape

We are going to draw a circle on a View. The circle is defined in an XML file. The manifest file does not need to be modified.

oval.xml

<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="oval">
    
   <solid 
       android:color="#666666"/>
   <size 
       android:width="70dp"
       android:height="70dp"/>
</shape> 

In the oval.xml file we create a circle shape. We define its colour and size. The oval.xml file is located in the res/drawable directory. The directory had to be created.

main.xml

<?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"
    >        

<View
    android:layout_width="100dp"
    android:layout_height="100dp"
    android:layout_marginTop="5dp"
    android:background="@drawable/oval"
    />   
   
</LinearLayout>

In the main.xml file, we define a View. The background of this view is filled with our drawable object.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">OvalShape</string>
</resources>

Resources file.

MainActivity.java

package com.shishirkant.ovalshape;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }
}

The file just loads the defined layout.

Oval Shape
Figure: Oval Shape

Drawing a rectangle

In the second example, we will draw a rectangle on a View. It will be drawn in the onDraw() method of the View. Since we will be drawing on an existing View, we will have a predefined Canvas with its Bitmap. We do not need to worry about them. The manifest file is not modified. In this example the main.xml file will not be needed.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">DrawRect</string>
</resources>

Resources.

DrawView.java

package com.shishirkant.drawrect;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.View;

public class DrawView extends View 
{
    Paint paint = new Paint();

    public DrawView(Context context)  
    {
        super(context);
        paint.setColor(Color.GREEN);
    }

    @Override
    public void onDraw(Canvas canvas) 
    {
        canvas.drawRect(30, 30, 100, 100, paint);
    }
}

We have a custom DrawView class. The file is located in the src/com/shishirkant/drawrect/ directory.

public class DrawView extends View 

The custom DrawView class inherits from the base View class.

Paint paint = new Paint();

An instance of the Paint class is created. It will define a colour for drawing.

paint.setColor(Color.GREEN);

We will paint in green colour.

@Override
public void onDraw(Canvas canvas) 
{
    canvas.drawRect(30, 30, 100, 100, paint);
}

The drawing is performed in the onDraw() method. The method provides the Canvas object for us. We call the drawRect() to draw the rectangle on the View.

MainActivity.java

package com.shishirkant.drawrect;

import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;

public class MainActivity extends Activity 
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        DrawView drawView = new DrawView(this);
        drawView.setBackgroundColor(Color.WHITE);
        setContentView(drawView);
    }
}

In the MainActivity.java source file we set the custom DrawView to be the content View of the Activity.

DrawView drawView = new DrawView(this);

We create an instance of the DrawView class.

drawView.setBackgroundColor(Color.WHITE);

We specify the background colour for the View.

setContentView(drawView);

The DrawView becomes the content View of the Activity.

Rectangle
Figure: Rectangle
]]>
1472
Android Dialogs https://shishirkant.com/android-dialogs/?utm_source=rss&utm_medium=rss&utm_campaign=android-dialogs Sat, 30 May 2020 16:11:17 +0000 http://shishirkant.com/?p=1469 A dialog is defined as a conversation between two or more persons. In a computer application a dialog is a window which is used to “talk” to the application. A dialog is used to input data, modify data, change the application settings etc.

An AlertDialog is a dialog used to display information or to receive data. It can display one, two, or three buttons. It is created with a Builder subclass.

Displaying a message

We use the AlertDialog to display a message. In the example, we do not need to modify the manifest file.

main.xml

<?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"
    >
    
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dip"
        android:onClick="onClicked"
        android:text="@string/btn_label" />
        
</LinearLayout>

In the main.xml layout file, we have a Button widget. This button displays an AlertDialog.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">DisplaySize</string>
    <string name="btn_label">Show</string>
</resources>

This is strings.xml file.

MainActivity.java

package com.shishirkant.displaysize;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.graphics.Point;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.view.WindowManager;
import android.view.Display;

public class MainActivity extends Activity
{    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClicked(View view)
    {
        Point p = getDisplaySize();

        AlertDialog ad = new AlertDialog.Builder(this).create();

        ad.setTitle("Display size");
        String msg = String.format("Width:%d, Height:%d", p.x, p.y);
        ad.setMessage(msg);
        ad.setIcon(android.R.drawable.ic_dialog_info);

        ad.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                dialog.cancel();
            }
        });

        ad.show();     
    }

    public Point getDisplaySize()
    {
        WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
        Display ds = wm.getDefaultDisplay();

        Point p = new Point();
        ds.getSize(p);

        return p;
    }
}

We use the AlertDialog to display the size of the display.

Point p = getDisplaySize();

In the custom getDisplaySize() method, we determine the size of the display.

AlertDialog ad = new AlertDialog.Builder(this).create();

An instance of the AlertDialog is created.

ad.setTitle("Display size");
String msg = String.format("Width:%d, Height:%d", p.x, p.y);
ad.setMessage(msg);
ad.setIcon(android.R.drawable.ic_dialog_info);

We set a title, message and an icon for the dialog.

ad.setButton("OK", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dialog, int which) {
        dialog.cancel();
    }
});

We add a button to the dialog. When we click on the OK button, the dialog is closed.

ad.show();

The show() method shows the dialog.

WindowManager wm = (WindowManager) getSystemService(WINDOW_SERVICE);
Display ds = wm.getDefaultDisplay();

We get the default display.

Point p = new Point();
ds.getSize(p);

We find out the size of the display with the getSize() method.

AlertDialog showing the size of the display
Figure: AlertDialog showing the size of the display

Receiving data

The second example uses the AlertDialog to receive data from a user. The dialog will ask a user for his name. It will then display the input in a TextView widget.

The manifest file is not modified.

main.xml

<?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"
    >
    
    <Button
        android:id="@+id/btnId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dip"
        android:onClick="onClicked"
        android:text="@string/btn_label" />   
        
    <TextView
        android:id="@+id/tvId"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" />
        
</LinearLayout>

This is main.xml file. We have a Button widget and a TextView widget. The button will show the dialog window. The TextView will receive the input text from the dialog.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">InputDialog</string>
    <string name="btn_label">Show dialog</string>
</resources>

This is the strings.xml resource file.

MainActivity.java

package com.shishirkant.input;

import android.app.Activity;
import android.os.Bundle;
import android.app.AlertDialog;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.content.DialogInterface;

public class MainActivity extends Activity
{
    private TextView tv;
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.tvId);
    }

    public void onClicked(View view)
    {
        AlertDialog.Builder ad = new AlertDialog.Builder(this);

        ad.setTitle("Input");
        ad.setMessage("Enter your name");

        final EditText input = new EditText(this);
        ad.setView(input);

        ad.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
        public void onClick(DialogInterface dlg, int which) {
            String val = input.getText().toString();
            String msg = String.format("Hello %s!", val);
            tv.setText(msg);
          }
        });

        ad.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
          public void onClick(DialogInterface dlg, int which) {
            dlg.cancel();
          }
        });

        ad.show();
    }
}

Clicking on the button widget will display the AlertDialog. It has an EditText to receive the input from a user.

AlertDialog.Builder ad = new AlertDialog.Builder(this);

ad.setTitle("Input");
ad.setMessage("Enter your name");

We set a title and a message for the dialog.

final EditText input = new EditText(this);
ad.setView(input);

We add the EditText widget to the dialog.

ad.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dlg, int which) {
    String val = input.getText().toString();
    String msg = String.format("Hello %s!", val);
    tv.setText(msg);
    }
});

Clicking on the OK button of the dialog, we get the text from the EditText widget. The text used to format a greeting which is set to the TextView.

ad.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
    public void onClick(DialogInterface dlg, int which) {
    dlg.cancel();
    }
});

Clicking on the Cancel button will dismiss the dialog.

Receiving input
Figure: Receiving input
]]>
1469
Android Menus https://shishirkant.com/android-menus/?utm_source=rss&utm_medium=rss&utm_campaign=android-menus Sat, 30 May 2020 16:07:43 +0000 http://shishirkant.com/?p=1466 There are three kinds of menus in Android: options menu, context menu, and popup menu. The options menu is the primary collection of menu items for an activity. In the options menu we should have commands that have global impact on the applications. For example a Settings menu. It is displayed either at the top or at the bottom of the activity. The context menu shows menu items in a specific context. For example for ListView items. It is shown when the user performs a long-click on an element. A popup menu displays a list of items in a vertical list that’s anchored to the view that invoked the menu. It appears below the anchor view if there is room, or above the view otherwise. It should relate to regions of content in the activity.

Menus can be created manually by coding or they can be defined in an XML file. If we define our menus in an XML file we use the MenuInflater object to create menus from the XML file.

Options menu

Our options menu will have two menu items. When we select a menu item a Toast window is shown with the name of the selected menu item. The options menu is displayed after we click on the menu button.

The manifest file is not modified in this example.

Menu button
Figure: Menu button
main.xml

<?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"
    >
    
  <TextView
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:text="@string/message" />
    
</LinearLayout>

In the main.xml layout file, we have one TextView widget. It will display a welcome message.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">OptionsMenu</string>
    <string name="message">Demonstrating Options Menu</string>
    <string name="om1">Settings</string>
    <string name="om2">Tools</string>
</resources>

This is strings.xml file.

options_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/settings"
    android:title="@string/om1" />
  <item android:id="@+id/tools"
    android:title="@string/om2" />
</menu>

This is options_menu.xml file. It defines two menu items. The file is located in the res/menu/ subdirectory.

MainActivity.java

package com.shishirkant.opmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
    {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.options_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) 
    {
        switch (item.getItemId()) 
        {
            case R.id.settings:
                Toast.makeText(MainActivity.this, "Settings menu selected.", 
                    Toast.LENGTH_SHORT).show();
                return true;

            case R.id.tools:
                Toast.makeText(MainActivity.this, "Tools menu selected.", 
                    Toast.LENGTH_SHORT).show();
                return true;

            default:
                return super.onOptionsItemSelected(item);
        }
    }
}

To enable an options menu in an activity, we need to override the onCreateOptionsMenu() and the onOptionsItemSelected() methods.

@Override
public boolean onCreateOptionsMenu(Menu menu) 
{
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.options_menu, menu);
    return true;
}

Inside the onCreateOptionsMenu() method, we build the options menu from the options_menu.xml file. We use the MenuInflater class to do the job.

@Override
public boolean onOptionsItemSelected(MenuItem item) 
{
...
}

The onOptionsItemSelected() method handles the click events on the menu items.

case R.id.settings:
    Toast.makeText(MainActivity.this, "Settings menu selected.", 
        Toast.LENGTH_SHORT).show();
    return true;

In case of the selection of the Settings menu item we show a Toast window with “Settings menu selected” message.

Options menu at the bottom of the activity
Figure: Options menu at the bottom of the activity

Context menu

We have a ListView with the names of our planets. A long-click on an element will show a context menu with tree options: Delete, Uppercase, and Lowercase.

The manifest file is not modified.

main.xml

<?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"
    >
    
    <ListView 
      android:id="@+id/lvId"
      android:layout_width="fill_parent"   
      android:layout_height="fill_parent" />  
      
</LinearLayout>

This is main.xml file. It contains a ListView widget.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ContextMenu</string>
    <string-array name="planets">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
        <item>Jupiter</item>
        <item>Saturn</item>
        <item>Uranus</item>
        <item>Neptune</item>
        <item>Pluto</item>
    </string-array>     
</resources>

This is the strings.xml resource file.

row.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="20sp">
</TextView>

This is the row.xml resource file. Each row of a ListView consists of a single TextView.

MainActivity.java

package com.shishirkant.conmenu;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;  
import android.widget.ListView;  
import android.view.View;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.widget.AdapterView.AdapterContextMenuInfo;

import java.util.Arrays;
import java.util.ArrayList;


public class MainActivity extends Activity
{
    private ListView lv;  
    private ArrayAdapter<String> la; 

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupUI();
    }

    public void setupUI()
    { 
        lv = (ListView) findViewById(R.id.lvId);  
        String[] planets = getResources().getStringArray(R.array.planets); 
        ArrayList<String> lst = new ArrayList<String>();
        lst.addAll(Arrays.asList(planets));

        la = new ArrayAdapter<String>(this, R.layout.row, lst);
        lv.setAdapter(la);
        registerForContextMenu(lv);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, 
        ContextMenuInfo menuInfo) 
    {
        super.onCreateContextMenu(menu, v, menuInfo);
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) 
    {
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        
        int pos = info.position;
        String i = la.getItem(pos);

        switch (item.getItemId()) 
        {
            case R.id.delId:
                la.remove(i);
                return true;

            case R.id.upId:               
                String upln = i.toUpperCase();
                la.remove(i);
                la.insert(upln, pos); 
                return true;

            case R.id.loId:
                String lpln = i.toLowerCase();
                la.remove(i);
                la.insert(lpln, pos);          
                return true;

            default:
                return super.onContextItemSelected(item);
        }
    }
}

In order to implement the context menu, we have to override the onCreateContextMenu() and the onContextItemSelected() methods. We also need to call the registerForContextMenu() method for a specific view.

String[] planets = getResources().getStringArray(R.array.planets); 
ArrayList<String> lst = new ArrayList<String>();
lst.addAll(Arrays.asList(planets));

We will be deleting items of the ListView. Therefore, we need to use an ArrayList. Otherwise the list would be read-only.

registerForContextMenu(lv);

The context menu is registered for the ListView widget.

@Override
public void onCreateContextMenu(ContextMenu menu, View v, 
    ContextMenuInfo menuInfo) 
{
    super.onCreateContextMenu(menu, v, menuInfo);
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.context_menu, menu);
}

In the onCreateContextMenu() method we build the context menu from the context_menu.xml file.

@Override
public boolean onContextItemSelected(MenuItem item) 
{
...
}

The onContextItemSelected() reacts to list item selection events.

AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();

int pos = info.position;
String i = la.getItem(pos);

To find out more about the selected item, we use the AdapterContextMenuInfo class. We get the position and the text of the selected item.

case R.id.delId:
    la.remove(i);
    return true;

If we select the Delete context menu option, we remove the item from the ArrayAdapter.

case R.id.upId:               
    String upln = i.toUpperCase();
    la.remove(i);
    la.insert(upln, pos); 
    return true;

For the Uppercase option, we modify the string, remove the original one and insert a new one.

Context menu with three options
Figure: Context menu with three options

Popup menu

The example shows a PopupMenu after clicking on a button.

The manifest file is not modified.

main.xml

<?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"
    >
    
  <Button
      android:id="@+id/btnId"
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:layout_marginTop="10dip"
      android:text="@string/btn_label"
      android:onClick="onClick" />
      
  <TextView
      android:id="@+id/tvId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" 
      android:layout_marginTop="10dip" />
      
</LinearLayout>

This is main.xml file. We have a Button widget and a TextView widget. The button will show a PopupMenu.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">PopupMenu</string>
    <string name="btn_label">Show menu</string>
    <string name="pm1">Item 1</string>
    <string name="pm2">Item 2</string>
</resources>

This is the strings.xml resource file.

popup_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@+id/settings"
    android:title="@string/pm1" />
  <item android:id="@+id/tools"
    android:title="@string/pm2" />
</menu>

This is popup_menu.xml file. It defines two menu items. The file is located in the res/menu/ subdirectory.

MainActivity.java

package com.shishirkant.popmenu;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.MenuItem;
import android.widget.TextView;
import android.widget.PopupMenu;
import android.widget.PopupMenu.OnMenuItemClickListener;

public class MainActivity extends Activity
    implements OnMenuItemClickListener
{   
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.tvId);        
    }

   public void onClick(View v) 
   {   
       showPopupMenu(v);
   }

   public void showPopupMenu(View v)
   {
       PopupMenu pm = new PopupMenu(MainActivity.this, v);
       pm.getMenuInflater().inflate(R.menu.popup_menu, pm.getMenu()); 
       pm.setOnMenuItemClickListener(this);          
       pm.show();
   }

   @Override
   public boolean onMenuItemClick(MenuItem item) 
   {           
      tv.setText(item.toString() + " selected");
      return true;  
   }
}

PopupMenu is displayed after clicking on the button widget.

public void onClick(View v) 
{   
    showPopupMenu(v);
}

This method is a callback to the button click. The relation is set in the main.xml file via an attribute. The method calls the showPopupMenu() method.

public void showPopupMenu(View v)
{
    PopupMenu pm = new PopupMenu(MainActivity.this, v);
    pm.getMenuInflater().inflate(R.menu.popup_menu, pm.getMenu()); 
    pm.setOnMenuItemClickListener(this);          
    pm.show();
}

We create an instance of the PopupMenu class. It builds the menu, sets the OnMenuItemClickListener and shows the PopupMenu.

@Override
public boolean onMenuItemClick(MenuItem item) 
{           
    tv.setText(item.toString() + " selected");
    return true;  
}

After selecting a menu item the onMenuItemClick() method is called. It sets the item’s title to the TextView widget.

]]>
1466
Android Pickers Widget https://shishirkant.com/android-pickers-widget/?utm_source=rss&utm_medium=rss&utm_campaign=android-pickers-widget Sat, 30 May 2020 16:01:09 +0000 http://shishirkant.com/?p=1463 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <NumberPicker android:id="@+id/npId" android:layout_marginTop="5dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView]]>

There are number, date or time pickers.

NumberPicker

NumberPicker is a widget that allows us to select a number from a predefined range of values. The manifest file is not modified in this example.

main.xml

<?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"
    >
    
    <NumberPicker android:id="@+id/npId"
      android:layout_marginTop="5dp"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tvId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp" 
        android:layout_marginLeft="5dp"
        android:text="0"
        android:textSize="30sp" />      
        
</LinearLayout>

In the layout file we have a NumberPicker widget and a TextView widget. The TextView widget will display the selected value of the NumberPicker.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">NumberPicker</string>
</resources>

The strings resource file.

MainActivity.java

package com.shishirkant.numpick;

import android.app.Activity;
import android.os.Bundle;
import android.widget.NumberPicker;
import android.widget.TextView;
import android.widget.NumberPicker.OnValueChangeListener;

public class MainActivity extends Activity
{
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupUI();
    }

    public void setupUI()
    {
        tv = (TextView) findViewById(R.id.tvId);

        NumberPicker np = (NumberPicker) findViewById(R.id.npId);

        np.setOnValueChangedListener(new OnValueChangeListener()
        {
            public void onValueChange(NumberPicker picker, int oldVal, 
                int newVal)
            {
                tv.setText(String.valueOf(newVal)); 
            }        
        });

        np.setMaxValue(100);
        np.setMinValue(0);
    }
}

Clicking on the plus and minus signs of the NumberPicker we select a new value. The currently selected value is displayed in the TextView widget.

NumberPicker np = (NumberPicker) findViewById(R.id.npId);

A reference to the NumberPicker widget is retrieved from the main.xml file.

np.setOnValueChangedListener(new OnValueChangeListener()
{
    public void onValueChange(NumberPicker picker, int oldVal, 
        int newVal)
    {
        tv.setText(String.valueOf(newVal)); 
    }        
});

OnValueChangeListener is added to the NumberPicker widget. It will call the onValueChange() method when the value of the NumberPickeris changed. Inside this method, we set the currently selected value to the TextView widget.

np.setMaxValue(100);
np.setMinValue(0);

We set the maximum and minimum value for the NumberPicker.

NumberPicker widget
Figure: NumberPicker widget

TimePicker

TimePicker is a widget for selecting the time of day. It has two modes, 24 hour or AM/PM mode. Selection of the hour and minute digit can be controlled by vertical spinners. A DatePicker is a widget for selecting a date. It is very similar to the TimePicker.

The manifest file is not modified.

main.xml

<?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"
    >
    
    <TimePicker android:id="@+id/tpId"
      android:layout_marginTop="5dp"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tvId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp" 
        android:layout_marginLeft="5dp"
        android:textSize="30sp" />  
        
</LinearLayout>

In the main.xml file we have a TimePicker and TextView widgets. The selected time is displayed in the TextView.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">TimePicker</string>
</resources>

This is the strings.xml resource file.

MainActivity.java

package com.shishirkant.timepicker;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TimePicker;
import android.widget.TextView;
import android.widget.TimePicker.OnTimeChangedListener;

public class MainActivity extends Activity
{
    private TextView tv;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupUI();
    }

    public void setupUI()
    {
        tv = (TextView) findViewById(R.id.tvId);

        TimePicker tp = (TimePicker) findViewById(R.id.tpId);
        displayCurrentTime(tp);

        tp.setOnTimeChangedListener(new OnTimeChangedListener()
        {
            public void onTimeChanged(TimePicker view, int hourOfDay, 
                int minute)
            {
                StringBuilder tm = new StringBuilder();
                tm.append(hourOfDay);
                tm.append(" h "); 
                tm.append(minute);
                tm.append(" m");
                tv.setText(tm); 
            }        
        });
    }

    public void displayCurrentTime(TimePicker tp)
    {
        int h = tp.getCurrentHour();
        int m = tp.getCurrentMinute();

        StringBuilder tm = new StringBuilder();
        tm.append(h);
        tm.append(" h "); 
        tm.append(m);
        tm.append(" m");
        tv.setText(tm);         
    }
}

The TimePicker listens to the OnTimeChangedListener. When the time is changed, the new time value is set to the TextView inside the onTimeChanged() method.

tp.setOnTimeChangedListener(new OnTimeChangedListener()
{
    public void onTimeChanged(TimePicker view, int hourOfDay, 
        int minute)
    {
        StringBuilder tm = new StringBuilder();
        tm.append(hourOfDay);
        tm.append(" h "); 
        tm.append(minute);
        tm.append(" m");
        tv.setText(tm); 
    }        
});

Inside an anonymous OnTimeChangedListener class we implement the onTimeChanged() method. With the StringBuilder we build the string to be displayed and set it to the TextView widget.

public void displayCurrentTime(TimePicker tp)
{
    int h = tp.getCurrentHour();
    int m = tp.getCurrentMinute();

    StringBuilder tm = new StringBuilder();
    tm.append(h);
    tm.append(" h "); 
    tm.append(m);
    tm.append(" m");
    tv.setText(tm);         
}

When the activity is first shown, we display the current time.

TimePicker
Figure: TimePicker widget
]]>
1463
Android ListView Widget https://shishirkant.com/android-listview-widget/?utm_source=rss&utm_medium=rss&utm_campaign=android-listview-widget Sat, 30 May 2020 15:56:53 +0000 http://shishirkant.com/?p=1459 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical"]]> ListView is a widget that shows items in a vertical scrolling list. An Adapter object is used to fill the ListView with data.

ListView Widget I

In the example, we show a ListView widget with the names of the planets of our solar system. We use an ArrayAdapter to fill the ListView with data.

main.xml

<?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">  
    
    <ListView 
      android:id="@+id/lvId"
      android:layout_width="fill_parent"   
      android:layout_height="fill_parent" />  
    
</LinearLayout> 

In the main.xml file we define one ListView widget.

row.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="20sp">
</TextView>

In the row.xml file we define, how a list row will look like. We will have one TextView in each row of a ListView. The sp is a unit used for setting the font size.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ListView</string>
    <string-array name="planets">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
        <item>Jupiter</item>
        <item>Saturn</item>
        <item>Uranus</item>
        <item>Neptune</item>
        <item>Pluto</item>
    </string-array>        
</resources>

The names of the planets are specified in the strings.xml file within a string array attribute.

MainActivity.java

package com.shishirkant.listview;

import android.app.Activity;
import android.os.Bundle;
import android.widget.ArrayAdapter;  
import android.widget.ListView;  

public class MainActivity extends Activity
{
    private ListView lv;  
    private ArrayAdapter<String> la; 

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setupUI();
    }

    public void setupUI()
    { 
        lv = (ListView) findViewById(R.id.lvId);  
        String[] planets = getResources().getStringArray(R.array.planets); 
        lv.setAdapter(new ArrayAdapter<String>(this, R.layout.row, planets));
    }
}

This is the MainActivity.java source file.

lv = (ListView) findViewById(R.id.lvId);  

We get the reference to the ListView widget.

String[] planets = getResources().getStringArray(R.array.planets);

This code line retrieves the names of the planets from the resource file.

lv.setAdapter(new ArrayAdapter<String>(this, R.layout.row, planets));

An ArrayAdapter is created and set to the ListView.

ListView widget
Figure: ListView widget

ListView widget II

ListActivity is a special activity that holds a ListView object. ListView is a common widget and it typically takes the whole screen. Therefore a special activity was created. In the example, the manifest file is not modified. We will also not need the main.xml layout file.

row.xml

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:padding="10dp"
    android:textSize="20sp">
</TextView>

In the row.xml file we define one TextView in each row of a ListView.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ListView2</string>
</resources>

This is the strings.xml resource file.

MainActivity.java

package com.shishirkant.listview2;

import android.app.ListActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;  
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ListView;  
import android.widget.TextView;

public class MainActivity extends ListActivity 
     implements OnItemClickListener, OnItemSelectedListener
{       
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setupUI();
    }

    public void setupUI()
    { 
        ArrayAdapter<String> la = new ArrayAdapter<String>(this, R.layout.row);  
        la.add("Mercury");
        la.add("Venus");
        la.add("Earth");
        la.add("Mars");
        la.add("Jupiter");
        la.add("Saturn");
        la.add("Uranus");
        la.add("Neptune");
        la.add("Pluto");

        setListAdapter(la);

        ListView lv = getListView();
        lv.setOnItemClickListener(this);
        lv.setOnItemSelectedListener(this);
    }

    public void onItemClick(AdapterView<?> parent, View view,
        int position, long id) 
    {        
        String planet = ((TextView) view).getText().toString();
        setTitle(planet);
    }

    public void onItemSelected(AdapterView<?> parent, View view,
        int position, long id) 
    {        
        String planet = ((TextView) view).getText().toString();
        setTitle(planet);
    }

    public void onNothingSelected(AdapterView<?> parent) 
    {        
        // not implemented
    }
}

We programmatically create the items of the ListView. We react to click and select events of the ListView. The planet that we select or click on will be shown in the titlebar.

public class MainActivity extends ListActivity 
     implements OnItemClickListener, OnItemSelectedListener

The MainActivityextends the ListActivity and implements two listeners. By implementing these two listeners, we must implement three abstract methods that are associated with these listeners.

@Override
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setupUI();
}

In the onCreate() method we do not call the setContentView() method. The ListView widget of the ListActivity will take up the whole screen.

ArrayAdapter<String> la = new ArrayAdapter<String>(this, R.layout.row);  
la.add("Mercury");
la.add("Venus");
la.add("Earth");
...

We create an instance of the ArrayAdapter. We add names of the planets to the adapter.

setListAdapter(la);

Sets the adapter for the associated ListView object.

ListView lv = getListView();
lv.setOnItemClickListener(this);
lv.setOnItemSelectedListener(this);

From the ListActivity we get the ListView widget. The two listeners are set for the ListView widget.

public void onItemClick(AdapterView<?> parent, View view,
    int position, long id) 
{        
    String planet = ((TextView) view).getText().toString();
    setTitle(planet);
}

Implementing the OnItemClickListener, we have to define the onItemClick() method. We get the planet name from the TextView of the clicked row and set it to the titlebar.

public void onItemSelected(AdapterView<?> parent, View view,
    int position, long id) 
{        
    String planet = ((TextView) view).getText().toString();
    setTitle(planet);
}

public void onNothingSelected(AdapterView<?> parent) 
{        
    // not implemented
}

After implementing the OnItemSelectedListener we have to define two abstract methods. The first method sets the currently selected planet to the titlebar. The second method is not implemented.

Selected row of a ListView widget
Figure: Selected row of a ListView widget
]]>
1459
Android ProgressBar Widget https://shishirkant.com/android-progressbar-widget/?utm_source=rss&utm_medium=rss&utm_campaign=android-progressbar-widget Sat, 30 May 2020 15:51:56 +0000 http://shishirkant.com/?p=1455 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > <ProgressBar android:id="@+id/pbId" android:layout_width="fill_parent" android:layout_height="wrap_content" style="?android:attr/progressBarStyleHorizontal" android:layout_margin="10dp" /> <TextView android:id="@+id/tvId" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_margin="10dp" /> </LinearLayout> In the main.xml layout file, we]]> ProgressBar I

We have a horizontal ProgressBar widget and a TextView widget that shows the percentage of the task completed. The manifest file is left untouched.

main.xml

<?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"
    >
<ProgressBar 
    android:id="@+id/pbId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_margin="10dp"
    />       
<TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_margin="10dp"
    />
</LinearLayout>

In the main.xml layout file, we have a ProgressBar and a TextView. The style="?android:attr/progressBarStyleHorizontal" style makes the ProgressBar horizontal. The default mode of the ProgressBar is the circular mode.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">ProgBar</string>
</resources>

String resource file.

MainActivity.java

package com.shishirkant.progbar2;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.util.Log;


public class MainActivity extends Activity
{
    ProgressBar pb;
    TextView tv;
    int prg = 0;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        pb = (ProgressBar) findViewById(R.id.pbId);
        tv = (TextView) findViewById(R.id.tvId);
 
        new Thread(myThread).start();
    }

    private Runnable myThread = new Runnable()
    { 
        @Override
        public void run() 
        {
            while (prg < 100)
            {
                try
                {
                    hnd.sendMessage(hnd.obtainMessage());
                    Thread.sleep(100);
                }
                catch(InterruptedException e) 
                {  
                    Log.e("ERROR", "Thread was Interrupted");
                }
            }

            runOnUiThread(new Runnable() { 
                public void run() {
                    tv.setText("Finished");
                }
            });          
        }
    
        Handler hnd = new Handler()
        {    
            @Override
            public void handleMessage(Message msg) 
            {
                prg++;
                pb.setProgress(prg);

                String perc = String.valueOf(prg).toString();
                tv.setText(perc+"% completed");
            }
        };
    };
}

We create a thread to control the progress of a ProgressBar.

new Thread(myThread).start();

A new thread is started. In Android, lengthy tasks should by performed inside a thread to prevent the application from appearing unresponsive. A thread ends by returning from its main() method, or by an exception.

@Override
public void run() 
{
    while (prg < 100)
    {
        try
        {
            hnd.sendMessage(hnd.obtainMessage());
            Thread.sleep(100);
        }
        catch(InterruptedException e) 
        {  
            Log.e("ERROR", "Thread was Interrupted");
        }
    }

    runOnUiThread(new Runnable() { 
        public void run() {
            tv.setText("Finished");
        }
    });          
}

The code in a thread is placed in the run() method. We will simulate a lengthy task by calling the Thread.sleep() method. This forces us to handle the InterruptedException. Android application runs in a single-thread model. All components of the main activity are created in the main thread. These components cannot be manipulated in other threads. To work around this, we use either the Handler object or call the runOnUiThread() method.

runOnUiThread(new Runnable() { 
    public void run() {
        tv.setText("Finished");
    }
});   

Only the original thread that created a view hierarchy can touch its views. Here we are modifying the TextView widget. Therefore we have put the code into the runOnUiThread() method, which runs the code in the main, UI thread, where the widget was created.

Handler hnd = new Handler()
{    
    @Override
    public void handleMessage(Message msg) 
    {
        prg++;
        pb.setProgress(prg);

        String perc = String.valueOf(prg).toString();
        tv.setText(perc+"% completed");
    }
};

Another way to touch widgets from another thread is to use the Handler object. It is used to enqueue an action to be performed on a different thread than its own. We update the progress bar and set a percentage of the task completed to the text view.

ProgressBar widget
Figure: ProgressBar widget

ProgressBar II

In the second example, we show the usage of the ProgressBar in a circular mode. The manifest file does not need to be modified.

main.xml

<?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"
    >
<ProgressBar 
    android:id="@+id/pbId"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    />    
<TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/msg"
    />        
</LinearLayout>

In the main.xml file we have a ProgressBar and a TextView. The ProgressBar has the default style, which is the circular style. This is the same as if we have used the style="?android:attr/progressBarStyle" attribute.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">CirProgBar</string>
    <string name="msg">Please wait...</string>
</resources>

We have two string resources in the strings.xml file.

MainActivity.java

package com.shishirkant.progbar;

import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.view.View;
import android.util.Log;

public class MainActivity extends Activity
{
    ProgressBar pb;
    TextView tv;
    int prg = 0;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        pb = (ProgressBar) findViewById(R.id.pbId);
        tv = (TextView) findViewById(R.id.tvId);
 
        new Thread(myThread).start();
    }

    private Runnable myThread = new Runnable()
    { 
        @Override
        public void run() 
        {
            while (prg < 100)
            {
                try
                {
                    hnd.sendMessage(hnd.obtainMessage());
                    Thread.sleep(100);
                }
                catch(InterruptedException e) 
                {  
                    Log.e("ERROR", "Thread was Interrupted");
                }
            }

            runOnUiThread(new Runnable() { 
                public void run() {
                    tv.setText("Finished");
                    pb.setVisibility(View.GONE); 
                }
            });          
        }
    
        Handler hnd = new Handler()
        {    
            @Override
            public void handleMessage(Message msg) 
            {
                prg++;
                pb.setProgress(prg);
            }
        };
    };
}

The code is similar to the first example with a few modifications.

runOnUiThread(new Runnable() { 
    public void run() {
        tv.setText("Finished");
        pb.setVisibility(View.GONE); 
    }
}); 

After the task was completed, we hide the ProgressBar using the setVisibility() method. The circle itself is an endless animation, so after the task was finished, we need to hide the widget.

Circular ProgressBar widget
Figure: Circular ProgressBar widget
]]>
1455
Android SeekBar Widget https://shishirkant.com/android-seekbar-widget/?utm_source=rss&utm_medium=rss&utm_campaign=android-seekbar-widget Sat, 30 May 2020 15:47:36 +0000 http://shishirkant.com/?p=1452 The SeekBar widget is used to select a value from a range of values. The user drags a thumb of the widget to select a specific value. To process the SeekBar events, we implement the SeekBar.OnSeekBarChangeListener listener.

SeekBar example

We have a SeekBar widget and a TextView widget. The current value from the SeekBar is displayed in the TextView. Android manifest file is left untouched.

main.xml

<?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"
    >  
<SeekBar
   android:id="@+id/sbId"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content"
   android:layout_margin="10dp"
   android:max="100"
   android:progress="50"
   />
<TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    />     
</LinearLayout>

In the main.xml layout file, we have two widgets defined. The SeekBar widget and the TextView widget.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">SeekBar</string>
    <string name="init_tv_value">50</string>
</resources>

This is strings.xml resource file. The init_tv_value is the initial value of the TextView widget.

MainActivity.java

package com.shishirkant.seekbar;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class MainActivity extends Activity implements 
    OnSeekBarChangeListener
{
    TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        SeekBar sb = (SeekBar) findViewById(R.id.sbId);
        sb.setOnSeekBarChangeListener(this);

        tv = (TextView) findViewById(R.id.tvId);
        String val = this.getString(R.string.init_tv_value);
        tv.setText(val);
    }

   @Override
   public void onProgressChanged(SeekBar seekBar, int progress,
     boolean fromUser) 
   {
       tv.setText(String.valueOf(progress));
   }

   @Override
   public void onStartTrackingTouch(SeekBar seekBar) 
   {
       // not implemented 
   }

   @Override
   public void onStopTrackingTouch(SeekBar seekBar) 
   {
       // not implemented 
   }
}

The current value from the SeekBar is set to the TextView widget.

public class MainActivity extends Activity implements 
    OnSeekBarChangeListener

The MainActivity class implements the OnSeekBarChangeListener. We need to define three abstract methods. The onProgressChanged(), the onStartTrackingTouch() and the onStopTrackingTouch() method. The last two methods are not implemented. They are related to touch gestures. We provide only empty methods.

SeekBar sb = (SeekBar) findViewById(R.id.sbId);
sb.setOnSeekBarChangeListener(this);

We get the reference to the SeekBar widget and set a listener for it.

tv = (TextView) findViewById(R.id.tvId);
String val = this.getString(R.string.init_tv_value);
tv.setText(val);

We get the reference to the TextView widget. We retrieve the init_tv_value from the string resources and set it to the TextView.

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
    boolean fromUser) 
{
    tv.setText(String.valueOf(progress));
}

When we move the thumb of the SeekBar, the onProgressChanged() method is called. The progress parameter is the current value of the SeekBar. The default range is 0..100. We set the current value of the SeekBar to the TextView widget.

SeekBar widget
Figure: SeekBar widget
]]>
1452
Android Spinner Widget https://shishirkant.com/android-spinner-widget/?utm_source=rss&utm_medium=rss&utm_campaign=android-spinner-widget Sat, 30 May 2020 15:45:11 +0000 http://shishirkant.com/?p=1447

A spinner widget enables a user to select an item from a list of options. In the normal state it shows the currently selected item. Clicking on the spinner widget shows a dropdown menu with all available items. The user can choose a new one from the list. The Spinner class is used to create a spinner widget.

The Spinner widget can be populated in the XML file. Or it can be programmatically filled. In the latter case we need an Adapter class to populate the Spinner widget. An adapter is a bridge between a Spinner and its data.

Spinner I

In the first example we have a Spinner widget whose items are defined in an XML file.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.shishirkant.finish"
      android:versionCode="1"
      android:versionName="1.0">
 <application android:label="@string/app_name" android:icon="@drawable/ic_launcher">
    <activity android:name="MainActivity"
                android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
 </application>
</manifest>

This is the manifest file for the program.

main.xml

<?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"
    >
   <Spinner
        android:id="@+id/spn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:entries="@array/dlangs"
        android:layout_marginTop="10dip"
        android:prompt="@string/spn_title" />

   <TextView
      android:id="@+id/tvId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content" 
      android:layout_marginTop="10dip"
      />        
        
</LinearLayout>

In the main.xml layout file, we have a Spinner and a TextView. The android:entries="@array/dlangs" attribute defines a XML resource that provides an array of strings. The strings are written in the strings.xml file.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Spinner</string>
    <string name="spn_title">Choose a language</string>
    
    <string-array name="dlangs">
        <item>Python</item>
        <item>PHP</item>
        <item>Perl</item>
        <item>Tcl</item>
        <item>Ruby</item>
    </string-array>    
    
</resources>

In the strings.xml file we have the elements of the string array. These are displayed when we click on the Spinner widget.

MainActivity.java

package com.shishirkant.spinner;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import android.widget.Spinner;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;


public class MainActivity extends Activity implements OnItemSelectedListener 
{
    private TextView tv;

    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        tv = (TextView) findViewById(R.id.tvId);

        Spinner spn = (Spinner) findViewById(R.id.spn);
        spn.setOnItemSelectedListener(this);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) 
    {
      String item = parent.getItemAtPosition(pos).toString();
      tv.setText(item);
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) 
    {      
      tv.setText("");
    }
}

The selected item from the Spinner widget is displayed in the TextView widget.

public class MainActivity extends Activity implements OnItemSelectedListener 

The MainActivity class implements the OnItemSelectedListener. The class must now implement two methods. The onItemSelected() and onNothingSelected() methods.

Spinner spn = (Spinner) findViewById(R.id.spn);
spn.setOnItemSelectedListener(this);

These two lines get the reference to the Spinner widget and set the OnItemSelectedListener for it.

@Override
public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) 
{
    String item = parent.getItemAtPosition(pos).toString();
    tv.setText(item);
}

In the onItemSelected() method we get the currently selected Spinner item with the getItemAtPosition(). The item is transformed to a string and set to the TextView.

Spinner widget
Figure: Spinner widget

Spinner II

In the second spinner example, we will define our list of spinner elements programmatically. For this we will use the ArrayAdapter in conjunction with the ArrayList.

An Adapter design pattern is used by Android platform to work with the Spinner widget. The ArrayAdapter is an intermediary between the data source and the data view. In this case the data source is the ArrayList and the view is the Spinner widget. Using an adapter we are decoupling our code.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.shishirkant.toast"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" 
            android:icon="@drawable/ic_launcher">
        <activity android:name="MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

This is the manifest file.

main.xml

<?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"
    >
    
  <Spinner
      android:id="@+id/spnId"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:layout_marginTop="10dip" 
      android:prompt="@string/spn_title" />    
      
  <TextView
    android:id="@+id/tvId"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_marginTop="10dip"  />
    
</LinearLayout>

In the main.xml file we have two widgets. The Spinner and the TextView widget. This time we do not define the array data entries for the Spinner.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Spinner2</string>
    <string name="spn_title">Choose a language</string>
</resources>

This is the strings.xml resource file.

MainActivity.java

package com.shishirkant.spinner2;

import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Spinner;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;


public class MainActivity extends Activity implements OnItemSelectedListener
{
    private TextView tv;
    private Spinner spn;
    
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        setup();
    }

    public void setup()
    {
        tv = (TextView) findViewById(R.id.tvId);
   
        spn = (Spinner) findViewById(R.id.spnId);
        fillSpinner(spn);
        spn.setOnItemSelectedListener(this);
    }

    public void fillSpinner(Spinner spn) 
    {
        List<String> lst = new ArrayList<String>();
        lst.add("Python");
        lst.add("PHP");
        lst.add("Perl");
        lst.add("Tcl");
        lst.add("Ruby");
        
        ArrayAdapter<String> da = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, lst);
        da.setDropDownViewResource(android.R.layout.simple_spinner_item);

        spn.setAdapter(da);
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View v, int pos, long id) 
    {
      String item = parent.getItemAtPosition(pos).toString();
      tv.setText(item);
    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) 
    {      
      tv.setText("");
    }
}

In the MainActivity.java source file we fill the Spinner widget with data and implement the OnItemSelectedListener for the widget.

spn = (Spinner) findViewById(R.id.spnId);
fillSpinner(spn);

We get the reference to the Spinner widget and call the fillSpinner() method to populate it with data.

List<String> lst = new ArrayList<String>();
lst.add("Python");
lst.add("PHP");
lst.add("Perl");
lst.add("Tcl");
lst.add("Ruby");

An ArrayList is created and filled with strings.

ArrayAdapter<String> da = new ArrayAdapter<String>(this,
        android.R.layout.simple_spinner_item, lst);

The instance of the ArrayAdapter is created. It takes the ArrayList as a parameter.

da.setDropDownViewResource(android.R.layout.simple_spinner_item);

This line determines the look of the dropdown menu of the Spinner widget. This one is a dropdown without radio buttons. A spinner with the android.R.layout.simple_spinner_dropdown_item defined has radio buttons in its rows.

spn.setAdapter(da);

The adapter is set for the Spinner widget.

Spinner dropdown menu
Figure: Spinner dropdown menu
]]>
1447
Layout Management in Android https://shishirkant.com/layout-management-in-android/?utm_source=rss&utm_medium=rss&utm_campaign=layout-management-in-android Sat, 30 May 2020 15:39:56 +0000 http://shishirkant.com/?p=1442 When we design the user interface of our application, we decide what components we will use and how we will organise those components in the application. To organise our components, we use specialised non visible objects called layout managers.

There are several layout managers in Android. A LinearLayout lines up its views in one row or column. A FrameLayout is a simple layout manager used to display one view. A RelativeLayout is a layout manager in which the views are positioned in relation to each other or to the parent. The most powerful layout manager is the GridLayout manager. It arranges the views in a grid.

Showing an image with FrameLayout

The first example shows an image using the FrameLayout manager.

$ ls res/drawable-hdpi/
ic_launcher.png  zamok.jpg

Depending on a android virtual device we are using, we put the image in the corresponding subdirectory of the res directory.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_gravity="top"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >
    
 <ImageView  
        android:layout_height="match_parent"  
        android:layout_width="match_parent"  
        android:src="@drawable/zamok"  />
        
</FrameLayout>

In the FrameLayout manager, we put one ImageView.

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_gravity="top"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    >

The FrameLayout is big enough to display the ImageView by setting the layout width and height to wrap_content. It is pushed to the top using the layout_gravity attribute.

<ImageView  
    android:layout_height="match_parent"  
    android:layout_width="match_parent"  
    android:src="@drawable/zamok"  />

The ImageView displays an image. The image is located in a subdirectory of the res directory.

Showing an image with a FrameLayout
Figure: Showing an image with a FrameLayout

A row of buttons

In the example we create a row of four buttons.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    
  <Button
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:text="Button1" />

  <Button
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:text="Button2" />
      
  <Button
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:text="Button3" />
      
  <Button
      android:layout_height="wrap_content"
      android:layout_width="wrap_content"
      android:text="Button4" />      
      
</LinearLayout>

We have a horizontal LinearLayout. In this layout, we add four buttons.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

We create a horizontal LinearLayout manager. The width and height of the layout match the parent which means that it fills the entire screen.

<Button
    android:layout_height="wrap_content"
    android:layout_width="wrap_content"
    android:text="Button1" />

Each of the four buttons use the wrap_content property. They are then just big enough to display their content.

A row of buttons
Figure: A row of buttons

A row of buttons II

In the third example of this chapter, we show how to programmatically create a row of buttons with a LinearLayout manager.

MainActivity.java

package com.shishirkant.btnrow2;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.LinearLayout;

public class ButtonRow2 extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        
        initUI();
    }

    public void initUI()
    {
        Button btn1 = new Button(this);
        btn1.setText("Button");

        Button btn2 = new Button(this);
        btn2.setText("Button");

        Button btn3 = new Button(this);
        btn3.setText("Button");

        Button btn4 = new Button(this);
        btn4.setText("Button");

        LinearLayout ll = new LinearLayout(this);
        ll.setOrientation(LinearLayout.HORIZONTAL);

        ll.addView(btn1);
        ll.addView(btn2);
        ll.addView(btn3);
        ll.addView(btn4);

        setContentView(ll);
    }
}

Four buttons are placed in a horizontal LinearLayout. We will not use the layout XML file in this sample.

Button btn1 = new Button(this);
btn1.setText("Button");

Button widget is created. The text is set for the button with the setText() method.

LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.HORIZONTAL);

A horizontal LinearLayout is created.

ll.addView(btn1);
ll.addView(btn2);
ll.addView(btn3);
ll.addView(btn4);

Buttons are added to the layout manager.

setContentView(ll);

The linear layout manager is set to be the content view of the activity.

A column of Buttons

We use the FrameLayout and the LinearLayout managers to create a column of buttons centered on the screen.

main.xml

<?xml version="1.0" encoding="utf-8"?>  
<FrameLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"
    android:layout_gravity="center" 
    >  
    
  <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      >

      <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"    
        android:text="Button" />    
        
      <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"    
        android:text="Button" />    
        
      <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"    
        android:text="Button" />    
        
      <Button
        android:layout_height="wrap_content"
        android:layout_width="wrap_content"    
        android:text="Button" />           
    
  </LinearLayout>

</FrameLayout>    

A LinearLayout manager with four buttons is placed in the FrameLayout manager.

<FrameLayout  
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:layout_width="wrap_content"  
    android:layout_height="wrap_content"
    android:layout_gravity="center" 
    > 

The FrameLayout does not occupy all the available space. It is just big enough to take all the four buttons. And therefore we can use the layout_gravity attribute to center the LinearLayout and its four buttons.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >

A vertical LinearLayout is created.

A column of buttons
Figure: A column of buttons

RelativeLayout

RelativeLayout lets child views specify their position relative to the parent view or to each other. The views are referenced by their ids.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    
    <EditText
      android:id="@+id/etId"
      android:layout_marginTop="10dp"      
      android:layout_width="match_parent"
      android:layout_height="wrap_content" />  
        
    <Button
      android:id="@+id/btn_sendId"
      android:layout_below="@+id/etId"
      android:layout_width="wrap_content"               
      android:layout_height="wrap_content"      
      android:text="Send" />          
          
    <Button
      android:id="@+id/btn_clearId"
      android:layout_below="@+id/etId"
      android:layout_toRightOf="@+id/btn_sendId"
      android:layout_width="wrap_content"               
      android:layout_height="wrap_content"      
      android:text="Clear" />    
      
</RelativeLayout>  

The XML code displays an EditText with two buttons.

<EditText
    android:id="@+id/etId"
    android:layout_marginTop="10dp"      
    android:layout_width="match_parent"
    android:layout_height="wrap_content" /> 

The EditText will be stretched from right to left by setting the android:layout_width to android:match_parent. The widget will be high enough to show its contents. We specify some gap between the widget and the border of the screen with android:layout_marginTop property.

<Button
    android:id="@+id/btn_sendId"
    android:layout_below="@+id/etId"
    android:layout_width="wrap_content"               
    android:layout_height="wrap_content"      
    android:text="Send" />   

The Send button widget will be placed below the EditText widget. To accomplish this, we use the android:layout_below property. Note that we reference the id of the widget that we relate to.

<Button
    android:id="@+id/btn_clearId"
    android:layout_below="@+id/etId"
    android:layout_toRightOf="@+id/btn_sendId"
    android:layout_width="wrap_content"               
    android:layout_height="wrap_content"      
    android:text="Clear" />   

The Clear button is placed below the EditText widget and to the right of the Send button. We accomplish this by two properties. The android:layout_below and the android:layout_toRightOf property.

RelativeLayout example
Figure: RelativeLayout example

Grid

GridLayout manager places its children in a rectangular grid. The grid consists of row and columns. The intersections of rows and columns are cells. Each cell is referenced by its index. A view in a grid can occupy one or more cells. The gravity is a property that specifies how a view should be placed in its group of cells.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent" 
    android:layout_height="match_parent"
    >
    
    <Button
      android:text="(0, 0)"      
      android:layout_row="0"              
      android:layout_column="0" />    
      
    <Button
      android:layout_row="0"              
      android:layout_column="1" 
      android:layout_columnSpan="2"
      android:layout_gravity="fill_horizontal" />       
      
    <Button
      android:text="(0, 3)"      
      android:layout_row="0"              
      android:layout_column="3" />       
    
    <Button
      android:text="(0, 4)"     
      android:layout_row="0"              
      android:layout_column="4" />       
      
    <Button      
      android:layout_row="1"
      android:layout_column="0"
      android:layout_rowSpan="3" 
      android:layout_columnSpan="5" 
      android:layout_gravity="fill" />   
      
    <Button
      android:text="Center"      
      android:layout_row="4"
      android:layout_column="0"
      android:layout_columnSpan="5" 
      android:layout_gravity="center_horizontal" />      
      
    <Button
      android:text="Right"      
      android:layout_row="5"
      android:layout_column="0"
      android:layout_columnSpan="5" 
      android:layout_gravity="right" />           
    
</GridLayout>

In the example we put a few buttons in a GridLayout. We show how a button can stretch over several cells.

<Button
    android:text="(0, 0)"      
    android:layout_row="0"              
    android:layout_column="0" />  

Using the layout_row and layout_column properties, we place a button at top-left cell. The indeces start from zero.

<Button
    android:layout_row="0"              
    android:layout_column="1" 
    android:layout_columnSpan="2"
    android:layout_gravity="fill_horizontal" /> 

This button will span two columns. The layout_gravity property will cause the button to fill the two columns.

<Button      
    android:layout_row="1"
    android:layout_column="0"
    android:layout_rowSpan="3" 
    android:layout_columnSpan="5" 
    android:layout_gravity="fill" /> 

This button will span three rows and five columns.

<Button
    android:text="Center"      
    android:layout_row="4"
    android:layout_column="0"
    android:layout_columnSpan="5" 
    android:layout_gravity="center_horizontal" />  

A view may not occupy all the space that was allotted to it. This button is horizontally centered within five columns.

GridLayout example
Figure: GridLayout example
]]>
1442
Android Intents https://shishirkant.com/android-intents/?utm_source=rss&utm_medium=rss&utm_campaign=android-intents Sat, 30 May 2020 15:34:22 +0000 http://shishirkant.com/?p=1438 According to the Android developer documentation, an Intent is an asynchronous message. It is an abstract description of an operation to be performed. Intents are used to navigate through activities. Activities, services and broadcast receivers are activated through intents. Intents enable loose coupling of code in the application. An Intent is passed to the some method like Context.startActivity() or Context.startService() to perform some action.

There are two types of intents: explicit and implicit. In explicit intents you provide the name of the Activity class. In implicit intents, you tell the system what to do rather than name the Activity class to launch.

Implicit Intent

Displaying a web page can be done via an implicit intent. It will start a default web browser with the specified web page. In the example we will display the contents of a web page. The manifest file is not modified.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
 
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:onClick="onClicked"
        android:text="@string/btn_title" />
 
</LinearLayout>

In the main.xml layout file, we have just a simple button widget. Clicking on the button will show the web page.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Url</string>
    <string name="btn_title">Visit</string>
</resources>

String resources.

MainActivity.java

package com.shishirkant.url;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.net.Uri;
import android.view.View;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClicked(View view)
    {
        Intent intent =  new Intent(Intent.ACTION_VIEW, 
            Uri.parse("http://www.google.com"));
        startActivity(intent);        
    }
}

This is the MainActivity.java source file.

public void onClicked(View view)
{
    Intent intent =  new Intent(Intent.ACTION_VIEW, 
        Uri.parse("http://www.google.com"));
    startActivity(intent);        
}

In the onClicked() method, we create an Intent object and start a new activity. With this implicit intent, we tell Android to start a default web browser with google.com web page opened.

Web page in Android emulator
Figure: Web page in Android emulator

Explicit intent

In explicit intents, we provide the exact class to be run.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.shishirkant.explicit"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name" 
            android:icon="@drawable/ic_launcher">
        <activity android:name="MainActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:name=".NextActivity"></activity>
        
    </application>
</manifest>

In the manifest file we register the new activity under the name NextActivity. The leading dot is a shorthand for the full package name, com.shishirkant.explicit in our case.

main.xml

<?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"
    >
    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:onClick="onClicked"
        android:text="@string/btn_title" />        
</LinearLayout>

In the main.xml file we have one button. Clicking on this button will start a new explicit activity.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Explicit</string>
    <string name="btn_title">Next</string>
</resources>

This is the strings.xml resource file.

$ ls src/com/shishirkant/explicit/
MainActivity.java  NextActivity.java

In the src/com/zetcode/explicit subdirectory we have two source files for two activities.

MainActivity.java

package com.shishirkant.explicit;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.content.Intent;

public class MainActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

    public void onClicked(View view)
    {
        Intent intent =  new Intent(this, NextActivity.class);
        startActivity(intent);        
    }
}

This is the source for the main activity. In the onClicked() method, we start a new explicit intent.

public void onClicked(View view)
{
    Intent intent =  new Intent(this, NextActivity.class);
    startActivity(intent);        
}

The second parameter of the Intent constructor is the class name to be invoked. The activity is started with the startActivity() method.

NextActivity.java

package com.shishirkant.explicit;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.LinearLayout;

public class NextActivity extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        initUI();
    }

    public void initUI()
    {
        LinearLayout lay = new LinearLayout(this);
        
        TextView tv = new TextView(this);
        tv.setText("Next screen");
        lay.addView(tv);

        setContentView(lay);
    }
}

This is the NextActivity.java source code. In this activity, we show a TextView on the screen. It is programmatically placed into a linear layout.

Transferring Data

Intents are used to transfer data from one activity to another. We use the putExtra() method to add extra data to an intent. In the following example, we write a name to the edit text and click on the Send button. We will land on another screen where we will see a greeting to the name that we have entered.

$ ls res/layout/
screen1.xml  screen2.xml
$ ls src/com/shishirkant/switch2/
FirstScreen.java  SecondScreen.java

In the res/layout directory we have two XML layout files. In the src/com/shishirkant/switch2 we have source files of two activities.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.shishirkant.switch2"
      android:versionCode="1"
      android:versionName="1.0">
    <application android:label="@string/app_name"
                    android:icon="@drawable/ic_launcher">
        <activity android:name=".FirstScreen">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
        <activity android:name=".SecondScreen"></activity>
        
    </application>
</manifest>

In the manifest file we define two activities: the FirstScreen and the SecondScreen activity. The FirstScreen is the main activity.

screen1.xml

<?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"
    >
  <EditText android:id="@+id/editId"
          android:layout_width="fill_parent"
          android:layout_height="wrap_content"
          android:layout_marginTop="10dip"
          android:layout_marginBottom="10dip"
          android:hint="@string/etHint" />    
          
  <Button
          android:layout_width="wrap_content"
          android:layout_height="wrap_content"
          android:text="@string/btn_send" 
          android:onClick="sendMessage" />      
</LinearLayout>

The screen1.xml layout file is loaded by the FirstScreen activity. It displays an EditText and a Button widget. The android:hint attribute shows a default shaded text in the EditText.

screen2.xml

<?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"
    >
  <TextView
      android:id="@+id/tvId"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      />
</LinearLayout>

In the screen2.xml file we have one TextView widget. It will display the text that we will transfer from one screen to another. It is loaded by the SecondScreen activity.

strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">Switch</string>
    <string name="etHint">Enter your name</string>
    <string name="btn_send">Send</string>
</resources>

This is the strings.xml resource file.

FirstScreen.java

package com.shishirkant.switch2;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.view.View;
import android.widget.EditText;

public class FirstScreen extends Activity
{
    private EditText iname;
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        setTitle("First screen");
        setContentView(R.layout.screen1);

        iname = (EditText) findViewById(R.id.editId);
    }

    public void sendMessage(View view) 
    {
        Intent switchTo = new Intent(this, SecondScreen.class);        
        switchTo.putExtra("name", iname.getText().toString());        
        startActivity(switchTo); 
    }
}

The FirstScreen is the main activity. The sendMessage() method is called, when we click on the button.

public void sendMessage(View view) 
{
    Intent switchTo = new Intent(this, SecondScreen.class);        
    switchTo.putExtra("name", iname.getText().toString());        
    startActivity(switchTo); 
}

In the sendMessage() method, we create an instance of an Intent. It will direct us to the SecondScreen activity. With the putExtra() method, we add data from the EditText to the intent. The first parameter is the name by which we will refer the data. The second parameter is the data to be transferred.

SecondScreen.java

package com.shishirkant.switch2;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.widget.TextView;

public class SecondScreen extends Activity
{
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.screen2);

        setupUI();
    }

    void setupUI()
    {
        setTitle("Second screen");

        TextView tv = (TextView) findViewById(R.id.tvId);
        
        Intent i = getIntent();
        String name = i.getStringExtra("name");        
        tv.setText("You have entered: " + name);
    }
}

This is the SecondScreen.java source file. It is called by the FirstScreen activity.

setupUI();

In the setupUI() method, we set up the user interface of the screen.

setTitle("Second screen");

We give the title to the screen with the setTitle() method.

Intent i = getIntent();
String name = i.getStringExtra("name");        
tv.setText("You have entered: " + name);

The getIntent() method returns the intent that started the activity. We get the extra data using the getStringExtra() method. The data is set to the TextView.

]]>
1438