代写Project 2C-DreamCatcher Complete代写Java程序

Project 2C – DreamCatcher Complete

DreamCatcher App (Part 3 of 3)

In this third of three parts for this project, we will extend the app further by adding the following new features:

1. Add a New Dream menu item to the DLF app bar (Chapter 15)

2. Implement a swipe-to-delete feature to delete Dreams from DLF

3. Show message with Butt on to Add Dream when DLF is empty (Chapter 15 Challenge)

4. Share a Dream via an implicit intent (Chapter 16)

5. Take a photo via implicit intent for display in DDF (Chapter 17)

6. Display a zoomed photo in a dialog when clicked in DDF (Chapter 17 Challenge)

7. Implement a RecyclerView to hold the DreamEntry list within DDF

8. Implement a swipe-to-delete feature to delete reflecti ons from DDF

Several of these features correspond closely to BNRG Chapters 15 through 17, as noted in the list above. However, there are several places where DreamCatcher requires significant changes from the approaches described in the textbook for CriminalIntent, with the most notable divergences detailed below by feature and chapter.

Getting Started

First, please be sure to retain a backup copy of your P2B project submission.

Next, you must get some new updates from the remote Git repository that you configured when starti ng Project 2A. To do this, select Git | Update Project and choose the opti on to Merge the incoming changes. These updates provide the following changes specific to Project 2C:

build.gradle (Module :app)

A new dependency has been added to support the testi ng process

P2CTest.kt

This new instrumented test file will help ensure that your app meets all of the P2C assignment requirements

PictureUti ls.kt

This uti lity functi on is directly from BNRG Listi ng 17.14, provided here for convenience

Feature 1: Add a New Dream menu item to the DLF app bar (Chapter 15)

The goal of this feature is to allow the user to add a new Dream from a menu in the DLF.

Start Chapter 15, and follow Listi ngs 15.1 and 15.2. The string should be "New Dream" then skip Figure 15.3 because we've already added ic_add as a vector asset (for adding reflecti ons). When defining the menu, please call it "res/menu/fragment_dream_list.xml" and ensure the Item id is @+id/new_dream.

Stop at "Creati ng the menu" and skip Listi ngs 15.3 and 15.4. The approach in BNRG was replaced in late 2021, and is now deprecated and difficult to use. Instead of overriding onCreateOpti onsMenu() we'll call addMenuProvider() on the acti vity from within onCreateView(). This functi on takes a MenuProvider and a LifecycleOwner:

MenuProvider: We'll define this as an anonymous MenuProvider object (meaning object : MenuProvider). The MenuProvider itself requires the implementati on of two functi ons:

onCreateMenu() creates the menu by inflati ng it with a provided inflater and menu.

onMenuItemSelected() will react to the menu clicks, and in this case there's only one item in the menu.

LifecycleOwner: This parameter is opti onal, but by default it uses the Acti vity lifecycle. Since we're using a single-Acti vity app, the menu would be retained even when this fragment is replaced by the detail fragment. We want this menu to be removed when the fragment is replaced, so we explicitly specify viewLifecycleOwner here.

We'll get started with just the basics, and no implementati on yet:

_binding = ...

requireActivity().addMenuProvider(object : MenuProvider {

// blank for now

}, viewLifecycleOwner)

return binding.root

The "object" above will be highlighted with an error. Hover and click "Implement methods" then select both abstract functi ons to provide placeholders with the required headers. Please remove the TODO notati ons.

In onMenuItemSelected() we can just return false for now:

requireActivity().addMenuProvider(object : MenuProvider {

override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {

}

override fun onMenuItemSelected(menuItem: MenuItem): Boolean {

return false

}

}, viewLifecycleOwner)

In onCreateMenu() add something similar to Listi ng 15.3:

override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {

menuInflater.inflate(R.menu.fragment_dream_list, menu)

}

Please run the app now, and follow Figures 15.6, 15.7, and 15.8 from the texbook.

Listi ng 15.5 - database/DreamDao.kt - Please change the name of the @Insert functi on to internalInsertDream(), and also add a @Transaction functi on to add all the entries along with the dream:

@Insert

suspend fun internalInsertDream(dream: Dream)

@Transaction

suspend fun insertDreamAndEntries(dream: Dream) {

// You must implement this on your own

}

Listi ng 15.6 - DreamRepository.kt - Same as BNRG, but remember to call the @Transaction function:

suspend fun addDream(dream: Dream) {

database.dreamDao().insertDreamAndEntries(dream)

}

Listi ng 15.7 - DreamListViewModel.kt - Same as BNRG, with different names:

