22
Mobile App Development Lesson 5 - Spinners, Adapters & Fragment Communication

Spinners, Adapters & Fragment Communication

Embed Size (px)

Citation preview

Mobile App Development

Lesson 5 - Spinners, Adapters & Fragment Communication

Today’s Lesson● More UI Components - Tonight Spinners

● string-array resources

● ArrayAdapter

● Fragment to Fragment comunication

Previous Lesson● Fragments - We create them statically

● String resources

● Multiple Layouts, Multiple Devices = Multiple Layout XML files (use pre-defined names)

● android:weight should be used with LinearLayout

Android UI - Next Steps ● So far we’ve seen Buttons and TextView components.

The next step is Spinners, Pickers & ListView. Spinners this week.

● Spinners are what we commonly know elsewhere as drop-down lists.

● A typical example would be a drop down list containing a list of countries.

● Spinners can be populated statically or dynamically.

Spinner Population● If we are putting a known/pre-defined & fixed list of

values into a Spinner (e.g. List of Countries) we can use a

String array. This is static population.

● As previously mentioned Strings in our app should be defined as String resources (in res/values/strings.xml )

● We can define String arrays in this file as well as just <string> using the <string-array> tag.

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

<resources>

<string name="selectcountry">Choose a country</string>

<string-array name="countryarray">

<item>Ireland</item>

<item>France</item>

<item>Spain</item>

<item>Poland</item>

</string-array>

</resources>

string-array resource

Using string-array● To use the values in the string-array we just defined

we go back to our XML UI file of our Fragment or Activity

● As before we can add a UI component by dragging and dropping it on the UI designer or adding it directly in the XML file.

● Either way the XML UI tag that results is <Spinner>

● We can link the <Spinner> directly to the string-array

resource via the XML.

Spinner & string-array

<Spinner

android:id="@+id/spinner1"

android:layout_width="match_parent"

android:layout_height="wrap_content"

android:entries="@array/country_array"

android:prompt="@string/selectcountry"

/>

● The link is made via the new XML Spinner propertyandroid:entries

● NOTE : android:prompt only has an effect in dialog

mode (explained on next slide)

Getting value from Spinner● By default we end up with a Spinner which looks like

this

1. This is the default type of picker and is of type “dropdown”

1. You can also display it as a dialog by using the following property in your Spinner XML

android:spinnerMode="dialog"

dialog Spinner mode● We get slightly

different behaviour from dialog mode.

● The title of the dialog comes from the android:prompt

property

Getting value from SpinnerSpinner sp1 = (Spinner)findViewById(R.id.spinner1);

String str = sp1.getSelectedItem().toString();

● It is worth mentioning at this stage that we can add an array of anything behind a Spinner.

● This would be done programatically as opposed to through XML for the strings we just saw.

● Presume we had an ArrayList<Person>. To get this into our list we need an Adapter.

What is an Adapter ?● For those who have done Swing UI, an Adapter in Android

is similar to the like of a TableModel in swing.

● It is a bridge or translator between the model (data) and more complex UI components. It is part of the GUI.

● For Spinner the easiest option for displaying an ArrayList of object is to use ArrayAdapter

● As in Swing objects which are not Strings will use toString representation of the object for display.

Adding Objects to SpinnerPerson p1 = new Person(“john”, 50);

Person p2 = new Person(“mary”, 60);

ArrayList<Person> peopleList = new ArrayList<Person>();

peopleList.add(p1);

peopleList.add(p2);

Spinner sp1 = (Spinner)findViewById(R.id.spinner1);

ArrayAdapter<String> spinnerArrayAdapter =

new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item,

peopleList);

sp1.setAdapter(spinnerArrayAdapter);

Fragment Communication● As we have seen fragments are “self-contained

modular components” (which exist inside an Activity)

● What happens when a Fragment wants to send a message elsewhere ? (To another Fragment ? To another Activity ?)

● NB : All communication must be done through the Fragment’s associated Activity.

Fragment communication● The first step is to allow the Fragment to communicate

“up to” its Activity.

● To do this we define a simple Java interface which

defines what messages (i.e. method calls) the Fragment can make.

● This interface is usally put inside the Java class of the Fragment which wants to communicate.

● The content of the interface is entirely up to us.

The ScenarioMainActivity

TopFragment

BottomFragment

For messaging between Fragments communication MUST be done through the Activity

Fragment Communication interface

public class TopFragment extends Fragment {

public View onCreateView(LayoutInflater inflater, ViewGroup container,

Bundle savedInstanceState)

{

// Inflate the layout for this fragment

return inflater.inflate(R.layout.fragment_bottom, container,

false);

}

}

Presume we already have a basic fragment class

public interface SomethingHappenedInFragment

{

public void sendAMessage(String

message);

}

Put the communication interface within the Fragment class

Activity implements Fragment

interface

● After defining the interface the Activity which the Fragment needs to communicate with must implement that interface.

public class MainActivity

extends Activity implements TopFragment.SomethingHappenedInFragment

{

//The rest of the Activity will already be HERE(onCreate() etc)

//..and now the implementation of the SomethingHappenedInFragment

interfacepublic void sendAMessage(String message)

{

}

Message from

source fragment

arrives here

Delivering the message● Once the Activity receives the message it needs to find the

Fragment (or Fragments) to deliver the communication to (ie.

Call a method on.

public void sendAMessage(String message)

{

FragmentManager fMgr = getFragmentManager();

//Look up the destination fragment

BottomFragment bottomFrag =

(BottomFragment)fMgr.findFragmentById(R.id.fragment_bottom);

//Call a method on the destination fragment

bottomFrag.someMethodWhichWantsTheMessage(message);

}.

What’s Missing?MainActivity

TopFragment

BottomFragment

public interface

SomethingHappenedInFragment {public void sendMessage(String s);

}

implements

SomethingHappenedInFragment

public void sendMessage(String s)

{

}

TopFragment doesn’t have

a reference to MainActivity ???

MainActivity can

find BottomFragment

by ID

The Final Step

● As part of the lifecycle of Activities and Fragments the Activity “attaches itself” to its Fragments.

● Last week we saw the Fragment lifecycle method onCreateView which MUST be implemented to get your

Fragment running.

● Before on onCreateView there is an earlier method in the Fragment lifecycle called onAttach

● onAttach is called by the Activity which conveniently

passes a reference to itself. We store this reference.

The Codepublic class TopFragment extends Fragment

{

private SomethingHappenedInFragment activity;

@Override

public void onAttach(Activity activity)

{

this.activity = (SomethingHappenedInFragment)activity

}

}

Remember : Our Activity implements SomethingHappenedInFragment

so it “is a” SomethingHappenedInFragment