Android App Programming - LRI

Transcription

Android AppProgrammingLecture 8: UX Programming 2Fragments and NavigationDec 14th, 2021Anastasia BezerianosUniversité Paris-Saclay1ABezerianos-Android-Lecture08.key - 14 December 2021

in class2ABezerianos-Android-Lecture08.key - 14 December 2021

Reminder:next session (04/01/2022)TD noté3ABezerianos-Android-Lecture08.key - 14 December 2021

TD noté 2 TD noté on 04/01/2022 You will work alone (cannot discuss with others) Can use any material from class (transparencies, labsolutions, videos), the book, or the internet BUT the nal solution should be yoursfi4ABezerianos-Android-Lecture08.key - 14 December 2021

Last lecture recap5ABezerianos-Android-Lecture08.key - 14 December 2021

Adding a listenerRegistering an onClick Listener tomyButtonmyButton.setOnClickListener(new View.OnClickListener()@Overridpublic void onClick(View view)// your code})Anonymous inner class that followsthe Interface patternView.OnClickListenerMethod that defines the reaction tothe event. This is like the “onClick"method we define in XML{ABezerianos-Android-Lecture08.key - 14 December 2021{e};6

Constraint Layout7ABezerianos-Android-Lecture08.key - 14 December 2021

UX Programming 2Fragments and Navigation8ABezerianos-Android-Lecture08.key - 14 December 2021

Fragments modular user interface units sub-activities with a lifecycle, class and layout embedded into one or more activities added during design and reused by activities added at runtime to create dynamic interfaces9ABezerianos-Android-Lecture08.key - 14 December 2021

Fragments10ABezerianos-Android-Lecture08.key - 14 December 2021

Fragments extend the class FragmentActivity have onCreateView() method that returns a View In an Activity you can add & manage Fragments with the FragmentManager and FragmentTransaction classes11ABezerianos-Android-Lecture08.key - 14 December 2021

Fragments Chapter 30 of the book has an example on Fragments(optional class in the Lab)12ABezerianos-Android-Lecture08.key - 14 December 2021

Navigation13ABezerianos-Android-Lecture08.key - 14 December 2021

Navigation Navigation Architecture component comes with Android Assumes a single Activity with many Fragments (eachactivity has each own navigation graph) Navigation graph: XML info on destinations & paths NavHost: empty container that displays a destinations(usually the class NavHostFragment) NavController: object that manages the transitions14ABezerianos-Android-Lecture08.key - 14 December 2021

Navigation Navigation editor to create / edit the navigation graph Each NavHostFragment class has its own NavController,accessible with findNavController() Can use Bundles to communicate information acrossFragments Need to add dependencies into build.gradle lesABezerianos-Android-Lecture08.key - 14 December 2021fi15

Lab 8 Exercise 1 & 2: Navigation & Communication16ABezerianos-Android-Lecture08.key - 14 December 2021

// Top-level build file where you can add configuration options common to all avenCentral(dependenciesclasspath “com.android.tools.build:gradle:7.0.2Adding global navigation support.Don’t forget to Syncdef nav version "2.3.5classpath lugin: nav versiontask clean(type: Delete)delete ey - 14 December 2021""r{){{.){}17}}}build.gradle Project

build.gradle ModuleNeeded to pass data across fragmentsthrough the navigationandroidcompileSdk 3defaultConfigapplicationId "fr.ups.lab8 simplenavigationminSdk 2targetSdk 3versionCodeversionName "1.0testInstrumentationRunner releaseminifyEnabled falsproguardFiles txt'), ty JavaVersion.VERSION 1targetCompatibility JavaVersion.VERSION 1dependenciesimplementation 'androidx.appcompat:appcompat:1.4.0implementation ntation 2Navigation libraries.Don’t forget to Syncimplementation ementation tation entation 'junit:junit:4. androidTestImplementation ation 'ABezerianos-Android-Lecture08.key - 14 December 2021''"88'''e"10{{01{{{{{}}}18}}}}pluginsid 'com.android.applicationid 'androidx.navigation.safeargs

activity main.xml ?xml version "1.0" encoding "utf-8"? mlns:android pp s "http://schemas.android.com/toolsTells the activity this Fragment is aandroid:layout width "match parentNavigationHostFragment that willandroid:layout height "match parentbe showing different fragments as thetools:context ".MainActivity"user navigates id "@ id/fragmentContainerView2android:name id:layout width "wrap contentandroid:layout height "wrap contentapp:layout constraintBottom toBottomOf "parentapp:layout constraintEnd toEndOf "parentapp:layout constraintStart toStartOf "parentapp:layout constraintTop toTopOf "parentTells the activity there is a NavHostapp:defaultNavHost "trueapp:navGraph "@navigation/navigation graph"/and the name of the navigation graph (another xml file)""""" """"w"ABezerianos-Android-Lecture08.key - 14 December 2021""" "19

ckage fr.ups.lab8 simplenavigationimport androidx.appcompat.app.AppCompatActivityimport android.os.Bundlepublic class MainActivity extends AppCompatActivity@Overridprotected void onCreate(Bundle te)setContentView(R.layout.activity main){{;;ABezerianos-Android-Lecture08.key - 14 December 2021;;;e20}}MainActivity.java

navigation graph.xml ?xml version "1.0" encoding "utf-8"? navigation xmlns:android pp s "http://schemas.android.com/toolsandroid:id "@ id/navigation graphstarting destination Fragmentapp:startDestination "@id/firstFragment" fragmenandroid:id "@ id/firstFragmentandroid:name "fr.ups.lab8 simplenavigation.ToolbarFragmentandroid:label "fragment firsttools:layout "@layout/fragment toolbar" actioandroid:id "@ id/action toolbarFragment to textFragmentapp:destination "@id/secondFragment" / /fragment fragmenandroid:id "@ id/secondFragmentandroid:name "fr.ups.lab8 simplenavigation.TextFragmentandroid:label "fragment secondtools:layout "@layout/fragment text" / /navigation""""" "ABezerianos-Android-Lecture08.key - 14 December 2021 """ ""n tt 21action that connects theFirstFragment to the Second(one way)

fragment toolbar.xml ?xml version "1.0" encoding "utf-8"? RelativeLayout xmlns:android ools "http://schemas.android.com/toolsandroid:layout width "match parentandroid:layout height "match parent" Buttoandroid:id "@ id/button1android:layout width "wrap contentandroid:layout height "wrap contentandroid:layout below "@ id/seekBar1android:layout centerHorizontal "trueandroid:layout marginTop "17dpandroid:text "@string/change text" / EditTexandroid:id "@ id/editText1android:layout width "wrap contentandroid:layout height "wrap contentandroid:layout alignParentTop "trueandroid:layout centerHorizontal "trueandroid:layout marginTop "16dpandroid:ems "10android:inputType "textandroid:minHeight "48dptools:ignore "SpeakableTextPresentCheck" requestFocus / /EditText SeekBaandroid:id "@ id/seekBar1android:layout width "match parentandroid:layout height "wrap contentandroid:layout alignParentStart "trueandroid:layout below "@ id/editText1android:layout marginTop "14dpandroid:layout alignParentLeft "true" / /RelativeLayout ABezerianos-Android-Lecture08.key - 14 December 2021"" """ """"""""" """" """""" trn22

.SeekBarandroid.widget.TextViewClass extends Fragment but also implements anOnSeekBarListener.This forces the class to create the methods thathandle events on the SeekBar: onProgressChanged,on StartTrackingTouch, onStopTrackingTouchpublic class ToolbarFragment extends Fragment implements SeekBar.OnSeekBarChangeListenerprivate static int seekvalue 10private static EditText edittextpublic ToolbarFragment()// Required empty public constructopublic static ToolbarFragment newInstance(String param1, String param2)ToolbarFragment fragment new ToolbarFragment()Bundle args new Bundle()fragment.setArguments(args)return fragmentAutomatically created method@Overridpublic void onCreate(Bundle te)"Inflating" a view means taking thelayout XML and parsing it to createthe view and viewgroup Java objects.@Overridpublic View onCreateView(LayoutInflater inflater, ViewGroup containerBundle savedInstanceState)// Inflate the layout for this fragmenView view inflater.inflate(R.layout.fragment toolbar, container, false)edittext (EditText) view.findViewById(R.id.editText1)final SeekBar seekbar (SeekBar) arChangeListener(this)final Button button (Button) stener(new View.OnClickListener()public void onClick(View v)buttonClicked(v)Tell the seeker bar that the code forthe OnSeekBarChange events are in“this" (the object of this class)})return viewpublic void buttonClicked (View view)Bundle bundle new Bundle()bundle.putString("resizetext", evalue", ate(R.id.action toolbarFragment to textFragment, bundle)@Overridpublic void onProgressChanged(SeekBar seekBar, int i, boolean b)seekvalue iNEW. Used this listener implementation to(i) create a Bundle to pass the info fromEditText and Seekbar; and(ii) Use the Navigation class to go to the TextFragment, using the action@Overridpublic void onStartTrackingTouch(SeekBar seekBar)@Overridpublic void onStopTrackingTouch(SeekBar seekBar);ABezerianos-Android-Lecture08.key - 14 December e}eee;}}}}}}}23}}ToolbarFragment.javapackage fr.ups.lab8 simplenavigation

fragment text.xml ?xml version "1.0" encoding "utf-8"? RelativeLayout xmlns:android :layout width "match parentandroid:layout height "match parent" TextVieandroid:id "@ id/textView1android:layout width "wrap contentandroid:layout height "wrap contentandroid:layout centerHorizontal "trueandroid:layout centerVertical "trueandroid:text "@string/fragment twoandroid:textAppearance "?android:attr/textAppearanceLarge" / /RelativeLayout" ABezerianos-Android-Lecture08.key - 14 December 2021""""" " " w24

ndroid.widget.TextView/** A simple {@link Fragment} subclass* Use the {@link SecondFragment#newInstance} factory method t* create an instance of this fragment*public class TextFragment extends Fragment// the fragment initialization parameters, e.g. ARG ITEM NUMBEprivate static final String resizetext "resizetext"private static final String resizevalue "resizevalue"Will use these names to access themsg from the Bundleprivate String TextEdit textprivate int TextEdit fontsizeI will store their values hereprivate static TextView textviewpublic TextFragment()// Required empty public constructopublic static TextFragment newInstance(String param1, int param2)TextFragment fragment new TextFragment()Bundle args new Bundle()args.putString(resizetext, param1)args.putInt(resizevalue, param2)fragment.setArguments(args)return fragmentAutomatically created method to readthe Bundle, not needed@Overridpublic void onCreate(Bundle te)if (getArguments() ! null)TextEdit text getArguments().getString(resizetext)TextEdit fontsize getArguments().getInt(resizevalue)Automatically created method, I amretrieving info from Bundle@Overridpublic View onCreateView(LayoutInflater inflater, ViewGroup containerBundle savedInstanceState)// Inflate the layout for this fragmen"Inflating" a view means taking the layout XMLand parsing it to create the view and viewgroupJava objects.View view inflater.inflate(R.layout.fragment text, container, false)textview (TextView) ies(TextEdit fontsize, TextEdit text )return viewpublic void changeTextProperties(int fontsize, String textA public method to change the size of the (text);ABezerianos-Android-Lecture08.key - 14 December }{}*25/}TextFragment.javapackage fr.ups.lab8 simplenavigation

Bindings(aside note, since Android Studio 3.6)26ABezerianos-Android-Lecture08.key - 14 December 2021

Bindings So far we accessed a widget (eg myButtonFoo) fromActivities using findViewById(R.id.myButtonFoo) Since Android Studio 3.6 an alternative way (optional) isusing a View Binding View Bindings are classes which are automaticallygenerated by Android Studio for each XML layout leABezerianos-Android-Lecture08.key - 14 December 2021fi27

Bindings Both Bindings and findViewById() are valid choices. Bindings can help avoid errors BUT they require you tochange your compilation options Edit build.gradle (Module: app) le:android {buildFeatures {viewBinding true}ABezerianos-Android-Lecture08.key - 14 December 2021fi28

public class MainActivity extends AppCompatActivityprivate ActivityMainBinding binding;@Overrideprotected void onCreate(Bundle savedInstanceState) (R.layout.activity main);binding iew view binding.getRoot();setContentView(view);}// Now we have a reference to the binding and can access the views by nampublic void convertCurrency(View view)EditText dollarText findViewById(R.id.dollarText)TextView textView findViewById(R.id.textView)if "))e{;{ABezerianos-Android-Lecture08.key - 14 December 2021;{29 }}Bindings

Bindings Many of the Project examples use Bindings For example Basic Activity, Bottom Navigation, etc.More under -binding30ABezerianos-Android-Lecture08.key - 14 December 2021

MVVM MVVM code organization stands for Model, View, .key - 14 December 2021

MVVM MVVM stands for Model, View, ViewModel. Model: Data of the application. It cannot directly talk to the View.Generally, we try to pass the data to the ViewModel throughObservables. View: It represents the UI of the application devoid of anyApplication Logic. It observes the ViewModel. ViewModel: It acts as a link between the Model and the View. It’sresponsible for transforming the data from the Model. It providesdata streams to the View. It also uses hooks or callbacks toupdate the View. It’ll ask for the data from the Model.32ABezerianos-Android-Lecture08.key - 14 December 2021

Navigation Fragments Navigation, Fragments and Binding can be combined tocreate more complex apps Example projects types like: Tabbed Activity, BottomNavigation, Navigation Drawer, 33ABezerianos-Android-Lecture08.key - 14 December 2021

Navigation FragmentsBottom NavigationNavigation Drawer34ABezerianos-Android-Lecture08.key - 14 December 2021

Navigation FragmentsTabbed ActivityBasic Activity35ABezerianos-Android-Lecture08.key - 14 December 2021

Lab 8 Exercise 3: Use existing Project types Optional use them to revisit Lab7-Ex336ABezerianos-Android-Lecture08.key - 14 December 2021

Lab 8 Exercise Optional: Fragments Follow the tutorial from the book on Chapter 30 (yourreading of Chapter 29 that contains the basics) !!!! See on the webpage for notes about the booktutorial that you need to adjust37ABezerianos-Android-Lecture08.key - 14 December 2021

Fragments Start a manager and assign a transactionFragmentManager fM getSupportFragmentManager()FragmentTransaction transaction frM.beginTransaction()A transaction can be used to: at the end commit the transaction 8.key - 14 December 2021; add a Fragment, replace it, remove it, addToBackStack(for when the user goes back in navigation);

Fragments Fragments can communicate via the activity they belong to39ABezerianos-Android-Lecture08.key - 14 December 2021

Fragments Communication: Activity Fragment done via the Fragment ID getSupportFragmentManager().findFragmentById( )40ABezerianos-Android-Lecture08.key - 14 December 2021

FragmentsCommunication: Fragment Activity requires: Fragment: Override the onAttach() method and store a linkto the Activity that attached (used) the Fragment Fragment: de ne a listener interface (pattern) Activity: implement a listener interface of the type de nedby the FragmentABezerianos-Android-Lecture08.key - 14 December 2021fi41fi

Lab 8 - optional42ABezerianos-Android-Lecture08.key - 14 December 2021

This class now extendsFragmentActivityBUTIt also implements a listenerToolbarListener that I have createdinside my class ToolbarFragment.my package name (also directory in my disk)package fr.ups.lab8 ex1import androidx.fragment.app.FragmentActivityimport android.os.BundleThis forces my classFragmentExampleActivity to providethe method onButtonClicpublic class FragmentExampleActivity extends FragmentActivityimplements ToolbarFragment.ToolbarListenerThis Listener that waits for events ishow the ToolBarFragment will sendinformation to the Activity.@Overridprotected void onCreate(Bundle te)setContentView(R.layout.activity fragment example)@OverridThis method will be activated by thepublic void onButtonClick(int fontsize, String text)Fragment ToolbarFragmentTextFragment textFragment changeTextProperties(fontsize, text)This is how the Activity sends information to theTextFragment.Access the methodchangeTextProperties of myTextFragmentWe access the activity’s FrameManager (through themethod getSupportFrameManager) and ask it to find aspecific frame (the one contained inside ecture08.key - 14 December 2021;{;;;kee}43}}FragmentActivity.java

activity fragment example.xml ?xml version "1.0" encoding "utf-8"? mlns:android pp s "http://schemas.android.com/toolsandroid:layout width "match parentandroid:layout height "match parenttools:context ".FragmentExampleActivity" id "@ id/fragmentContainerViewandroid:name "fr.ups.lab8 ex1.ToolbarFragmentandroid:layout width "wrap contentandroid:layout height "wrap contentapp:layout constraintBottom toBottomOf "parentapp:layout constraintEnd toEndOf "parentapp:layout constraintStart toStartOf "parentapp:layout constraintTop toTopOf "parent" /A FrameContainerView, I have addedhere my ToolbarFragment.The layout is the middle of the Activity id "@ id/fragmentContainerView2A FrameContainerView, I have addedandroid:name "fr.ups.lab8 ex1.TextFragmenthere my TextFragment.android:layout width "wrap contentThe layout is the middle of the Activityandroid:layout height "wrap contenthorizontally, and vertically betweenapp:layout constraintBottom toBottomOf "parentthe previous container and the bottomapp:layout constraintEnd toEndOf "parentapp:layout constraintStart toStartOf "parentapp:layout constraintTop toBottomOf "@ id/fragmentContainerView" / /androidx.constraintlayout.widget.ConstraintLayout """"""" """ABezerianos-Android-Lecture08.key - 14 December 2021"w"w" """""" 44

x.fragment.app.FragmentClass extends Fragment but also implements anOnSeekBarListener.This forces the class to create the methods thathandle events on the SeekBar: onProgressChanged,on StartTrackingTouch, onStopTrackingTouchpublic class ToolbarFragment extends Fragment implements SeekBar.OnSeekBarChangeListenerprivate static int seekvalue 10private static EditText edittextToolbarListener activityCallbackpublic interface ToolbarListenerpublic void onButtonClick(int position, String text)This is how this Fragment will communicate with theActivity that contains it.We override the method onAttach to store a link tothe context (ie the Activity that called the onAttach)@Overridpublic void onAttach(Context context)super.onAttach(context)tryactivityCallback (ToolbarListener) context} catch (ClassCastException e)throw new ClassCastException(context.toString( " must implement ToolbarListener")}@Nullabl@Overridpublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)// Inflate the layout for this fragmenView view inflater.inflate(R.layout.toolbar fragmentcontainer, false)"Inflating" a view means taking thelayout XML and parsing it to createthe view and viewgroup Java objects.edittext (EditText) view.findViewById(R.id.editText1)final SeekBar seekbar (SeekBar) arChangeListener(this)Tell the seeker bar that the code forthe OnSeekBarChange events are in“this" (the object of this class)final Button button (Button) stener(new View.OnClickListener()public void onClick(View v)buttonClicked(v)})return viewSend a msg to the Activity that contains thisFragment.We use the stored link to the Activity to call theActivity’s method onButtonClick that expectstwo parameters, the seekvalue and the textpublic void buttonClicked (View ext.getText().toString())@Overridpublic void onProgressChanged(SeekBar seekBar, int i, boolean b)seekvalue i@Overridpublic void onStartTrackingTouch(SeekBar seekBar) {@Overridpublic void onStopTrackingTouch(SeekBar seekBar) {{ABezerianos-Android-Lecture08.key - 14 December }eee;}}}45}}}ToolbarFragment.javapackage fr.ups.lab8 ex1

toolbar fragment.xml ?xml version "1.0" encoding "utf-8"? RelativeLayout xmlns:android ools "http://schemas.android.com/toolsandroid:layout width "match parentandroid:layout height "match parent" Buttoandroid:id "@ id/button1android:layout width "wrap contentandroid:layout height "wrap contentandroid:layout below "@ id/seekBar1android:layout centerHorizontal "trueandroid:layout marginTop "17dpandroid:text "@string/change text" / EditTexandroid:id "@ id/editText1android:layout width "wrap contentandroid:layout height "wrap contentandroid:layout alignParentTop "trueandroid:layout centerHorizontal "trueandroid:layout marginTop "16dpandroid:ems "10android:inputType "textandroid:minHeight "48dptools:ignore "SpeakableTextPresentCheck" requestFocus / /EditText SeekBaandroid:id "@ id/seekBar1android:layout width "match parentandroid:layout height "wrap contentandroid:layout alignParentStart "trueandroid:layout below "@ id/editText1android:layout marginTop "14dpandroid:layout alignParentLeft "true" / /RelativeLayout ABezerianos-Android-Lecture08.key - 14 December 2021"" """ """"""""" """" """""" trn46

package fr.ups.lab8 android.widget.TextViewimport androidx.annotation.NonNullimport androidx.annotation.Nullableimport androidx.fragment.app.Fragmentpublic class TextFragment extends Fragmentprivate static TextView textview@Nullabl@Overridpublic View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable BundlesavedInstanceState)View view inflater.inflate(R.layout.text fragment"Inflating" a view means takingcontainer, false)thelayout XML and parsing it to createthe view and viewgroup Java objects.textview (TextView) view.findViewById(R.id.textView1)return viewpublic void changeTextProperties(int fontsize, String textA public method to change the size of the (text);)ABezerianos-Android-Lecture08.key - 14 December 2021,{;;;;;;;;;;;;;;;;{;ee}{47}}TextFragment.java

text fragment.xml ?xml version "1.0" encoding "utf-8"? RelativeLayout xmlns:android :layout width "match parentandroid:layout height "match parent" TextVieandroid:id "@ id/textView1android:layout width "wrap contentandroid:layout height "wrap contentandroid:layout centerHorizontal "trueandroid:layout centerVertical "trueandroid:text "@string/fragment twoandroid:textAppearance "?android:attr/textAppearanceLarge" / /RelativeLayout"ABezerianos-Android-Lecture08.key - 14 December 2021 """"" " " w48

Advance Reading Next week’s topic: building web services https://en.wikipedia.org/wiki/Representational state transfer (no quiz as we’ll have a TD note)49ABezerianos-Android-Lecture08.key - 14 December 2021

Questions50ABezerianos-Android-Lecture08.key - 14 December 2021

Android App Programming Lecture 8: UX Programming 2 Fragments and Navigation Dec 14th, 2021 Anastasia Bezerianos . Chapter 30 of the book has an example on Fragments (optional class in the Lab) Fragments 12 ABezerianos-Android-Lecture08.key - 14 December 2021. Navigation