suspend fun addDream(dream: Dream) {

dreamRepository.addDream(dream)

}

Now we can fill in the code to create the new dream and navigate to it.

Listi ng 15.8 - DreamListFragment.kt - The code is nearly identi cal, but it belongs in the onMenuItemSelected() functi on we created above

override fun onMenuItemSelected(menuItem: MenuItem): Boolean {

return when (menuItem.itemId) {

R.id.new_dream -> {

showNewDream()

true

}

else -> false

}

}

...

private fun showNewDream() {

viewLifecycleOwner.lifecycleScope.launch {

val newDream = Dream()

vm.addDream(newDream)

findNavController().navigate(

DreamListFragmentDirections.showDreamDetail(newDream.id)

)

}

}

Important: Please skip Listi ng 15.9. Please don't disable or delete the prepopulated dream-database asset. It's sti ll useful for us throughout this project.

Run the app and you should be able to add a new Dream from the app bar menu.

Feature 2: Implement a swipe-to-delete feature to delete Dreams from DLF

The goal of this feature is for the user to swipe any Dream to the left to delete the dream and its entries from the system.

First we must add a way to delete a dream (and its entries) from the database, which requires updati ng several files.

database/DreamDao.kt:

@Delete

suspend fun internalDeleteDream(dream: Dream)

@Transaction

suspend fun deleteDreamAndEntries(dream: Dream) {

// You must implement this on your own

}

DreamRepository.kt:

suspend fun deleteDream(dream: Dream) {

// You must implement this on your own

}

DreamListViewModel.kt:

fun deleteDream(dream: Dream) {

// You must implement this on your own

}

DreamListAdapter.kt - In order for the swipe handler to know which dream to delete, the DreamHolder class must be adjusted to expose the bound dream object as a public read-only property, set by its bind() functi on. This is the Kotlin equivalent to exposing a public gett er with a private sett er in Java:

class DreamHolder(private val binding: ListItemDreamBinding) :

