Activities are equivalent to forms, and can be call directly by any other activity or app.
findViewById()
is a way to locate resources within Activity.
Example 1:
public class MainActivity extends AppCompatActivity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button btnAdd = (Button) findViewById(R.id.btnAdd); btnAdd.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Do something, such as add to values EditText txtVal1 = (EditText) findViewById(R.id.txtVal1); EditText txtVal2 = (EditText) findViewById(R.id.txtVal2); int val1 = (int) Integer.parseInt(txtVal1.getText().toString()); int val2 = (int) Integer.parseInt(txtVal2.getText().toString()); int result = val1 + val2; final TextView lblResult = (TextView) findViewById(R.id.lblResult); lblResult.SetText(result + ""); // append empty string to convert operation to string Log.d("MyApp", "We clicked a button!"); Toast.makeText(this, "We clicked a button!", Toast.LENGTH_SHORT).show(); } }); } }
Example 2: Sharing onClickListener with multiple buttons in same Activity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener { // Resources private TextView txt; private Button btn; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); txt = (TextView) findViewById(R.id.txtTest); btn = (Button) findViewById(R.id.btnTest); btn.setOnClickListener(this); } @Override public void onClick(View view) { // do something switch(view.getId()) { case R.id.btnTest: Log.d("MyApp", "We clicked a button!"); txt.SetText("We clicked a button!"); Toast.makeText(this, "YEs!!", Toast.LENGTH_SHORT).show(); break; // case ... } } }
Call for an activity into action (your own or other apps), which can carry a data payload. Eg: Calling dialer from your app, or calling email client when sending an email, or calling a new activity from within your app.
To deliver an intent:
To handle an intent:
Intents that do not define which activity will handle the request, but rather seek a registered app to handle the provided data payload.
// Call dialer app to handle phone number Intent intentDialNumber = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:4071233500")); if (intentDialNumber.resolveActivity(getPackageManager()) != null) { startActivity(intentDialNumber); } // Call contacts to handle contact selection Intent intentSelectContact = new Intent(Intent.ACTION_DIAL, new Uri("content://contacts")); if (intentSelectContact.resolveActivity(getPackageManager()) != null) { startActivity(intentSelectContact); } // Call web browser to handle URL Intent intentViewWebsite = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.acme.com")); if (intentViewWebsite.resolveActivity(getPackageManager()) != null) { startActivity(intentViewWebsite); } // Call a mapping app to handle geolocation (lat,long,zoom) Intent intentShowLocation = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:28.6027902,-81.4232732,14z")); if (intentShowLocation.resolveActivity(getPackageManager()) != null) { startActivity(intentShowLocation); } // Display all activities supporting Action View that can handle intent Intent intentShowAllActivities = new Intent(Intent.ACTION_VIEW); if (intentShowAllActivities.resolveActivity(getPackageManager()) != null) { startActivity(intentShowAllActivities); }
Intents that fully define the required activity that should handle the action and its data payload.
For example, in the MainActivity
, you can define an intent:
//... public class MainActivity extends AppCompatActivity { @Override public void onClick(View view) { switch(view.getId()) { case R.id.btnShowIntent: Intent intentDataHandler = new Intent(this, TargetActivity.class); intentDataHandler.putExtra("Key1", "Value1"); // data payload (optional) intentDataHandler.putExtra("Key2", "Value2"); // data payload (optional) intentDataHandler.putExtra("com.acme.myapp.Key3", "Value3"); // use full path with key (recommended) intentDataHandler.putExtra("Key4.TEAM_OBJ", aTeamObj); // parcelable object (eg. object of type Team) startActivity(intentDataHandler); break; } } }
In your target activity, retrieve the intent as follows:
//... public class TargetActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(saveInstanceState); setContentView(R.layout.activity_target); //----------------------------------- // Get data payload (if available) //----------------------------------- // Method 1 Bundle bundle = getIntent().getExtras(); String str = bundle.getString("Key1"); Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); // Method 2 Intent intent = getIntent(); if (intent.hasExtra("Key2")) { str = intent.getExtras().getString("Key2"); Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } // Method 3 if (getIntent().hasExtra("Key3")) { str = getIntent().getExtras().getString("Key3"); Toast.makeText(this, str, Toast.LENGTH_SHORT).show(); } // Parcelable data Team objTeam; if (intent.hasExtra("Key4.TEAM_OBJ")) { Log.d("MyApp", "Retrieving intent extras..."); objTeam = intent.getParcelableExtra("Key4.TEAM_OBJ"); Toast.makeText(this, "Team Name: "+ objTeam.name, Toast.LENGTH_SHORT).show(); } } }
A parcelable extra must be of a type supporting parcelable. For example:
package com.acme.myapp; import android.os.Parcel; import android.os.Parcelable; public class Team implements Parcelable { public long id = 0; public String name = ""; public String number = ""; public int ranking = 0; // Default constructor Team() { } // In constructor, read variables from Parcel. // Important: Read them in the same sequence in which they were written in Parcel. public Team(Parcel in) { id = in.readLong(); name = in.readString(); number = in.readString(); ranking = in.readInt(); } @Override public int describeContents() { return 0; } // Write member variables in Parcel. // Write in any order. Not required to write all members in Parcel. @Override public void writeToParcel(Parcel dest, int flags) { // Write data in any order dest.writeLong(id); dest.writeString(name); dest.writeString(number); dest.writeInt(ranking); } // De-serialize the object public static final Parcelable.Creator<Team> CREATOR = new Parcelable.Creator<Team>(){ public Team createFromParcel(Parcel in) { return new Team(in); } public Team[] newArray(int size) { return new Team[size]; } }; }
For example, in the MainActivity
, you can define an intent:
//... public class MainActivity extends AppCompatActivity implements View.OnClickListener { // Resources private TextView txtHello; private Button btnDialNumber; private Button btnViewWebsite; //... @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); txtHello = (TextView) findViewById(R.id.txtHello); btnDialNumber = (Button) findViewById(R.id.btnDialNumber); btnDialNumber.setOnClickListener(this); btnViewWebsite= (Button) findViewById(R.id.btnViewWebsite); btnViewWebsite.setOnClickListener(this); //... } @Override public void onClick(View view) { switch(view.getId()) { case R.id.btnDialNumber: Intent intentDialNumber = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:4071233500")); if (intentDialNumber.resolveActivity(getPackageManager()) != null) { startActivity(intentDialNumber); } break; case R.id.btnViewWebsite: Intent intentViewWebsite = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.acme.com")); if (intentViewWebsite.resolveActivity(getPackageManager()) != null) { startActivity(intentViewWebsite); } break; case R.id.btnShowLocation: Intent intentShowLocation = new Intent(Intent.ACTION_VIEW, Uri.parse("geo:28.6027902,-81.4232732,14z" // lat,long,zoom )); if (intentShowLocation.resolveActivity(getPackageManager()) != null) { startActivity(intentShowLocation); } break; case R.id.btnShowAllActivities: // Display all activities supporting Action View that can handle intent Intent intentShowAllActivities = new Intent(Intent.ACTION_VIEW); if (intentShowAllActivities.resolveActivity(getPackageManager()) != null) { startActivity(intentShowAllActivities); } break; case R.id.btnShowToast: Intent intentShowToast = new Intent(MainActivity.this, SampleActivity.class // target activity ); if (intentShowToast.resolveActivity(getPackageManager()) != null) { startActivity(intentShowToast); } break; case R.id.btnShowSampleActivity: Intent intentShowSampleActivity = new Intent("com.acme.myapp.SampleActivity"); if (intentShowSampleActivity.resolveActivity(getPackageManager()) != null) { startActivity(intentShowSampleActivity); } break; } } }
activity_main.xml
:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.acme.myapp.MainActivity"> <Button android:id="@+id/btnDialNumber" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="24dp" android:text="@string/live" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <Button android:id="@+id/btnViewWebsite" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="@string/archives" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.501" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/btnDialNumber" /> <!-- More controls ... --> </android.support.constraint.ConstraintLayout>
In the manifest.xml
, you can add intent filters:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.acme.myapp"> <application ...> <activity android:name=".MainActivity" android:label="@string/app_name" android:theme="@style/AppTheme.NoActionBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".SampleActivity"> <intent-filter> <!-- Action Name to call directly --> <action android:name="com.acme.myapp.SampleActivity" /> <!-- Action Category. Required when including an action name --> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name=".Sample2Activity"> <intent-filter> <!-- Optional: Action Type by which to respond --> <action android:name="android.intent.action.VIEW" /> <!-- Action Category. Required when including an action name --> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> </application> </manifest>
Log.d("MyAppTag", "A debug message"); // standard debug message Log.e("MyAppTag", "A debug message"); // error message Log.w("MyAppTag", "A debug message"); // warning message Log.i("MyAppTag", "A debug message"); // info message
Under resources (app
> res
> values
), add string arrays in strings.xml
. These will be data bound to a ListView
control:
<resources> <!-- Other resources... --> <string name="app_name">MyApp</string> <!-- String arrays for ListView --> <string-array name="arrProducts"> <item>Table</item> <item>Chair</item> <item>Stool</item> </string-array> <string-array name="arrPrices"> <item>$1.00</item> <item>$1.50</item> <item>$1.25</item> </string-array> <string-array name="arrColors"> <item>Red</item> <item>Blue</item> <item>Green</item> </string-array> </resources>
In the default onCreate()
method, add references to the ListView
:
package com.acme.myapp; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // ADD ListView here... } }
Add a ListView
with a custom item view using an ItemAdapter
. You can choose the type of item view:
To use a custom layout based on TextView
layout, create ListViewDetail layout:
app
> res
> layout
. Right-click and select New
> Layout resource file
.listview_detail
TextView
Activity code:
public class MainActivity extends AppCompatActivity { // Properties ListView lstProducts; String[] arrProducts; String[] arrPrices; String[] arrColors; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Resources res = getResources(); lstProducts = (ListView) findViewById(R.id.lstProducts); arrProducts = res.getStringArray(R.array.arrProducts); arrPrices = res.getStringArray(R.array.arrPrices); arrColors = res.getStringArray(R.array.arrColors); // Example: Using layout resource based on TextView lstProducts.setAdapter(new ArrayAdapter<String>( this, // context R.layout.listview_detail, // detail view layout arrProducts // data )); } }
You will need the following:
To use a custom layout based on RelativeLayout
or ConstraintLayout
, create ListViewDetail layout:
app
> res
> layout
. Right-click and select New
> Layout resource file
.listview_detail
RelativeLayout
or ConstraintLayout
Activity code:
import com.acme.myapp.ItemAdapter; public class MainActivity extends AppCompatActivity { ListView lstProducts; String[] arrProducts; String[] arrPrices; String[] arrColors; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Resources res = getResources(); lstProducts = (ListView) findViewById(R.id.lstProducts); arrProducts = res.getStringArray(R.array.arrProducts); arrPrices = res.getStringArray(R.array.arrPrices); arrColors = res.getStringArray(R.array.arrColors); // Example: Using custom ItemAdapter with custom layout ItemAdapter itemAdapter = new ItemAdapter( this, // context arrProducts, arrPrices, arrColors // data ); lstProducts.setAdapter(itemAdapter); } }
Create class ItemAdapter
app
> java
> <your app package name>
. Right-click and select New
> Java Class
.ItemAdapter
Class
android.widget.BaseAdapter
package com.acme.myapp; import android.content.Context; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.TextView; public class ItemAdapter extends BaseAdapter { // Properties LayoutInflater mInflater; String[] arrProducts; String[] arrPrices; String[] arrColors; // // Constructor: Create custom contructor so properties get assigned right away // public ItemAdapter(Context cx, String[] prod, String[] prices, String[] colors) { arrProducts = prod; arrPrices = prices; arrColors = colors; mInflater = (LayoutInflater) cx.getSystemService(Context.LAYOUT_INFLATER_SERVICE); } @Override public int getCount() { return arrProducts.length; } @Override public Object getItem(int idx) { return arrProducts[idx]; } @Override public long getItemId(int idx) { return idx; } @Override public View getView(int idx, View view, ViewGroup viewGroup) { // Use layout inflater. Use listview_detail.xml layout View vw = mInflater.inflate(R.layout.listview_detail, null); TextView txtProduct = (TextView) vw.findViewById(R.id.txtProduct); TextView txtPrice = (TextView) vw.findViewById(R.id.txtPrice); TextView txtColor = (TextView) vw.findViewById(R.id.txtColor); String strProduct = arrProducts[idx]; String strPrice = arrPrices[idx]; String strColor = arrColors[idx]; txtProduct.setText(strProduct); txtPrice.setText(strPrice); txtColor.setText(strColor); return vw; } }
app
> res
> drawable
folder in project tree.TextView
control for item name and description.ImageView
control for item image.
Add an ItemClickListener
for the ListView
in MainActivity
activity. This will launch the secondary activity with the ListView
item details:
protected void onCreate(Bundle savedInstanceState) { // ... lstTeams.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Log.d("RoboticsLeague", "Loading rubric for Team " + (position+1)); Toast.makeText(getApplicationContext(), "Loading rubric for Team " + (position+1), Toast.LENGTH_SHORT).show(); Intent showRubricActivity = new Intent(getApplicationContext(), RobotRubricActivity.class); showRubricActivity.putExtra("com.voirtech.roboticsleague.TEAM_ID", (position+1)+""); startActivity(showRubricActivity); } }); }
On the secondary activity, process the intent:
package com.acme.roboticsleague; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; public class RobotRubricActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_robot_rubric); Intent intent = getIntent(); String strTeamId = intent.getExtras().getString("com.acme.roboticsleague.TEAM_ID"); TextView lblTeamId = (TextView) findViewById(R.id.lblTeamId); lblTeamId.setText("Team " + strTeamId); Button btnSaveRubric = (Button) findViewById(R.id.btnSaveRubric); btnSaveRubric.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { // Do something, such as add to values SeekBar barDurability = (SeekBar) findViewById(R.id.barDurability); SeekBar barMechanicalEfficiency = (SeekBar) findViewById(R.id.barMechanicalEfficiency); SeekBar barMechanization = (SeekBar) findViewById(R.id.barMechanization); String valDurability = (String) (barDurability.getProgress() + ""); String valMechanicalEfficiency = (String) (barMechanicalEfficiency.getProgress() + ""); String valMechanization = (String) (barMechanization.getProgress() + ""); //final TextView lblResult = (TextView) findViewById(R.id.lblResult); //lblResult.SetText(result + ""); // append empty string to convert operation to string String msg = String.format("Saved evaluation at: %s, %s, %s", valDurability, valMechanicalEfficiency, valMechanization); Log.d("RoboticsLeague", msg); Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show(); } }); } }
The secondary activity with item details would look like:
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".RobotRubricActivity"> <TextView android:id="@+id/lblMechanicalDesign" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="8dp" android:layout_marginTop="56dp" android:text="Mechanical Design" android:textStyle="bold" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/lblDurability" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="4dp" android:text="Durability" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lblMechanicalDesign" /> <TextView android:id="@+id/lblMechanicalEfficiency" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="12dp" android:text="Mechanical Efficiency" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lblDurability" /> <TextView android:id="@+id/lblMechanization" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginStart="16dp" android:layout_marginTop="12dp" android:text="Mechanization" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/lblMechanicalEfficiency" /> <TextView android:id="@+id/lblTeamId" android:layout_width="85dp" android:layout_height="27dp" android:layout_marginEnd="268dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Team ID" android:textAlignment="viewStart" android:textSize="18sp" android:textStyle="bold" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.0" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <SeekBar android:id="@+id/barDurability" style="@style/Widget.AppCompat.SeekBar.Discrete" android:layout_width="156dp" android:layout_height="23dp" android:layout_marginEnd="16dp" android:layout_marginTop="76dp" android:max="4" android:progress="3" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> <SeekBar android:id="@+id/barMechanicalEfficiency" style="@style/Widget.AppCompat.SeekBar.Discrete" android:layout_width="156dp" android:layout_height="23dp" android:layout_marginEnd="16dp" android:layout_marginTop="8dp" android:max="4" android:progress="2" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/barDurability" /> <SeekBar android:id="@+id/barMechanization" style="@style/Widget.AppCompat.SeekBar.Discrete" android:layout_width="156dp" android:layout_height="23dp" android:layout_marginEnd="16dp" android:layout_marginTop="8dp" android:max="4" android:progress="3" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toBottomOf="@+id/barMechanicalEfficiency" /> <Button android:id="@+id/btnSaveRubric" android:layout_width="87dp" android:layout_height="34dp" android:layout_marginEnd="8dp" android:layout_marginTop="4dp" android:text="Save" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" /> <TextView android:id="@+id/lblRobotDesignRubric" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginEnd="4dp" android:layout_marginStart="8dp" android:layout_marginTop="8dp" android:text="Robot Design Rubric" android:textSize="18sp" app:layout_constraintEnd_toStartOf="@+id/btnSaveRubric" app:layout_constraintStart_toEndOf="@+id/lblTeamId" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>