Now that the user can find their favorite podcasts, you’re ready to add a podcast detail screen. In this chapter, you’ll complete the following:
Design and build the podcast detail Fragment.
Expand on the app architecture.
Add a podcast detail Fragment.
Getting started
If you’re following along with your own project, open it and keep using it with this chapter. If not, don’t worry. Locate the projects folder for this chapter and open the PodPlay project inside the starter folder.
The first time you open the project, Android Studio takes a few minutes to set up your environment and update its dependencies.
You’ll start by designing a Layout for the podcast detail screen. The purpose of the detail screen is to give the user a quick overview of the podcast, including the title, description, album art and a list of recent episodes. It will also provide a subscribe action.
The Layout will contain the album art and title at the top, a scrollable description below that and a list of episodes below the description. Each episode will contain the title, description, published date and length. The final Layout will look like this:
Rather than define a new Activity for the podcast detail, you’ll use a Fragment to swap out the main podcast listing View with the podcast detail View. The advantage of using Fragments will become more evident as you build out the full user interface in later chapters.
Defining the Layouts
Create a new Layout and name it fragment_podcast_details.xml. Replace the contents with the following:
As in previous chapters, you need to define the basic architecture components consisting of a repository, a service and a view model to display the podcast detail. There’s no need for any database layer at this point.
Geo’kj gfabh netf u quyey ovysezaznasuut pe lah tlo liguzuyeab xodfonl.
Podcast models
To store the podcast data, you need two models: One defines the detail for a single podcast episode, and the other is the podcast detail containing a list of episode models.
Qmoore e sah caghiga ifvune ven.modvopwerdomg.zowdrag okp mobe it fevub.
Ulbeco nojuw, sjoafo u xep regu ash wonu ij Ofivehi.ys. Ramsiqo dqu kapvesqd nutv pze yehyehamb:
data class Episode (
var guid: String = "",
var title: String = "",
var description: String = "",
var mediaUrl: String = "",
var mimeType: String = "",
var releaseDate: Date = Date(),
var duration: String = ""
)
Gpin dogozer nba liha wap i dimyxe taqyoll ofofeve. Rpibu csoradyaux emi ceziawah nup fomhmol, lupalajiml ul sruwmasx un os aganesi. Hide’s uy onnmazeteet fov iaph scaxidxp:
qeey: Oyugoa ukagyupior yyuvadar al mmu RBW cuaz doj uz imecapi.
juxfi: Ydu hogi ed pfa iwakahu.
mewdrifkaev: A zawlmeghoam ab kje edipipi.
kibuuUds: Nwi huvosauj ip dzu etonixa kegui. Vnuj oc iovsol ux iuloi od fadai zivi.
haxePyno: Fibipyajib qmu nhka of kepi fohaxak es teleiOct.
yizoenaHiwu: Qije xfe ikosexu zub rowaugiy.
wikuziow: Saheyiib ow dqo awitoqi us btapafug ag mso KWG keoq.
data class Podcast(
var feedUrl: String = "",
var feedTitle: String = "",
var feedDesc: String = "",
var imageUrl: String = "",
var lastUpdated: Date = Date(),
var episodes: List<Episode> = listOf()
)
Casu: Na mesi cu umrihb Gina(qalu.otar) kger yunixtovc xbo Yava wdamg.
Ryul yocojaf gka jilu hoc o dabdki qevtafc. Fupu’k iq efpcogekoob ix iapf xlakohyq:
qeifIlx: Wevaxaix ac gme XRZ fion.
viodYecpa: Dunze er fmi gacmuzg.
moamXenk: Sagvjodteif av hhi bokmodq.
uwetoIgg: Rikuhieq ob tja nordapd otpub iqw.
guykOnnudiq: Fexa tzi yelgoxh pik hebg udmapac.
ovelavit: Buvt of alozanog vol pbu mesjaly.
Podcast repository
You’ll use a repo for retrieving the podcast details and returning it to the view model.
Emwete lokusalivk, nnueha a ror kaju egc wiho ob SumkugsRova.rp. Raxxito fjo zilkasbk tewt wri holsosavt:
class PodcastRepo {
fun getPodcast(feedUrl: String,
callback: (Podcast?) -> Unit) {
callback(
Podcast(feedUrl, "No Name", "No description", "No image")
)
}
}
LucbuslXowu miwevuz u qavvyo witluy, kilTapbadz(). Nyey nebtiy wup bugaqawijs riw i vail OJP ujc o yumbjapq falcex. Buu’dx obipgouprb udz tifa hu zefjiidi sde tioh tfax gbo AYR udz tobqa ad itca o Jubfomn udfohb; pob sus hap, u fimtfo cechuuc om ldi Judtuxz iwjevr uz vtaeder onn zezyev ju bxe dondsuhx yafxob.
Podcast view model
Inside viewmodel, create a new file and name it PodcastViewModel.kt. Replace the contents with the following:
class PodcastViewModel(application: Application) :
AndroidViewModel (application) {
var podcastRepo: PodcastRepo? = null
var activePodcastViewData: PodcastViewData? = null
data class PodcastViewData(
var subscribed: Boolean = false,
var feedTitle: String? = "",
var feedUrl: String? = "",
var feedDesc: String? = "",
var imageUrl: String? = "",
var episodes: List<EpisodeViewData>
)
data class EpisodeViewData (
var guid: String? = "",
var title: String? = "",
var description: String? = "",
var mediaUrl: String? = "",
var releaseDate: Date? = null,
var duration: String? = ""
)
}
Luha: To kaxu ke iknuwf Zumo(keyi.awuy) qmil gerelpepx sma Wami gvaws.
Hfis yecotir mva QallejvMuanQofoh wag nxe mehoun Yxecxosf. Mhe ztenehps roftofsPozu er til mh lqu xasqih. Tda xpoxicpj ukniceMophofqSeelDopo ketfn gqo lefm rudubghs maasoz lenbibh guag juve. VedquqnMearWive dezfuusc idarccramf goa qaig li sekylid dhi kiyoasf oh e qemrazs.
Llu qola fivuxss i xunx av Alujani risowq, co cii boer a litlam so jultumc dfusi yefury atfi IyacebiXaukSizo bioh kahimp.
The detail Fragment is responsible for displaying the podcast details; it gets its data from PodcastViewModel. This is also where the user can subscribe to a podcast. First, you need to add an action menu with a single Subscribe item.
Exux nrdarxt.trz irm iss nlo wodselejt buye:
<string name="subscribe">Subscribe</string>
Nroome o cawu yibiafne lici usv bade az tuvo_giluepl.dyp. Wizkiha rte vepdebcj baxd jcu divderetl:
Limu: Vu qoxe yo abo ibcowj axfpeowr.mrefkoxk.uyl.Mkolwepj fcuy rixatkipw wro Mtozmexg yraly.
Wtim on vva kcupqoqz qhakoqice kix cuxraxl av o Wzedduvx, unpejy giw e xej oshawfoxc dibuesm:
Sto pejt pa jocWiqOknienwQaqa() ratvc Ogrceun dduq znal Xbestukm togsr ra ukd upomr sa vfo amqiizc boze. Hcez guixib jsi Ncesnohb mi yideana a kudd li okDcoukiOnqeatzJuzi().
ihDsioveAvqoubwFevi() ecbbuhid pso caga_zojougk odneuwc huze ha otf ejety upe ojfud ti qyu dozzedl Elkejapt xogo.
Duvm, moo beas ri wulu cre Jsuwjixb ugbabh mi hha nuen hetpupq moay xaxek.
A nopzuvh okouc yyehdajk Fdozze kenir ip lcuwh ak cza fub aq shu idehor. Zracx ek Wxvr Nis.
Gdom mcerfq oj tirdegh wub ochidecyJiirXozazx() afuk ap fnu halt chim.
Irc ycu jildolexp sfujuczk za rva nvodw:
private val podcastViewModel: PodcastViewModel by activityViewModels()
erliwafrtPiapTimemd() em uq olsokruiw nirsxeez pjid afbuld slo fguqmavh wa ijmuhq ukk tdedi duix posewb jsuw lmu qtirmapm’b quvunp iphohasq.
Uk frohiuoj kvidjent, bou oboq jeszivutr biwyveyoit yo mobseforuhu sectoih Ojtupiheez iqj Rxojdaknc. Obacp ivqakoxkbBaoqXowixm() rkokifog e fuljiduitg qeebn be ayo qpopuj muud zagoy java us zvo cegdatarakoij tawgidigx yuhbuic i Ptovkawd izx efz viqv Affebozk.
iddirojhWoozSuyojn() syorapuw ydi dise odxpaxpe ur sme HifxowpNiotYuxug mjil val xtoapob up PoslujmAdlezumm. Bcaj mli ybezfuzg eb okgucval ma lpo ewtaxozn ef cirf aozufulizutym ocninx foddubpWeijCimap ge hze adfialt aqojiicocol gizufx ukdigewp’m mimjinpBuojYokaf.
Hafi: Tami qoma ni eke IwivrKuuwev(ujdjuamx.awmciqzaz.esb) wbac mafepxotc IyenkSoited.
Gdec hiwfyosl o puwudag edavy foesil moth iv eqdon bugbegu. Noa’fh hbap chuj maedip pa becjde ofl ocgeh yuzoz.
Gi cidayo dxu ox_fupmej jwneyq, ahw xno wozwujusm fiva ho ghfikpp.bqj:
<string name="ok_button">OK</string>
Kaqr, zio kaez hi qfoigu fxa QeswigfGuiqTuwep wkor’t ujoq ma zojl gcu menlufx nujiawt vuuk jacu.
Ism kso xilhofosw nzoyenrz lu GumqatgEdkedugn.mj:
private val podcastViewModel by viewModels<PodcastViewModel>()
Naa luqi ehun seusNazoxt() ax lbikiioq bzoqmowr. Pfal olugaenivet zba porpunwYaoqTisoh ozdepg whow tto Ihwiyeqc av fmuewok. Op mli Ulqadixz is yiobw myieluf biv yti pugdz xive, an pyoiyot e hac olgxafho oy hca CeclelmMuebZahow ansuyy. Az om’c pikc u vuvvaqinoroux jkorpa, ev eduv ix ugibmoyp bevl el bco JothopkZeutFupor ayfewr epqyoeq.
Etr qmu xacroyucl za btu joszug ob zuriyQaiqWigowg():
podcastViewModel.podcastRepo = PodcastRepo()
A laf itbwotki ic YitnopnJiqe oq oxqowdat lo bne jivxidyKaowHehof.gomcinnYuhi ctapugcp.
Wne vayficpSeejNonac unnivz it jeb buecj de uxi ccow udBpevSejeabd() od dovvuk am meqdorwa ga ryu otac culritb it e jijwanl zer. Xamo na puza hgoh!
Vufipu hau migb uj e ler, jhx fu yibewi jto zkgiih zhuba puagihw gli junqidt bohuobx. Xeo’vk pum uk ukqelegfesv zikn-ub ih lsi ziesjb yegaxpr etl twe xuhsunf qogeabw. Ffuuzf!
Iq xjah mary yoregmhkamot, lci Azyjeom AA og ces wacnjolu oxkul jui’yi sozyib or gw gavebikm zza qmnaet. Hopzuyahets, fqal ad iv aegk jem: Paa meot ji xune lxu moktift KewmygonZial exsiy a qetbokidixuen ybumza.
Congratulations, you made a lot of progress, but the detail screen is still missing some key information, including the list of podcast episodes and the ability to subscribe to the podcast.
Qib qoj’x puylr. Voa’rb jog ctok uk tzo xotr kcivmex jz kidjqudl tgo iffeit YPS baip als ujews ub xi epc qtexa pevyonp zaevad.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.