RecyclerView.ViewHolder(binding.root) {

lateinit var boundDream: Dream

private set

...

fun bind(...) {

boundDream = dream

...

}

DreamListFragment.kt - Consult the API for ItemTouchHelper along with the autocomplete of the IDE to create a private functi on that returns a new ItemTouchHelper object:

private fun getItemTouchHelper(): ItemTouchHelper {

return ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {

override fun onMove(...): Boolean = true

override fun onSwiped(...) {

// You must implement this on your own

}

}

}

Hint: In the onSwiped() functi on above, the viewHolder must be cast to a DreamHolder type, using the as operator of Kotlin. To actually delete the dream and its entries, call vm.deleteDream() on the boundDream property of the DreamHolder.

Feature 3: Show message with Button to Add Dream when DLF is empty (Chapter 15 Challenge)

The goal of this feature is to display a brief message to the user if there are no dreams displayed in the DLF. There should also be a Butt on displayed to allow the user to add a new Dream (in additi on to the menu item in the app bar implemented above).

layout/fragment_dream_list.xml - Currently the RecyclerView is the top-level view of the layout. We need to place this RecyclerView within a ConstraintLayout component, so that we can add two new views that will overlap the RecyclerView. Because the RecyclerView height and width are both match_parent it doesn't require any constraints. However, the new view components will require you to specify constraints. You can review Chapter 11 for details about working with the ConstraintLayout.

Please use the following naming conventi ons for the two new view components:

TextView:

android:id="@+id/no_dream_text"

android:text="@string/no_dreams"

Butt on:

android:id="@+id/no_dream_add_button"

android:text="@string/new_dream"

app:icon="@drawable/ic_add"

DreamListFragment.kt - Set an onClickListener for the new butt on to call the showNewDream() functi on implemented earlier.

Hints: Before constructi ng the adapter, but within the collect{} block for dreams, set the visibility of the new views to either View.VISIBLE or View.GONE, based on whether the collected dreams list is empty or not. Also, don't forget to set a listener for the new butt on, so that it behaves exactly the same as the New Dream app bar menu from Feature 1.

Feature 4: Share a Dream via an implicit intent (Chapter 16)

The goal of this feature is for the user to use an app bar menu from the detail screen to share dream details with others via SMS, email, or copy-and-paste.

Chapter 16: Read – but please don't implement – BNRG up through the "Using a Format String" secti on.

Follow the concepts of Listi ngs 16.6 and 16.7, but shared dream will have the following format:

[Dream Title]

[Date String]

Reflections:

* [Reflection 1]

* [Reflection 2]

* [Reflection 3]

This dream has been [Deferred|Fulfilled].

Example:

Ride in a hot air balloon

Last updated 2023-09-10 at 11:12:13 AM

Reflections:

* One

* Two

This dream has been Deferred.

Formatti ng Notes:

The Date String should be the same format as in the last_updated_text of DDF

Only show as many Reflecti on lines as there are Reflecti on entries

If there are no reflecti ons, the "Reflecti ons:" header should be omitt ed

The joinToString() functi on is very useful for handling the reflecti ons

The last line should be omitt ed if the dream is neither fulfilled nor deferred

DreamDetailFragment.kt - BNRG uses a butt on placed in the layout for to trigger the implicit intent. Instead, we'll add a new menu to the DDF app bar using the same approach that we used to add a menu to the app bar of the DLF in Feature 1 above.

Use the Resource Manager to add a new Vector Asset from clip art called ic_share, and create another Menu resource called menu/fragment_dream_detail.xml. Please use the following naming conventi ons in the att ributes:

Item:

android:id="@+id/share_dream_menu"

android:icon="@drawable/ic_share"

android:title="@string/share_dream"

app:showAsAction="ifRoom|withText"

Listi ng 16.8 and 16.9 - DreamDetailFragment.kt - Follow the BNRG concepts, but place the listener code from Listi ng 16.8 into a helper functi on private fun shareDream(dream: Dream) instead. We'll call this functi on from the onMenuItemSelected functi on, aft er extracti ng the current dream value from the StateFlow held in the view model:

R.id.share_dream_menu -> {

vm.dream.value?.let { shareDream(it) }

return true

}

Aft er this, please read — but don't implement anything — starti ng from the "Asking Android for a contact" secti on through the end of this chapter.



热门主题

课程名

mktg2509 csci 2600 38170 lng302 csse3010 phas3226 77938 arch1162 engn4536/engn6536 acx5903 comp151101 phl245 cse12 comp9312 stat3016/6016 phas0038 comp2140 6qqmb312 xjco3011 rest0005 ematm0051 5qqmn219 lubs5062m eee8155 cege0100 eap033 artd1109 mat246 etc3430 ecmm462 mis102 inft6800 ddes9903 comp6521 comp9517 comp3331/9331 comp4337 comp6008 comp9414 bu.231.790.81 man00150m csb352h math1041 eengm4100 isys1002 08 6057cem mktg3504 mthm036 mtrx1701 mth3241 eeee3086 cmp-7038b cmp-7000a ints4010 econ2151 infs5710 fins5516 fin3309 fins5510 gsoe9340 math2007 math2036 soee5010 mark3088 infs3605 elec9714 comp2271 ma214 comp2211 infs3604 600426 sit254 acct3091 bbt405 msin0116 com107/com113 mark5826 sit120 comp9021 eco2101 eeen40700 cs253 ece3114 ecmm447 chns3000 math377 itd102 comp9444 comp(2041|9044) econ0060 econ7230 mgt001371 ecs-323 cs6250 mgdi60012 mdia2012 comm221001 comm5000 ma1008 engl642 econ241 com333 math367 mis201 nbs-7041x meek16104 econ2003 comm1190 mbas902 comp-1027 dpst1091 comp7315 eppd1033 m06 ee3025 msci231 bb113/bbs1063 fc709 comp3425 comp9417 econ42915 cb9101 math1102e chme0017 fc307 mkt60104 5522usst litr1-uc6201.200 ee1102 cosc2803 math39512 omp9727 int2067/int5051 bsb151 mgt253 fc021 babs2202 mis2002s phya21 18-213 cege0012 mdia1002 math38032 mech5125 07 cisc102 mgx3110 cs240 11175 fin3020s eco3420 ictten622 comp9727 cpt111 de114102d mgm320h5s bafi1019 math21112 efim20036 mn-3503 fins5568 110.807 bcpm000028 info6030 bma0092 bcpm0054 math20212 ce335 cs365 cenv6141 ftec5580 math2010 ec3450 comm1170 ecmt1010 csci-ua.0480-003 econ12-200 ib3960 ectb60h3f cs247—assignment tk3163 ics3u ib3j80 comp20008 comp9334 eppd1063 acct2343 cct109 isys1055/3412 math350-real math2014 eec180 stat141b econ2101 msinm014/msing014/msing014b fit2004 comp643 bu1002 cm2030
联系我们
EMail: 99515681@qq.com
QQ: 99515681
留学生作业帮-留学生的知心伴侣!
工作时间:08:00-21:00
python代写
微信客服:codinghelp
站长地图