GitHub - DroidKaigi/conference-app-2019: The Official Conference App for DroidKa...
source link: https://github.com/DroidKaigi/conference-app-2019
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
README.md
DroidKaigi 2019 official Android app
DroidKaigi 2019 is a conference tailored for developers on 7th and 8th February 2019.
You can download the binary built on master branch from
Features
top detail- View conference schedule and details of each session
- Set notification for upcoming sessions on your preference
- Search sessions and speakers and topics
- Show Information Feed
Contributing
We are always welcome your contribution!
How to find the tasks
We use GitHub issues to manage the tasks. Please find the issues you'd like to contribute in it. welcome contribute and easy are good for first contribution.
Of course, it would be great to send PullRequest which has no issue!
How to contribute
If you find the tasks you want to contribute, please comment in the issue like this to prevent to conflict contribution. We'll reply as soon as possible, but it's unnecessary to wait for our reaction. It's okay to start contribution and send PullRequest!
We've designated these issues as good candidates for easy contribution. You can always fork the repository and send a pull request (on a branch other than master
).
Development Environment
Multi module project
We separate the modules for each feature.
You can check generated module dependency diagram
Unidirectional data flow(Flux-based) Architecture
Unidirectional data flow(Flux-based) Architecture with Kotlin Coroutines
and AndroidX
Libraries(LiveData
, ViewModel
, Room
) DataBinding
, Dagger
and AssistedInject
, Firebase
etc.
Groupie
By using Groupie
you can simplify the implementation around RecyclerView.
class SpeakerItem @AssistedInject constructor( @Assisted val speaker: Speaker, // Inject by AssistedInject val navController: NavController // Inject by Dagger ) : BindableItem<ItemSpeakerBinding>() { @AssistedInject.Factory interface Factory { fun create( speaker: Speaker ): SpeakerItem } override fun getLayout(): Int = R.layout.item_speaker override fun bind(itemBinding: ItemSpeakerBinding, position: Int) { itemBinding.speakerText.text = speaker.name ... } }
We use AssistedInject
for creating item.
@Inject lateinit var speakerItemFactory: SpeakerItem.Factory ... val speakerItems = session .speakers .map { speakerItemFactory.create(it) } groupAdapter.update(speakerItems)
Architecture
Unidirectional data flow(Flux-based) Architecture with Kotlin Coroutines and AndroidX Libraries(LiveData, ViewModel, Room) DataBinding, dependency injection, Firebase etc.
Activity/Fragment -> Action Creator
Fragments just call Action Creator's method.
class SessionPagesFragment : DaggerFragment() { @Inject lateinit var announcementActionCreator: AnnouncementActionCreator override fun onActivityCreated(savedInstanceState: Bundle?) { ... announcementActionCreator.load() }
Action Creator <-> DB / API and Action Creator -> dispatcher
Action Creator fetches data from DB / API with Kotlin Coroutines suspend function
. And Action Creator dispatches data loaded action and loading state changed actions.
class AnnouncementActionCreator @Inject constructor( override val dispatcher: Dispatcher, val firestore: Firestore, @PageScope val lifecycle: Lifecycle ) : CoroutineScope by lifecycle.coroutineScope, ErrorHandler { fun load() = launch { try { dispatcher.dispatch(Action.AnnouncementLoadingStateChanged(LoadingState.LOADING)) // fetch announcement by Kotlin Coroutines suspend function dispatcher.dispatch(Action.AnnouncementLoaded(firestore.getAnnouncements())) dispatcher.dispatch(Action.AnnouncementLoadingStateChanged(LoadingState.LOADED)) } catch (e: Exception) { onError(e) dispatcher.dispatch(Action.AnnouncementLoadingStateChanged(LoadingState.INITIALIZED)) } } }
Actions are just data holder class.
sealed class Action { ... class AnnouncementLoadingStateChanged(val loadingState: LoadingState) : Action() class AnnouncementLoaded(val announcements: List<Announcement>) : Action() ... }
Dispatcher -> Store
Store subscribe dispatcher's action with Kotlin Coroutines channel
and transform it to AndroidX LiveData
.
This store is a ViewModel
. But if the store is used by the whole application(ex: UserStore), you can change the store to a singleton.
class AnnouncementStore @Inject constructor( dispatcher: Dispatcher ) : ViewModel() { val loadingState: LiveData<LoadingState> = dispatcher .subscribe<Action.AnnouncementLoadingStateChanged>() .map { it.loadingState } .toLiveData(LoadingState.LOADING) val announcements: LiveData<List<Announcement>> = dispatcher .subscribe<Action.AnnouncementLoaded>() .map { it.announcements } .toLiveData(listOf()) }
Store -> Activity/Fragment
In the fragment, we can observe Store's LiveData
. You can display the UI with LiveData
.
override fun onActivityCreated(savedInstanceState: Bundle?) { ... announcementStore.loadingState.changed(viewLifecycleOwner) { // apply loading state for progress bar progressTimeLatch.loading = it == LoadingState.LOADING } announcementStore.announcements.changed(viewLifecycleOwner) { announcements -> // we can show UI with announcements } ...
Thanks
Thank you for contributing!
- Contributors
- Designer
- App Distribution
- DeployGate (https://deploygate.com)
Credit
This project uses some modern Android libraries and source codes.
- Android Jetpack (Google)
- Foundation
- AppCompat
- Android KTX
- Mutidex
- Test
- Architecture
- Data Binding
- Lifecycles
- LiveData
- Navigation
- UI
- Emoji
- Fragment
- Transition
- ConstraintLayout
- RecyclerView
- ...
- Foundation
- Kotlin (Jetbrains)
- Stdlib
- Coroutines
- Serialization
- Firebase (Google)
- Auth
- Firestore
- Dagger 2
- Core (Google)
- AndroidSupport (Google)
- AssistedInject (Square)
- Material Components for Android (Google)
- Ktor (Jetbrains)
- Android Client
- Json
- OkHttp (Square)
- Client
- LoggingInterceptor
- livedata-ktx (Shopify)
- LeakCanary (Square)
- Stetho (Facebook)
- Hyperion-Android (WillowTree)
- Groupie (lisawray)
- KLOCK (soywiz)
- MockK (oleksiyp)
- Injected ViewModel Provider (evant)
- Google I/O 2018 (Google)
- Picasso (Square)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK