├── .DS_Store ├── .github └── PULL_REQUEST_TEMPLATE.md ├── LICENSE ├── README.md ├── art ├── instagram.png ├── telegram.png └── twitter.png ├── codes ├── ActivityRecognition.kt ├── ArrayListToString.kt ├── Average.kt ├── CheckNetworkConnection.kt ├── CommitVsCommitAllowingStateLoss.kt ├── CorouitinesContinuation.kt ├── DeepLinkWithNavigationComponent.kt ├── DefiningMapWithKotlin.kt ├── DowloadingFileOkhttpOkio.kt ├── EasySpannableOnKotlin.kt ├── EfficientStringConcat.kt ├── ElvisOperator.kt ├── EncryptedSharedPreferences.kt ├── ExecuteBodyIfDebugMode.kt ├── FilterGooglePlacesAutocomplete.kt.kt ├── FragmentArgumentDelegate.kt ├── FragmentLiveDataLifeCycleOwner.kt ├── HasCodeForNullableTypes.kt ├── HowToGetPrimaryColorOfTheme.kt ├── ImplicitNullCheck.java ├── InfixFunctions.kt ├── JetPackCompose.kt ├── KeyboardShowHideExt.kt ├── KotlinStyleSupportVersionCheck.kt ├── KotlinWayToAddOrRemoveView.kt ├── KotlinWayToCreateSingletons.kt ├── LaunchWhenStarted.kt ├── LazyLoading.kt ├── LiveDataTransformations.kt ├── LocalFunctions.kt ├── LogginWithLiveTemplate.kt ├── MapComparison.java ├── Mapper.kt ├── MasteringKotlinStandartFunctions.kt ├── MemoryOptimization.java ├── MultiDimensionalFlavorConfigFields.gradle ├── NamingImportExample.kt ├── NetworkCallWithRxJavaAndViewModel.kt ├── ObservableDelegation.kt ├── PackageLevelFunctions.kt ├── RandomExtFuncInKotlin1-3.kt ├── RangeUsing.kt ├── ReifiedTypeParameters.kt ├── RepeatFunction.kt ├── RoomTypeConverter.kt ├── RxJavaFirebaseStorageSample.kt ├── SafeConstantNullCheck.java ├── SealedClass.kt ├── Sequence.kt ├── SmartCast.kt ├── StopGradleProcesses.sh ├── StringTemplates.kt ├── TailrecUsage.kt ├── Transient.kt ├── TypeAliases.kt ├── UsingApplySample.kt ├── ViewModelExtension.kt ├── WhenInKotlin1-3.kt └── usingParcelizeInKotlin.kt └── screenshots ├── .DS_Store ├── 1kbDownloadWithDevice.png ├── 6MobileSecurityTips.png ├── ActivityRecognition.png ├── AndroidActionMode.png ├── AndroidArchitecture.jpg ├── AndroidCoroutinesContinuation.png ├── AndroidLocalizedPushNotifications.png ├── AndroidPerformanceTips.png ├── AndroidQFeatures.png ├── AndroidStudioReleaseNewFeatures.jpg ├── AndroidViewHierarchy.png ├── AnyTryCatch.png ├── ApiCallsAndSuspendFunctions.png ├── ApkSignatureSchemeV2.png ├── AppActions.png ├── AppComponentFactory.png ├── AppFgBgListener.png ├── ApplyChanges.jpg ├── ArrayListToString.png ├── ArtVsDalvik.jpg ├── AsyncToSync.png ├── Average.png ├── AvoidMemoryLeaksWithInnerClasses.png ├── BackPressedOnFragments.jpg ├── BitmapExtension.png ├── BuildscriptVsAllprojects.png ├── CheckNetworkConnection.png ├── CheckingLocationServices.png ├── CheckingPermissions.png ├── CommitVsCommitAllowingStateLoss.png ├── CommonGradleFile.png ├── ConstraintLayoutAspectRatio.png ├── ConstructorInjection.png ├── CoroutineScopeVssupervisorScope.png ├── CoroutineViewModel.png ├── Coroutines.png ├── CoroutinesAsyncManager.png ├── CoroutinesContinuationUsage.png ├── CoroutinesVsRxKotlin.png ├── CreatingHiddenFiles.jpg ├── DaggerAndroidInjector.png ├── DalvikVsArt.png ├── DataBindingSeekBarColor.jpg ├── DbEntityMapper.png ├── DeepLinkWithNavigationComponent.png ├── DefiningMapWithKotlin.png ├── DelegatingSettersGetters.jpg ├── Dexguard.jpg ├── DiImplCosts.jpg ├── DowloadingFileOkhttpOkio.png ├── DrawableVsMipMapFolders.jpg ├── EditTextListenerImpl.png ├── EditTextManualFocusForward.jpg ├── EfficientSplashScreen.png ├── EfficientStringConcat.png ├── ElvisOperator.png ├── EncryptedSharedPreferences.png ├── ExecuteBodyIfDebugMode.png ├── ExtensionFuncForRxSubscriptions.png ├── FancyWayToSetOnClickListeners.png ├── FeatureModule.png ├── FilterGooglePlacesAutocomplete.png ├── FirstAndPredicate.jpg ├── FlattenArray.png ├── FlowVsObservable.jpg ├── FragmentArgumentDelegate.png ├── FragmentContainerView.png ├── FragmentLiveDataLifeCycleOwner.png ├── FunctionInterfaces.jpg ├── GitFetch.png ├── GitPull.png ├── GradleConfigurationFile.png ├── HandlingApiResultWithSealedClass.png ├── HandlingGenericApiResponseWithCoroutines.png ├── HashCodeForNullableTypes.png ├── HowToGetPrimaryColorOfTheme.png ├── HowToResolveAppLaunchingTimeDelay.png ├── HowToStoreDataLocally.png ├── ImplicitNullCheck.png ├── InfixFunctions.png ├── InteritanceWithDataClasses.jpg ├── JetpackCompose.png ├── JoinToString.png ├── JvmOverloads.png ├── KaptIncrementalCompilation.jpg ├── KeyFeaturesToIncreaseReachAndEngagement.png ├── KeyboardShowHideExt.png ├── KotlinAsClassClash.jpg ├── KotlinDelegateForInitializing.png ├── KotlinDelegationBy.png ├── KotlinDsl.png ├── KotlinInIs.jpg ├── KotlinReadableAndCleanCode.png ├── KotlinRun.jpg ├── KotlinStandartFunctions.png ├── KotlinStyleSupportVersionCheck.jpg ├── KotlinWayToAddOrRemoveView.png ├── KotlinWayToCreateSingletons.png ├── KotlinWhereUsage.jpg ├── LaunchVsAsync.jpg ├── LaunchWhenStarted.png ├── LazyLoading.png ├── LetApplyRunAlsoWith.jpg ├── ListImplDiscuss.png ├── LiveData.png ├── LiveDataGenericErrorHandling.png ├── LiveDataTransformations.png ├── LocalFirstWithCoroutines.jpg ├── LocalFunctions.png ├── LocalReturn.png ├── LocusId.jpg ├── LogginWithLiveTemplate.png ├── Looper.png ├── LuhnCheck.png ├── MapAssociate.png ├── Mapper.png ├── MasteringKotlinStandartFunctions.png ├── MemoryOptimization.png ├── MoshiOverGson.png ├── MultiDimensionalFlavorConfigFields.png ├── MviArchitecture.png ├── MvpArchitecture.png ├── NamingImportExample.png ├── NetworkCallWithRxJavaAndViewModel.png ├── NewlineAtEndOfFile.png ├── NotationForPlatformTypes.png ├── ObservableDelegation.png ├── ObservingLiveData.png ├── PackageInfo.png ├── PackageLevelFunctions.png ├── ParcelableVsSerializable.png ├── PerformanceTips.jpg ├── Preconditions.png ├── ProguardKeep.png ├── PropertyOverride.png ├── RandomExtFuncInKotlin1-3.png ├── RangeUsing.png ├── ReadFromJson.png ├── RecyclerViewLayoutManagerWithXml.jpg ├── RecyclerviewSetup.png ├── ReifiedTypeFindFragment.jpg ├── ReifiedTypeParameters.png ├── RelationBetweenLivedataAndSubClasses.png ├── RepeatFunction.png ├── RoomTypeConverter.png ├── RoomWithDagger.png ├── RxDebounceWithKotlinCoroutines.jpg ├── RxJavaConcatUsage.png ├── RxJavaFirebaseStorageSample.png ├── SafeConstantNullCheck.png ├── SealedClass.png ├── Sequence.png ├── SetTargetFragment.png ├── SingleLiveData.png ├── SingleRecyclerViewAdapter.png ├── SmartCasts.png ├── SomeJavaIssuesAddressedInKotlin.png ├── StethoTip.jpg ├── StopGradleProcesses.jpg ├── StringTemplates.png ├── TailrecUsage.png ├── TakeIf.png ├── TestingWithMockito.png ├── ToolsToImproveRendering.png ├── Transient.png ├── TypeAliases.png ├── Typealias.png ├── UsefulViewPagerExtensions.png ├── UsingApplySample.png ├── UtilityFunctions.png ├── VcsShortcutsForMDD.png ├── ViewLifeCycle.png ├── ViewModelExtSafeLaunch.png ├── ViewModelExtension.png ├── ViewVisiblityExt.png ├── WhatsNewInAndroidPie.jpg ├── WhenExhaustive.png ├── WhenInKotlin1-3.png ├── WhenWithMixedObjects.jpg ├── WhyUseModularization.jpg ├── backgroundwork.png ├── easyspannableonkotlin.png ├── layoutparams.png ├── mapComprasion.png ├── usingParcelizeInKotlin.png └── zipWithNextAndWindowed.png /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/.DS_Store -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## PR Checklist 2 | 3 | Please check if your PR fulfills the following requirements: 4 | 5 | - [Carbon](carbon.now.sh) Requirements 6 | - [ ] Select `Dracula` Theme 7 | - [ ] Select right `programming language` 8 | - [ ] Set `largest` font size 9 | 10 | - Commit requirements 11 | - [ ] Image should be added to root 12 | - [ ] Naming should be short description of tip 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Android Daily Tips 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # android-daily-tips 2 | 3 | ### Daily Tips From Android World 4 | [![GitHub stars](https://img.shields.io/github/stars/MobileTipsters/android-daily-tips.svg)](https://github.com/MobileTipsters/android-daily-tips/stargazers) 5 | [![GitHub issues](https://img.shields.io/github/issues/MobileTipsters/android-daily-tips.svg)](https://github.com/MobileTipsters/android-daily-tips/issues) 6 | [![GitHub license](https://img.shields.io/github/license/MobileTipsters/android-daily-tips.svg)](https://github.com/MobileTipsters/android-daily-tips) 7 | 8 | [![alt text][TwitterIcon]][Twitter] 9 | [![alt text][InstagramIcon]][Instagram] 10 | [![alt text][TelegramIcon]][Telegram] 11 | 12 | ### #186 Fragment Container View 13 | ![alt text](/screenshots/FragmentContainerView.png) 14 | 15 | ### #185 Filter Google Places Autocomplete 16 | ![alt text](/screenshots/FilterGooglePlacesAutocomplete.png) 17 | 18 | ### #184 String Extension JoinToString 19 | ![alt text](/screenshots/JoinToString.png) 20 | 21 | ### #183 Android DI Performance 22 | ![alt text](/screenshots/android_di_performance.jpg) 23 | 24 | ### #182 Flow Api Cheat Sheet by Remy Benza 25 | ![alt text](/screenshots/flow_api_cheat_sheet.jpg) 26 | 27 | ### [#181 Sequence](/codes/Sequence.kt) 28 | ![alt text](/screenshots/Sequence.png) 29 | 30 | ### [#180 Providing Build Config Fields on Multi-Dimensional Flavor Types](/codes/MultiDimensionalFlavorConfigFields.gradle) 31 | ![alt text](/screenshots/MultiDimensionalFlavorConfigFields.png) 32 | 33 | ### #179 Bitmap Extension 34 | ![alt text](/screenshots/BitmapExtension.png) 35 | 36 | ### #178 BuildScript vs Allprojects 37 | ![alt text](/screenshots/BuildscriptVsAllprojects.png) 38 | 39 | ### [#177 Transient Annotation](/codes/Transient.kt) 40 | ![alt text](/screenshots/Transient.png) 41 | 42 | ### #176 ConstraintLayout Aspect Ratio 43 | ![alt text](/screenshots/ConstraintLayoutAspectRatio.png) 44 | 45 | ### #175 CoroutineScope Vs SupervisorScope 46 | ![alt text](/screenshots/CoroutineScopeVssupervisorScope.png) 47 | 48 | ### #174 Make When Exhaustive 49 | ![alt text](/screenshots/WhenExhaustive.png) 50 | 51 | ### #173 Delegating Setters and Getters 52 | ![alt text](/screenshots/DelegatingSettersGetters.jpg) 53 | 54 | ### #172 Proguard Keep Variants 55 | ![alt text](/screenshots/ProguardKeep.png) 56 | 57 | ### [#171 Kotlin Average Usage](/codes/Average.kt) 58 | ![alt text](/screenshots/Average.png) 59 | 60 | ### #170 View Visiblity Extensions 61 | ![alt text](/screenshots/ViewVisiblityExt.png) 62 | 63 | ### #169 Kotlin Where usage 64 | ![alt text](/screenshots/KotlinWhereUsage.jpg) 65 | 66 | ### #168 Moshi over Gson 67 | ![alt text](/screenshots/MoshiOverGson.png) 68 | 69 | ### #167 Constructor Injection over Field Injection 70 | ![alt text](/screenshots/ConstructorInjection.png) 71 | 72 | ### #166 Localizing Firebase Push Notifications 73 | ![alt text](/screenshots/AndroidLocalizedPushNotifications.png) 74 | 75 | ### #165 Dagger Android Injector 76 | ![alt text](/screenshots/DaggerAndroidInjector.png) 77 | 78 | ### [#164 Transformations switchMap and map LiveData-KTX usage](/codes/LiveDataTransformations.kt) 79 | ![alt text](/screenshots/LiveDataTransformations.png) 80 | 81 | ### #163 Creating Efficient Splash Screen 82 | ![alt text](/screenshots/EfficientSplashScreen.png) 83 | 84 | ### #162 Handling Deep Link with Navigation Component 85 | ![alt text](/screenshots/DeepLinkWithNavigationComponent.png) 86 | 87 | ### #161 Flow vs Observable 88 | ![alt text](/screenshots/FlowVsObservable.jpg) 89 | 90 | ### #160 Newline At End Of File 91 | ![alt text](/screenshots/NewlineAtEndOfFile.png) 92 | 93 | ### #159 Calling Java from Kotlin - Notation For Platform Types 94 | ![alt text](/screenshots/NotationForPlatformTypes.png) 95 | 96 | ### #158 App Background - Foreground Listener 97 | ![alt text](/screenshots/AppFgBgListener.png) 98 | 99 | ### #157 Automatically encrypts keys and values and adheres to the SharedPreference Interface 100 | ![alt text](/screenshots/EncryptedSharedPreferences.png) 101 | 102 | ### #156 Drawable vs Mipmap Folders 103 | ![alt text](/screenshots/DrawableVsMipMapFolders.jpg) 104 | 105 | ### #155 Extension functions for View Model Providers 106 | ![alt text](/screenshots/ViewModelExtension.png) 107 | 108 | ### #154 Relation Between Livedata,MutableLiveData and MediatorLiveData 109 | ![alt text](/screenshots/RelationBetweenLivedataAndSubClasses.png) 110 | 111 | ### #153 Coroutines Continuation Usage 112 | ![alt text](/screenshots/CoroutinesContinuationUsage.png) 113 | 114 | ### #152 Reading-Writing lists from/to RoomDB with Moshi 115 | ![alt text](/screenshots/RoomTypeConverter.png) 116 | 117 | ### #151 Jetpack Compose Sample 118 | ![alt text](/screenshots/JetpackCompose.png) 119 | 120 | ### #150 Launch vs Async 121 | ![alt text](/screenshots/LaunchVsAsync.jpg) 122 | 123 | ### #149 EditText Manual Focus Forward 124 | ![alt text](/screenshots/EditTextManualFocusForward.jpg) 125 | 126 | ### #148 Function Interfaces 127 | ![alt text](/screenshots/FunctionInterfaces.jpg) 128 | 129 | ### #147 DI Impl Costs Chart 130 | ![alt text](/screenshots/DiImplCosts.jpg) 131 | 132 | ### #146 Easy Spannable on Kotlin 133 | ![alt text](/screenshots/easyspannableonkotlin.png) 134 | 135 | ### #145 ApiCalls and Suspend Functions 136 | ![alt text](/screenshots/ApiCallsAndSuspendFunctions.png) 137 | 138 | ### #144 First and Predicate Usage 139 | ![alt text](/screenshots/FirstAndPredicate.jpg) 140 | 141 | ### #143 Luhn Check 142 | ![alt text](/screenshots/LuhnCheck.png) 143 | 144 | ### #142 List Impl. Discuss 145 | ![alt text](/screenshots/ListImplDiscuss.png) 146 | 147 | ### #141 How to Read From Json 148 | ![alt text](/screenshots/ReadFromJson.png) 149 | 150 | ### #140 Checking Location Services with AndroidX 151 | ![alt text](/screenshots/CheckingLocationServices.png) 152 | 153 | ### #139 How LiveData works? 154 | ![alt text](/screenshots/LiveData.png) 155 | 156 | ### #138 RxJava Firebase Storage Sample Usage 157 | ![alt text](/screenshots/RxJavaFirebaseStorageSample.png) 158 | 159 | ### #137 Naming Imports 160 | ![alt text](/screenshots/NamingImportExample.png) 161 | 162 | ### #136 Keyboard Show/Hide Ext. 163 | ![alt text](/screenshots/KeyboardShowHideExt.png) 164 | 165 | ### #135 Correct usage of LifeCycleOwner in Fragments 166 | ![alt text](/screenshots/FragmentLiveDataLifeCycleOwner.png) 167 | 168 | ### #134 Handling onBackPressed on Fragments 169 | ![alt text](/screenshots/BackPressedOnFragments.jpg) 170 | 171 | ### #133 Mapper in Kotlin 172 | ![alt text](/screenshots/Mapper.png) 173 | 174 | ### #132 Why use Modularization in Android App Dev? 175 | ![alt text](/screenshots/WhyUseModularization.jpg) 176 | 177 | ### #131 Understanding Let Apply Run Also With 178 | ![alt text](/screenshots/LetApplyRunAlsoWith.jpg) 179 | 180 | ### #130 Android Studio Apply Changes 181 | ![alt text](/screenshots/ApplyChanges.jpg) 182 | 183 | ### #129 Art vs Dalvik 184 | ![alt text](/screenshots/ArtVsDalvik.jpg) 185 | 186 | ### #128 Static protection techniques that Dexguard provides 187 | ![alt text](/screenshots/Dexguard.jpg) 188 | 189 | ### #127 Sample network call with using RxJava, ViewModel and LiveData 190 | ![alt text](/screenshots/NetworkCallWithRxJavaAndViewModel.png) 191 | 192 | ### #126 ArrayList to String with Separator 193 | ![alt text](/screenshots/ArrayListToString.png) 194 | 195 | ### #125 ViewModel Extension for Coroutines Safe Launch 196 | ![alt text](/screenshots/ViewModelExtSafeLaunch.png) 197 | 198 | ### #124 Kotlin In and Is Usage 199 | ![alt text](/screenshots/KotlinInIs.jpg) 200 | 201 | ### #123 App Component Factory 202 | ![alt text](/screenshots/AppComponentFactory.png) 203 | 204 | ### #122 When With Mixed Objects 205 | ![alt text](/screenshots/WhenWithMixedObjects.jpg) 206 | 207 | ### #121 Observing Network Requests with Stetho 208 | ![alt text](/screenshots/StethoTip.jpg) 209 | 210 | ### #120 Interitance With Data Classes 211 | ![alt text](/screenshots/InteritanceWithDataClasses.jpg) 212 | 213 | ### #119 Key Points of Android Q Features 214 | ![alt text](/screenshots/AndroidQFeatures.png) 215 | 216 | ### [#118 Dowlading file using OkHttp & Okio](/codes/DowloadingFileOkhttpOkio.kt) 217 | ![alt text](/screenshots/DowloadingFileOkhttpOkio.png) 218 | 219 | ### #117 Kotlin As Class Clash (by Ragunath Jawahar #30DaysOfKotlin) 220 | ![alt text](/screenshots/KotlinAsClassClash.jpg) 221 | 222 | ### [#116 Fragment Lifecyclescope.laucnhWhenStarted](/codes/LaunchWhenStarted.kt) 223 | ![alt text](/screenshots/LaunchWhenStarted.png) 224 | 225 | ### #115 Local First with Coroutines 226 | ![alt text](/screenshots/LocalFirstWithCoroutines.jpg) 227 | 228 | ### [#114 Logging methods and parameters with Live Template](/codes/LogginWithLiveTemplate.kt) 229 | ![alt text](/screenshots/LogginWithLiveTemplate.png) 230 | 231 | ### #113 Kotlin Run 232 | ![alt text](/screenshots/KotlinRun.jpg) 233 | 234 | ### #112 Kapt Incremental Compilation 235 | ![alt text](/screenshots/KaptIncrementalCompilation.jpg) 236 | 237 | ### #111 Creating Hidden Files 238 | ![alt text](/screenshots/CreatingHiddenFiles.jpg) 239 | 240 | ### #110 Locus Id 241 | ![alt text](/screenshots/LocusId.jpg)) 242 | 243 | ### #109 Setting RecyclerView LayoutManager from Xml 244 | ![alt text](/screenshots/RecyclerViewLayoutManagerWithXml.jpg) 245 | 246 | ### #108 Preventing setValue or postValue from UI 247 | ![alt text](/screenshots/ObservingLiveData.png) 248 | 249 | ### #107 Android Background Work Decision Graph 250 | ![alt text](/screenshots/backgroundwork.png) 251 | 252 | ### #106 Fragment Argument Delegate 253 | ![alt text](/screenshots/FragmentArgumentDelegate.png) 254 | 255 | ### #105 Db Entity Mapper 256 | ![alt text](/screenshots/DbEntityMapper.png) 257 | 258 | ### #104 Rx Debounce with Kotlin Coroutines 259 | ![alt text](/screenshots/RxDebounceWithKotlinCoroutines.jpg) 260 | 261 | ### #103 Data Binding SeekBar Color 262 | ![alt text](/screenshots/DataBindingSeekBarColor.jpg) 263 | 264 | ### #102 Useful ViewPager Extensions 265 | ![alt text](/screenshots/UsefulViewPagerExtensions.png) 266 | 267 | ### #101 Android Action Mode 268 | ![alt text](/screenshots/AndroidActionMode.png) 269 | 270 | ### #100 Room with Dagger 271 | ![alt text](/screenshots/RoomWithDagger.png) 272 | 273 | ### #99 Recyclerview Setup 274 | ![alt text](/screenshots/RecyclerviewSetup.png) 275 | 276 | ### #98 Handling Generic ApiResponse with Coroutines 277 | ![alt text](/screenshots/HandlingGenericApiResponseWithCoroutines.png) 278 | 279 | ### #97 Coroutines Async Manager 280 | ![alt text](/screenshots/CoroutinesAsyncManager.png) 281 | 282 | ### #96 SingleLiveData 283 | ![alt text](/screenshots/SingleLiveData.png) 284 | 285 | ### #95 Parcelable vs Serializable 286 | ![alt text](/screenshots/ParcelableVsSerializable.png) 287 | 288 | ### #94 Kotlin Delegation By 289 | ![alt text](/screenshots/KotlinDelegationBy.png) 290 | 291 | ### #93 TakeIf 292 | ![alt text](/screenshots/TakeIf.png) 293 | 294 | ### #92 Handling Api Result with Sealed Class 295 | ![alt text](/screenshots/HandlingApiResultWithSealedClass.png) 296 | 297 | ### #91 Android Arch. 298 | ![alt text](/screenshots/AndroidArchitecture.jpg) 299 | 300 | ### #90 Reified Type find Fragment 301 | ![alt text](/screenshots/ReifiedTypeFindFragment.jpg) 302 | 303 | ### #89 Dalvik vs Art 304 | ![alt text](/screenshots/DalvikVsArt.png) 305 | 306 | ### #88 Preconditions 307 | ![alt text](/screenshots/Preconditions.png) 308 | 309 | ### #87 Typealias 310 | ![alt text](/screenshots/Typealias.png) 311 | 312 | ### #86 Checking Permissions 313 | ![alt text](/screenshots/CheckingPermissions.png) 314 | 315 | ### #85 Any TryCatch 316 | ![alt text](/screenshots/AnyTryCatch.png) 317 | 318 | ### #84 LiveData Generic Error Handling 319 | ![alt text](/screenshots/LiveDataGenericErrorHandling.png) 320 | 321 | ### #83 Android Studio 3.3 Features 322 | ![alt text](/screenshots/AndroidStudioReleaseNewFeatures.jpg) 323 | 324 | ### #82 Kotlin Delegate for Initializing 325 | ![alt text](/screenshots/KotlinDelegateForInitializing.png) 326 | 327 | ### #81 Testing with Mockito 328 | ![alt text](/screenshots/TestingWithMockito.png) 329 | 330 | ### #80 Utility Functions 331 | ![alt text](/screenshots/UtilityFunctions.png) 332 | 333 | ### #79 Property Override 334 | ![alt text](/screenshots/PropertyOverride.png) 335 | 336 | ### #78 Coroutine ViewModel 337 | ![alt text](/screenshots/CoroutineViewModel.png) 338 | 339 | ### #77 RxJava Concat Usage 340 | ![alt text](/screenshots/RxJavaConcatUsage.png) 341 | 342 | ### #76 Single RecyclerView Adapter 343 | ![alt text](/screenshots/SingleRecyclerViewAdapter.png) 344 | 345 | ### #75 Common Gradle File 346 | ![alt text](/screenshots/CommonGradleFile.png) 347 | 348 | ### #74 Extension Function For Rx Subscriptions 349 | ![alt text](/screenshots/ExtensionFuncForRxSubscriptions.png) 350 | 351 | ### #73 Map Associate 352 | ![alt text](/screenshots/MapAssociate.png) 353 | 354 | ### #72 Android Layout Params 355 | ![alt text](/screenshots/layoutparams.png) 356 | 357 | ### #71 Android Feature Module 358 | ![alt text](/screenshots/FeatureModule.png) 359 | 360 | ### #70 Reified Type Parameters 361 | ![alt text](/screenshots/ReifiedTypeParameters.png) 362 | 363 | ### #69 Performance Tips 364 | ![alt text](/screenshots/PerformanceTips.jpg) 365 | 366 | ### #68 Package Info 367 | ![alt text](/screenshots/PackageInfo.png) 368 | 369 | ### #67 Kotlin Standart Functions Cheatsheet 370 | ![alt text](/screenshots/KotlinStandartFunctions.png) 371 | 372 | ### #66 JvmOverloads 373 | ![alt text](/screenshots/JvmOverloads.png) 374 | 375 | ### #65 Device and Network Requests 376 | ![alt text](/screenshots/1kbDownloadWithDevice.png) 377 | 378 | ### #65 Local Return 379 | ![alt text](/screenshots/LocalReturn.png) 380 | 381 | ### #64 Looper 382 | ![alt text](/screenshots/Looper.png) 383 | 384 | ### #63 Sync version of Async method 385 | ![alt text](/screenshots/AsyncToSync.png) 386 | 387 | ### #62 EditText Listener Impl 388 | ![alt text](/screenshots/EditTextListenerImpl.png) 389 | 390 | ### #61 MVI Architecture 391 | ![alt text](/screenshots/MviArchitecture.png) 392 | 393 | ### #60 Flatten Array 394 | ![alt text](/screenshots/FlattenArray.png) 395 | 396 | ### [#59 Kotlin Delegated Properties Observable](/codes/ObservableDelegation.kt) 397 | ![alt text](/screenshots/ObservableDelegation.png) 398 | 399 | ### #58 View Lifecycle 400 | ![alt text](/screenshots/ViewLifeCycle.png) 401 | 402 | ### #57 AndroidViewHierarchy 403 | ![alt text](/screenshots/AndroidViewHierarchy.png) 404 | 405 | ### #56 Kotlin DSL 406 | ![alt text](/screenshots/KotlinDsl.png) 407 | 408 | ### #55 APK Signature Scheme v2 409 | ![alt text](/screenshots/ApkSignatureSchemeV2.png) 410 | 411 | ### #54 MVP Architecture 412 | ![alt text](/screenshots/MvpArchitecture.png) 413 | 414 | ### #53 Gradle Configuration File 415 | ![alt text](/screenshots/GradleConfigurationFile.png) 416 | 417 | ### #52 Coroutines vs RxKotlin 418 | ![alt text](/screenshots/CoroutinesVsRxKotlin.png) 419 | 420 | ### #51 Coroutines 421 | ![alt text](/screenshots/Coroutines.png) 422 | 423 | ### #50 Fancy way to set OnClickListeners 424 | ![alt text](/screenshots/FancyWayToSetOnClickListeners.png) 425 | 426 | ### #49 Kotlin Package-Level Functions 427 | ![alt text](/screenshots/PackageLevelFunctions.png) 428 | 429 | ### #48 Android Coroutines Continuation 430 | ![alt text](/screenshots/AndroidCoroutinesContinuation.png) 431 | 432 | ### #47 MDD - VCS Shortcuts 433 | ![alt text](/screenshots/VcsShortcutsForMDD.png) 434 | 435 | ### #46 Android Performance Tips: 436 | ![alt text](/screenshots/AndroidPerformanceTips.png) 437 | 438 | ### #45 Target Fragment 439 | ![alt text](/screenshots/SetTargetFragment.png) 440 | 441 | ### [#44 Repeat Function](/codes/RepeatFunction.kt) 442 | ![alt text](/screenshots/RepeatFunction.png) 443 | 444 | ### [#43 Type Alias Usage](/codes/TypeAliases.kt) 445 | ![alt text](/screenshots/TypeAliases.png) 446 | 447 | ### [#42 Tailrec Usage](/codes/TailrecUsage.kt) 448 | ![alt text](/screenshots/TailrecUsage.png) 449 | 450 | ### [#41 Smart Casts](/codes/SmartCast.kt) 451 | ![alt text](/screenshots/SmartCasts.png) 452 | 453 | ### [#40 Infix Functions](/codes/InfixFunctions.kt) 454 | ![alt text](/screenshots/InfixFunctions.png) 455 | 456 | ### [#39 Local Functions](/codes/LocalFunctions.kt) 457 | ![alt text](/screenshots/LocalFunctions.png) 458 | 459 | ### #38 Some Java Issues Addressed in Kotlin 460 | ![alt text](/screenshots/SomeJavaIssuesAddressedInKotlin.png) 461 | 462 | ### [#37 ArrayMap vs HashMap](/codes/MapComparison.kt) 463 | ![alt text](/screenshots/mapComprasion.png) 464 | 465 | ### [#36 Using Parcelize in Kotlin](/codes/usingParcelizeInKotlin.kt) 466 | ![usingParcelizeInKotlin](/screenshots/usingParcelizeInKotlin.png) 467 | 468 | ### [#35 HashCode for Nullable Types in Kotlin 1.3](/codes/HasCodeForNullableTypes.kt) 469 | ![alt text](/screenshots/HashCodeForNullableTypes.png) 470 | 471 | ### [#34 Stop All Gradle Processes](/codes/StopGradleProcesses.sh) 472 | ![StopGradleProcesses](/screenshots/StopGradleProcesses.jpg) 473 | 474 | ### [#33 Random Extension Function in Kotlin 1.3](/codes/RandomExtFuncInKotlin1-3.kt) 475 | ![alt text](/screenshots/RandomExtFuncInKotlin1-3.png) 476 | 477 | ### [#32 When in Kotlin 1.3](/codes/WhenInKotlin1-3.kt) 478 | ![alt text](/screenshots/WhenInKotlin1-3.png) 479 | 480 | ### [#31 ActivityRecognition](/codes/ActivityRecognition.kt) 481 | ![alt text](/screenshots/ActivityRecognition.png) 482 | 483 | ### [#30 Memory Optimization](/codes/MemoryOptimization.kt) 484 | ![alt text](/screenshots/MemoryOptimization.png) 485 | 486 | ### #29 What's New in Android Pie? 487 | ![alt text](/screenshots/WhatsNewInAndroidPie.jpg) 488 | 489 | ### [#28 Range Using](/codes/RangeUsing.kt) 490 | ![alt text](/screenshots/RangeUsing.png) 491 | 492 | ### [#27 Kotlin Style Support Version Check](/codes/KotlinStyleSupportVersionCheck.kt) 493 | ![alt text](/screenshots/KotlinStyleSupportVersionCheck.jpg) 494 | 495 | ### #26 How To Resolve App Launching Time Delay 496 | ![alt text](/screenshots/HowToResolveAppLaunchingTimeDelay.png) 497 | 498 | ### #25 Tools To Improve Rendering 499 | ![alt text](/screenshots/ToolsToImproveRendering.png) 500 | 501 | ### [#24 Lazy Loading](/codes/LazyLoading.kt) 502 | ![alt text](/screenshots/LazyLoading.png) 503 | 504 | ### [#23 Execute Body If In Debug Mode](/codes/ExecuteBodyIfDebugMode.kt) 505 | ![alt text](/screenshots/ExecuteBodyIfDebugMode.png) 506 | 507 | ### #22 6 Mobile Security Tips 508 | ![alt text](/screenshots/6MobileSecurityTips.png) 509 | 510 | ### #21 Zip With Next And Windowed 511 | ![alt text](/screenshots/zipWithNextAndWindowed.png) 512 | 513 | ### #20 How To Store Data Locally 514 | ![alt text](/screenshots/HowToStoreDataLocally.png) 515 | 516 | ### [#19 Defining Map With Kotlin](/codes/DefiningMapWithKotlin.kt) 517 | ![alt text](/screenshots/DefiningMapWithKotlin.png) 518 | 519 | ### [#18 How To Get Primary Color Of Theme](/codes/HowToGetPrimaryColorOfTheme.kt) 520 | ![alt text](/screenshots/HowToGetPrimaryColorOfTheme.png) 521 | 522 | ### [#17 Check Network Connection](/codes/CheckNetworkConnection.kt) 523 | ![alt text](/screenshots/CheckNetworkConnection.png) 524 | 525 | ### [#16 String Templates](/codes/StringTemplates.kt) 526 | ![alt text](/screenshots/StringTemplates.png) 527 | 528 | ### [#15 Using Apply Sample](/codes/UsingApplySample.kt) 529 | ![alt text](/screenshots/UsingApplySample.png) 530 | 531 | ### [#14 Elvis Operator](/codes/ElvisOperator.kt) 532 | ![alt text](/screenshots/ElvisOperator.png) 533 | 534 | ### #13 Git Pull 535 | ![alt text](/screenshots/GitPull.png) 536 | 537 | ### #12 Git Fetch 538 | ![alt text](/screenshots/GitFetch.png) 539 | 540 | ### [#11 Commit Vs Commit Allowing State Loss](/codes/CommitVsCommitAllowingStateLoss.kt) 541 | ![alt text](/screenshots/CommitVsCommitAllowingStateLoss.png) 542 | 543 | ### [#10 Kotlin Way To Create Singletons](/codes/KotlinWayToCreateSingletons.kt) 544 | ![alt text](/screenshots/KotlinWayToCreateSingletons.png) 545 | 546 | ### #9 Kotlin Way To Add Or Remove View 547 | ![alt text](/screenshots/AppActions.png) 548 | 549 | ### #8 Mastering Kotlin Standard Functions 550 | ![alt text](/screenshots/MasteringKotlinStandartFunctions.png) 551 | 552 | ### #7 Avoid Memory Leaks With Inner Classes 553 | ![alt text](/screenshots/AvoidMemoryLeaksWithInnerClasses.png) 554 | 555 | ### #6 Key Features To Increase Reach And Engagement 556 | ![alt text](/screenshots/KeyFeaturesToIncreaseReachAndEngagement.png) 557 | 558 | ### #5 Kotlin Readable And Clean Code 559 | ![alt text](/screenshots/KotlinReadableAndCleanCode.png) 560 | 561 | ### [#4 Kotlin Way To Add Or Remove View](/codes/KotlinWayToAddOrRemoveView.kt) 562 | ![alt text](/screenshots/KotlinWayToAddOrRemoveView.png) 563 | 564 | ### [#3 Efficient String Concatenation](/codes/EfficientStringConcat.kt) 565 | ![alt text](/screenshots/EfficientStringConcat.png) 566 | 567 | ### [#2 Safe Constant Null Check](/codes/SafeConstantNullCheck.java) 568 | ![alt text](/screenshots/SafeConstantNullCheck.png) 569 | 570 | ### [#1 Implicit Null Check](/codes/ImplicitNullCheck.java) 571 | ![alt text](/screenshots/ImplicitNullCheck.png) 572 | 573 | [TwitterIcon]: /art/twitter.png (twitter) 574 | [InstagramIcon]: /art/instagram.png (instagram) 575 | [TelegramIcon]: /art/telegram.png (telegram) 576 | 577 | [Twitter]: https://twitter.com/AndroidDailyTip 578 | [Instagram]: https://www.instagram.com/androiddailytips/ 579 | [Telegram]: https://t.me/androiddailytips 580 | -------------------------------------------------------------------------------- /art/instagram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/art/instagram.png -------------------------------------------------------------------------------- /art/telegram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/art/telegram.png -------------------------------------------------------------------------------- /art/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/art/twitter.png -------------------------------------------------------------------------------- /codes/ActivityRecognition.kt: -------------------------------------------------------------------------------- 1 | 2 | Activity Recognition gives our android device the ability to detect a number of our physical activities. 3 | 4 | // The Activity Recognition API is an interface that periodically wakes the device, 5 | // reads bursts of data from the device’s sensors, and then analyzes this data using powerful machine learning models. 6 | 7 | The activities supported with the Transition API are: 8 | * IN_VEHICLE 9 | * ON_FOOT 10 | * RUNNING 11 | * WALKING 12 | * ON_BICYCLE 13 | * STILL 14 | 15 | // To use the Transition API requirement 16 | * Permission --> 17 | * API version --> 12.0.0 or higher 18 | -------------------------------------------------------------------------------- /codes/ArrayListToString.kt: -------------------------------------------------------------------------------- 1 | //Easiest way to create string from array with separator 2 | 3 | fun main(args: Array) { 4 | val productIdsArray : ArrayList = ArrayList() 5 | productIdsArray.add("190") 6 | productIdsArray.add("191") 7 | productIdsArray.add("192") 8 | productIdsArray.add("193") 9 | productIdsArray.add("194") 10 | productIdsArray.add("195") 11 | 12 | val productIdsString = productIdsArray.joinToString(separator = ",") 13 | println(productIdsString) 14 | } -------------------------------------------------------------------------------- /codes/Average.kt: -------------------------------------------------------------------------------- 1 | val list = arrayListOf(2.0, 3.0, 7.0) 2 | var sum = 0 3 | list.forEach{ 4 | sum += it.toInt() 5 | } 6 | println(sum/list.size) // 4 7 | println(list.average().toInt()) // 4 -------------------------------------------------------------------------------- /codes/CheckNetworkConnection.kt: -------------------------------------------------------------------------------- 1 | import android.content.Context 2 | import android.net.ConnectivityManager 3 | 4 | internal fun isConnected(context: Context): Boolean { 5 | val connetivityManager = 6 | context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager 7 | return connetivityManager.activeNetworkInfo?.isConnectedOrConnecting ?: false 8 | } -------------------------------------------------------------------------------- /codes/CommitVsCommitAllowingStateLoss.kt: -------------------------------------------------------------------------------- 1 | fun commitAllowingStateLoss(): Int = commitInternal(true) 2 | 3 | fun commit() = commitInternal(false) 4 | 5 | fun commitInternal(allowStateLoss: Boolean): Int { 6 | //... 7 | if (!allowStateLoss) { 8 | checkStateLoss() 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /codes/CorouitinesContinuation.kt: -------------------------------------------------------------------------------- 1 | package katas.`3kyu` 2 | 3 | import java.util.* 4 | import kotlin.coroutines.* 5 | 6 | fun plus(o1: Optional, o2: Optional): Optional = `for` { 7 | val i1: Int = bind(o1) 8 | val i2: Int = bind(o2) 9 | yield(i1 + i2) 10 | } 11 | 12 | suspend fun bind(value: Optional): T { 13 | return suspendCoroutine { cont -> 14 | if (value.isPresent) 15 | cont.resumeWith(Result.success(value.get())) 16 | else 17 | cont.resumeWith(Result.failure(fail())) 18 | } 19 | } 20 | 21 | fun yield(value: T) = Optional.of(value) 22 | 23 | fun `for`(lambda: suspend () -> Optional): Optional { 24 | var ret: Optional = Optional.empty() 25 | val completion: Continuation> = object : Continuation> { 26 | override val context: CoroutineContext = EmptyCoroutineContext 27 | 28 | override fun resumeWith(result: Result>) { 29 | ret = result.getOrElse { 30 | when (it) { 31 | is NoSuchElementException -> Optional.empty() 32 | else -> throw it 33 | } 34 | } 35 | } 36 | } 37 | lambda.startCoroutine(completion) 38 | return ret 39 | } 40 | 41 | fun fail() = Exception() 42 | 43 | -------------------------------------------------------------------------------- /codes/DeepLinkWithNavigationComponent.kt: -------------------------------------------------------------------------------- 1 | // Step 1: Add deep link element inside fragment of navigation graph 2 | 3 | 4 | // Step 2: To enable implicit deep linking, Add a single element to an activity that points to an existing navigation graph 5 | 6 | 8 | 9 | 10 | 11 | 12 | ... 13 | 14 | 15 | 16 | ... 17 | 18 | 19 | 20 | 21 | 22 | 23 | // Step 3 (Optional): Also you can handle parameters of deep link with placeholder 24 | 25 | 26 | // Step 4: To read data from placeholder, you need add an argument below deep link element 27 | 28 | 29 | // Step 5: Now you can use deep link placeholder's data in fragment with arguments 30 | val displayName = arguments?.get("display_name") as String -------------------------------------------------------------------------------- /codes/DefiningMapWithKotlin.kt: -------------------------------------------------------------------------------- 1 | val map = mapOf( 2 | "keyA" to "valueA", 3 | "keyB" to "valueB", 4 | "keyC" to "valueC" 5 | ) 6 | -------------------------------------------------------------------------------- /codes/DowloadingFileOkhttpOkio.kt: -------------------------------------------------------------------------------- 1 | // Downloading file using OkHttp & Okio 2 | 3 | private lateinit var client: OkHttpClient 4 | 5 | fun dowloadFile(url: String) { 6 | val httpUrl = HttpUrl.parse(url)!! 7 | val fileName = httpUrl.encodedPathSegments().last() ?: "file" 8 | val response = client.newCall(Request.Builder().get().url(url).build()).execute() 9 | val source = response.body()?.source() 10 | val file = File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), fileName) 11 | if (file.createNewFile()) { 12 | val buffer = file.sink().buffer() 13 | source?.use { input -> 14 | buffer.use { output -> 15 | output.writeAll(input) 16 | } 17 | } 18 | } 19 | } -------------------------------------------------------------------------------- /codes/EasySpannableOnKotlin.kt: -------------------------------------------------------------------------------- 1 | val spanned = spannable { 2 | bold("Sample Bold") + 3 | italic("And Italic Text") + 4 | color(Color.BLUE, "Blue Colored Text") 5 | } 6 | 7 | val nested = spannable{ bold(italic("nested ")) + url("www.google.com", "text") } 8 | 9 | textView.text = spanned + nested 10 | 11 | // Spannable.kt extension for further manipulations 12 | 13 | import android.text.Spannable 14 | import android.text.SpannableString 15 | import android.text.TextUtils 16 | import android.text.style.* 17 | 18 | fun spannable(func: () -> SpannableString) = func() 19 | private fun span(s: CharSequence, o: Any) = (if (s is String) SpannableString(s) else s as? SpannableString 20 | ?: SpannableString("")).apply { setSpan(o, 0, length, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE) } 21 | 22 | operator fun SpannableString.plus(s: SpannableString) = SpannableString(TextUtils.concat(this, s)) 23 | operator fun SpannableString.plus(s: String) = SpannableString(TextUtils.concat(this, s)) 24 | 25 | fun bold(s: CharSequence) = span(s, StyleSpan(android.graphics.Typeface.BOLD)) 26 | fun italic(s: CharSequence) = span(s, StyleSpan(android.graphics.Typeface.ITALIC)) 27 | fun underline(s: CharSequence) = span(s, UnderlineSpan()) 28 | fun strike(s: CharSequence) = span(s, StrikethroughSpan()) 29 | fun sup(s: CharSequence) = span(s, SuperscriptSpan()) 30 | fun sub(s: CharSequence) = span(s, SubscriptSpan()) 31 | fun size(size: Float, s: CharSequence) = span(s, RelativeSizeSpan(size)) 32 | fun color(color: Int, s: CharSequence) = span(s, ForegroundColorSpan(color)) 33 | fun background(color: Int, s: CharSequence) = span(s, BackgroundColorSpan(color)) 34 | fun url(url: String, s: CharSequence) = span(s, URLSpan(url)) 35 | -------------------------------------------------------------------------------- /codes/EfficientStringConcat.kt: -------------------------------------------------------------------------------- 1 | val names = listOf("John", "Jane", "Micheal") 2 | var allNames = "" 3 | 4 | //WRONG WAY 5 | names.forEach { name -> 6 | allNames += name 7 | } 8 | 9 | //RIGHT WAY 10 | val nameBuilder = StringBuilder() 11 | names.forEach { name -> 12 | nameBuilder.append(name) 13 | } 14 | -------------------------------------------------------------------------------- /codes/ElvisOperator.kt: -------------------------------------------------------------------------------- 1 | val name: String? = "Android Daily Tips" 2 | 3 | val nameLength: Int = name?.length ?: -1 -------------------------------------------------------------------------------- /codes/EncryptedSharedPreferences.kt: -------------------------------------------------------------------------------- 1 | // Step 1: Create or retrieve the Master Key for encryption/decryption 2 | val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) 3 | 4 | // Step 2: Initialize/open an instance of EncryptedSharedPreferences 5 | val sharedPreferences = EncryptedSharedPreferences.create( 6 | "secret_shared_prefs", 7 | masterKeyAlias, 8 | applicationContext, 9 | EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV, 10 | EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM 11 | ) 12 | 13 | 14 | // Step 3: Save data to the EncryptedSharedPreferences as usual 15 | sharedPreferences.edit() 16 | .putString("KEY_VALUE", saveText.text.toString()) 17 | .apply() 18 | 19 | 20 | // Step 4: Read data from EncryptedSharedPreferences as usual 21 | val value = sharedPreferences.getString("KEY_VALUE", "") -------------------------------------------------------------------------------- /codes/ExecuteBodyIfDebugMode.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * execute "body" if app in debug mode 3 | */ 4 | 5 | inline fun debug(body: () -> Unit) { 6 | if (BuildConfig.DEBUG) body() 7 | } -------------------------------------------------------------------------------- /codes/FilterGooglePlacesAutocomplete.kt.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Filtering Google Places Autocomplete Results 3 | */ 4 | 5 | /* 6 | * Field list to receive from the place instances 7 | */ 8 | val fields = listOf( 9 | Place.Field.NAME, 10 | Place.Field.ADDRESS, 11 | Place.Field.LAT_LNG 12 | ) 13 | 14 | /* 15 | * Rectangular area bounds to filter place results 16 | */ 17 | val bounds = RectangularBounds.newInstance( 18 | LatLng(-33.880490, 151.184363), 19 | LatLng(-33.858754, 151.229596) 20 | ) 21 | 22 | val placesBuilder = Autocomplete.IntentBuilder( 23 | AutocompleteActivityMode.OVERLAY, 24 | fields 25 | ) 26 | 27 | /* 28 | * Filter places result by area bounds 29 | */ 30 | placesBuilder.setLocationBias(bounds) 31 | 32 | /* 33 | * Filter places result by country code 34 | */ 35 | placesBuilder.setCountry("TR") 36 | 37 | /* 38 | * Start places search intent 39 | */ 40 | startActivityForResult(placesBuilder.build(context), 1000) -------------------------------------------------------------------------------- /codes/FragmentArgumentDelegate.kt: -------------------------------------------------------------------------------- 1 | package com.androiddailytips 2 | 3 | import android.os.Binder 4 | import android.os.Bundle 5 | import androidx.core.app.BundleCompat 6 | import androidx.fragment.app.Fragment 7 | import kotlin.properties.ReadWriteProperty 8 | import kotlin.reflect.KProperty 9 | 10 | // Fragment Argument Delegate 11 | class FragmentArgumentDelegate : ReadWriteProperty { 12 | 13 | var value: T? = null 14 | 15 | override operator fun getValue(thisRef: Fragment, property: KProperty<*>): T { 16 | if (value == null) { 17 | val args = thisRef.arguments 18 | ?: throw IllegalStateException("Cannot read property ${property.name} if no arguments have been set") 19 | @Suppress("UNCHECKED_CAST") 20 | value = args.get(property.name) as T 21 | } 22 | return value ?: throw IllegalStateException("Property ${property.name} could not be read") 23 | } 24 | 25 | override operator fun setValue(thisRef: Fragment, property: KProperty<*>, value: T) { 26 | if (thisRef.arguments == null) thisRef.arguments = Bundle() 27 | 28 | val args = thisRef.arguments 29 | val key = property.name 30 | 31 | when (value) { 32 | is String -> args?.putString(key, value) 33 | is Int -> args?.putInt(key, value) 34 | is Short -> args?.putShort(key, value) 35 | is Long -> args?.putLong(key, value) 36 | is Byte -> args?.putByte(key, value) 37 | is ByteArray -> args?.putByteArray(key, value) 38 | is Char -> args?.putChar(key, value) 39 | is CharArray -> args?.putCharArray(key, value) 40 | is CharSequence -> args?.putCharSequence(key, value) 41 | is Float -> args?.putFloat(key, value) 42 | is Bundle -> args?.putBundle(key, value) 43 | is Binder -> BundleCompat.putBinder(args!!, key, value) 44 | is android.os.Parcelable -> args?.putParcelable(key, value) 45 | is java.io.Serializable -> args?.putSerializable(key, value) 46 | else -> throw IllegalStateException("Type ${value.javaClass.canonicalName} of property ${property.name} is not supported") 47 | } 48 | } 49 | } 50 | 51 | // Usage of FragmentArgumentDelegate 52 | class ProjectFragment : Fragment() { 53 | 54 | private var projectId by FragmentArgumentDelegate() 55 | 56 | companion object { 57 | fun newInstance(projectId: String) = ProjectFragment().apply { 58 | this.projectId = projectId 59 | } 60 | } 61 | 62 | override fun onActivityCreated(savedInstanceState: Bundle?) { 63 | ... 64 | // do whatever you want with "projectId" 65 | } 66 | } 67 | 68 | // credits: https://gist.github.com/yanngx/efdfbf777d21d6f0e73fab4efe47e924 -------------------------------------------------------------------------------- /codes/FragmentLiveDataLifeCycleOwner.kt: -------------------------------------------------------------------------------- 1 | class SearchFragment : BaseFragment(SearchViewModel::class.java) { 2 | 3 | /* 4 | some stuff 5 | */ 6 | 7 | // Wrong usage 8 | if (viewModel.genresLiveData.hasActiveObservers()) 9 | viewModel.genresLiveData.removeObservers(this) 10 | 11 | viewModel.genresLiveData.observe( 12 | this@SearchFragment, 13 | Observer> { 14 | it.data?.let { genres -> addChipToGroup(mBinding.chipGroupGenres, genres) } 15 | } 16 | ) 17 | 18 | // Correct usage 19 | viewModel.genresLiveData.observe(viewLifecycleOwner, 20 | Observer> { 21 | it.data?.let { genres -> addChipToGroup(mBinding.chipGroupGenres, genres) }}) 22 | } -------------------------------------------------------------------------------- /codes/HasCodeForNullableTypes.kt: -------------------------------------------------------------------------------- 1 | /* hashcode() for Nullable Types in Kotlin 1.3 */ 2 | public inline fun Any?.hashcode(): Int = this?.hashcode() ?: 0 3 | val myHashCode: Int myObject.hashcode() -------------------------------------------------------------------------------- /codes/HowToGetPrimaryColorOfTheme.kt: -------------------------------------------------------------------------------- 1 | fun getPrimaryColor(context: Context): Int { 2 | val typedValue = TypedValue() 3 | val typedArray = context.obtainStyledAttributes(typedValue.data, intArrayOf(R.attr.colorPrimary)) 4 | val color = typedArray.getColor(0, 0) 5 | typedArray.recycle() 6 | return color 7 | } -------------------------------------------------------------------------------- /codes/ImplicitNullCheck.java: -------------------------------------------------------------------------------- 1 | //Unnecessary null check 2 | (result != null && result instanceof KeyValuePair) 3 | 4 | //Efficient approach 5 | (result instanceof KeyValuePair) -------------------------------------------------------------------------------- /codes/InfixFunctions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Infix functions are good for readability, because it allows 3 | typing something like "test" foo "x" for example. 4 | */ 5 | infix fun String.foo(s: String) { 6 | // do stg 7 | } 8 | 9 | // Call extension function 10 | "test".foo("x") 11 | 12 | // Or call extension function using infix notation. 13 | "test" foo "x" -------------------------------------------------------------------------------- /codes/JetPackCompose.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Your Activity, in the onCreate method, 3 | setContent{ 4 | //call the composable method 5 | setTextIntoTheColumn("TextView Text1", "TextView Text2") 6 | } 7 | */ 8 | 9 | @Composable 10 | fun setTextIntoTheColumn(messageOne: String, messageTwo: String) { 11 | Column { 12 | Text(text = messageOne) 13 | Text(text = messageTwo) 14 | } 15 | } -------------------------------------------------------------------------------- /codes/KeyboardShowHideExt.kt: -------------------------------------------------------------------------------- 1 | // Easiest way to show/hide keyboard 2 | 3 | fun View.showKeyboard(activity: Activity) { 4 | val inputManager: InputMethodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 5 | inputManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0) 6 | } 7 | 8 | fun View.hideKeyboard(activity: Activity) { 9 | val view = activity.findViewById(android.R.id.content) 10 | val inputManager: InputMethodManager = activity.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager 11 | inputManager.hideSoftInputFromWindow(view.windowToken, 0) 12 | } -------------------------------------------------------------------------------- /codes/KotlinStyleSupportVersionCheck.kt: -------------------------------------------------------------------------------- 1 | package com.raqun.kotlinext 2 | 3 | import android.os.Build 4 | 5 | /** 6 | * execute "func" if current version is grater than or equal to given version 7 | */ 8 | inline fun supportsVersion(ver: Int, func: () -> Unit) { 9 | if (Build.VERSION.SDK_INT >= ver) { 10 | func.invoke() 11 | } 12 | } -------------------------------------------------------------------------------- /codes/KotlinWayToAddOrRemoveView.kt: -------------------------------------------------------------------------------- 1 | inline operator fun ViewGroup.minusAssign(child: View) = removeView(child) 2 | 3 | inline operator fun ViewGroup.plusAssign(child: View) = addView(child) -------------------------------------------------------------------------------- /codes/KotlinWayToCreateSingletons.kt: -------------------------------------------------------------------------------- 1 | // Kotlin way to create singletons 2 | object Singleton { 3 | var s: String? = null 4 | } -------------------------------------------------------------------------------- /codes/LaunchWhenStarted.kt: -------------------------------------------------------------------------------- 1 | //To avoid illegal state exception you can use new launchWhenStarted method 2 | class MyFragment: Fragment { 3 | init { 4 | // We are safely launch in the Fragment constructor 5 | // even if Lifecycle will be CREATED at first 6 | 7 | lifecycleScope.launchWhenStarted { 8 | // This will suspend when state is < STARTED 9 | 10 | // Here, since we've checked, it is safe to run any 11 | // Fragment transactions. 12 | fragmentManager.beginTransaction() 13 | } 14 | } 15 | } 16 | //original article: http://bit.ly/2JDlKRs -------------------------------------------------------------------------------- /codes/LazyLoading.kt: -------------------------------------------------------------------------------- 1 | val purchasingApi: PurcahasingApi by lazy { 2 | val retrofit: Retrofit = Retrofit.Builder() 3 | .baseUrl(API_URL) 4 | .addConverterFactory(MoshiConverterFactory.create()) 5 | .build() 6 | retrofit.create(PurcahasingApi::class.java) 7 | } -------------------------------------------------------------------------------- /codes/LiveDataTransformations.kt: -------------------------------------------------------------------------------- 1 | // Transformations switchMap and map LiveData-KTX usage 2 | 3 | /* These methods permit functional composition and delegation of LiveData instances. The transformations are calculated 4 | * lazily, and will run only when the returned LiveData is observed. Lifecycle behavior is propagated from the input 5 | * source LiveData to the returned one. - more info.: developer.android.com/reference/androidx/lifecycle/Transformations 6 | */ 7 | 8 | class DashboardFragmentViewModel @Inject internal constructor(private val currentWeatherUseCase: CurrentWeatherUseCase) : BaseViewModel() { 9 | 10 | private val _currentWeatherParams: MutableLiveData = MutableLiveData() 11 | fun getCurrentWeatherViewState() = currentWeatherViewState 12 | 13 | private val currentWeatherViewState: LiveData = _currentWeatherParams.switchMap { params -> 14 | currentWeatherUseCase.execute(params) // When _currentWeatherParams triggered `switchMap` returns useCase.execute() 15 | } 16 | 17 | fun setCurrentWeatherParams(params: CurrentWeatherUseCase.CurrentWeatherParams) { 18 | if (_currentWeatherParams.value == params) 19 | return 20 | _currentWeatherParams.postValue(params) 21 | } 22 | } 23 | 24 | 25 | class CurrentWeatherUseCase @Inject internal constructor(private val repository: CurrentWeatherRepository) : UseCaseLiveData() { 26 | 27 | override fun buildUseCaseObservable(params: CurrentWeatherParams?): LiveData { 28 | return repository.loadCurrentWeatherByGeoCords( 29 | params?.lat?.toDouble() ?: 0.0, 30 | params?.lon?.toDouble() ?: 0.0, 31 | params?.fetchRequired 32 | ?: false, 33 | units = params?.units ?: Constants.Coords.METRIC 34 | ).map { // When loadCurrentWeatherByGeoCords triggered `map` returns onCurrentWeatherResultReady() 35 | onCurrentWeatherResultReady(it) 36 | } 37 | } 38 | 39 | private fun onCurrentWeatherResultReady(resource: Resource): CurrentWeatherViewState { 40 | return CurrentWeatherViewState( 41 | status = resource.status, 42 | error = resource.message, 43 | data = resource.data 44 | ) 45 | } 46 | } -------------------------------------------------------------------------------- /codes/LocalFunctions.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Local functions are good for code reuse, 3 | just be careful not to overuse them to avoid confusion. 4 | */ 5 | fun foo(a: Int) { 6 | fun local(b: Int) { 7 | return a + b 8 | } 9 | return local(1) 10 | } -------------------------------------------------------------------------------- /codes/LogginWithLiveTemplate.kt: -------------------------------------------------------------------------------- 1 | //Logging methods and parameters with Timber via Live Template 2 | Abbreviation: 3 | timberm 4 | 5 | Context: 6 | Kotlin: statement 7 | 8 | Template text: 9 | timber.log.Timber.d($CONTENT$) 10 | 11 | Variables: 12 | CONTENT 13 | 14 | Expression: 15 | groovyScript("def params = _2.collect {it + ' = [\$' + it + ']'}.join(', ');return '\"' + _1 + '() called' + (params.empty ? '' : ' with: ' + params) + '\"'", kotlinFunctionName(), functionParameters()) 16 | 17 | //timberm 18 | fun foo(bar1: Int, bar2: String) { 19 | Timber.d("foo() called with: bar1 = [$bar1], bar2 = [$bar2]") 20 | } -------------------------------------------------------------------------------- /codes/MapComparison.java: -------------------------------------------------------------------------------- 1 | // ArrayMap vs HashMap 2 | 3 | // ArrayMap provides the identical functionality as a hashMap but avoids all overhead by using two small arrays instead of one large one. 4 | // ArrayMap designed to be more memory efficient than a traditional (java.util.HashMap) for 2 situations 5 | 6 | 1. Situations where you have a small number of items (<1000) 7 | 2. Situations where we have containers of maps. Like maps of maps where the sub maps tend to have a low number of items. 8 | 9 | // ArrayMap 10 | ArrayMap arrayMap = new ArrayMap<>(); 11 | arrayMap.put("Key1", "Value1"); 12 | ... 13 | for (int i = 0; i < arrayMap.size(); i++) { 14 | String key = arrayMap.keyAt(i); 15 | String value = arrayMap.valueAt(i); 16 | } 17 | 18 | // HashMap 19 | HashMap map = new HashMap< String, String>(); 20 | map.put("Key1", "Value1"); 21 | ... 22 | for(Iterator it = map.iterator(); it.hasNext();) { 23 | Object obj = it.next(); 24 | ... 25 | } -------------------------------------------------------------------------------- /codes/Mapper.kt: -------------------------------------------------------------------------------- 1 | interface Mapper { 2 | operator fun invoke(input: T): R 3 | } 4 | 5 | data class UserRaw( 6 | @SerializedName("name") val name: String, 7 | @SerializedName("surname") val surname: String, 8 | @SerializedName("age") val age: Int, 9 | @SerializedName("height") val height: Int 10 | ) 11 | 12 | data class User( 13 | val name: String, 14 | val surname: String, 15 | val age: Int, 16 | val height: Int 17 | ) 18 | 19 | data class UserViewItem( 20 | val name: String, 21 | val surname: String, 22 | val age: String 23 | ) 24 | 25 | class UserDomainMapper : Mapper { 26 | override fun invoke(input: UserRaw) = with(input) { 27 | User(name, surname, age, height) 28 | } 29 | } 30 | 31 | class UserViewItemMapper : Mapper { 32 | override fun invoke(input: User) = with(input) { 33 | UserViewItem(name, surname, age.toString()) 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /codes/MasteringKotlinStandartFunctions.kt: -------------------------------------------------------------------------------- 1 | class MyClass { 2 | fun test() { 3 | val str = "..." 4 | 5 | val result = str.xxx { 6 | print(this) //Receiver 7 | print(it) //Argument 8 | 42 //Block return value 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /codes/MemoryOptimization.java: -------------------------------------------------------------------------------- 1 | // Enum often require more than twice as much memory as static constants. You should avoid using enums on Android. 2 | 3 | // DEX file size 2680 4 | private static final int VALUE1 = 1; 5 | private static final int VALUE2 = 2; 6 | private static final int VALUE3 = 3; 7 | int function(Value value) { 8 | switch(value) { 9 | case VALUE1: 10 | return -1; 11 | case VALUE2: 12 | return -1; 13 | case VALUE3: 14 | return -1; 15 | } 16 | return 0; 17 | } 18 | 19 | 20 | // DEX file size 4188 Bytes --> Bloats your DEX File, eat your heap space. 21 | public static enum Value { 22 | VALUE1, VALUE2, VALUE3 23 | } 24 | int function(Value value) { 25 | switch (value) { 26 | case VALUE1: 27 | return -1; 28 | case VALUE2: 29 | return -1; 30 | case VALUE3: 31 | return -1; 32 | } 33 | return 0; 34 | } 35 | 36 | 37 | // Otherwise you can use @IntDef annotation for built time safety. 38 | @Retention(CLASS) 39 | @IntDef({VALUE1, VALUE2, VALUE3}) 40 | public @interface ExampleMode { 41 | } 42 | public static final int VALUE1 = 0; 43 | public static final int VALUE2 = 1; 44 | public static final int VALUE3 = 2; 45 | ... 46 | 47 | public abstract void setExampleMode(@ExampleMode int mode) 48 | @ExampleMode 49 | public abstract int getExampleMode(); 50 | -------------------------------------------------------------------------------- /codes/MultiDimensionalFlavorConfigFields.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * Providing build config fields on multi-dimensional flavor types 3 | */ 4 | 5 | android { 6 | flavorDimensions Dimensions.default, Dimensions.type 7 | productFlavors { 8 | prod { 9 | dimension Dimensions.default 10 | } 11 | 12 | beta { 13 | dimension Dimensions.default 14 | } 15 | 16 | alpha { 17 | dimension Dimensions.default 18 | } 19 | 20 | dev { 21 | dimension Dimensions.default 22 | } 23 | 24 | free { 25 | dimension Dimensions.type 26 | } 27 | 28 | paid { 29 | dimension Dimensions.type 30 | } 31 | } 32 | 33 | // Use combination of the flavor names 34 | libraryVariants.all { variant -> 35 | if (variant.getName().startsWith("prodPaid")) { 36 | variant.buildConfigField 'String', "key", "value" 37 | } else if (variant.getName().startsWith("betaPaid")) { 38 | variant.buildConfigField 'String', "key", "value" 39 | } else if (variant.getName().startsWith("alphaPaid")) { 40 | variant.buildConfigField 'String', "key", "value" 41 | } else if (variant.getName().startsWith("devPaid")) { 42 | variant.buildConfigField 'String', "key", "value" 43 | } 44 | } 45 | } -------------------------------------------------------------------------------- /codes/NamingImportExample.kt: -------------------------------------------------------------------------------- 1 | /* Sometimes we may face "name conflicts" 2 | * while importing API with same name/qualifier 3 | * Kotlin allows you to rename your imports to fix the conflicts 4 | * and also shorten your API names/qualifiers 5 | * instead of using full name/qualifier :) 6 | */ 7 | import android.os.Process as AndroidProcess 8 | import java.lang.Process as JavaProcess 9 | 10 | // Example usage of android.os.Process API 11 | fun useAndroidProcess() { 12 | val myUid = AndroidProcess.myUid() 13 | println("My current UID: $myUid") 14 | } 15 | 16 | // Example usage of java.lang.Process API 17 | fun useJavaProcess() { 18 | val cmdStr = arrayOf("sh", "-c", "echo Hello i'm sir mordred :)") 19 | val p: JavaProcess = Runtime.getRuntime().exec(cmdStr) 20 | p.waitFor() 21 | } -------------------------------------------------------------------------------- /codes/NetworkCallWithRxJavaAndViewModel.kt: -------------------------------------------------------------------------------- 1 | /* Sample network call with using RxJava, ViewModel and LiveData 2 | First of all prepare your Resource.kt and Status.kt classes*/ 3 | 4 | class Resource constructor(val status: Status, val data: T?, val error: Throwable? = null) { 5 | 6 | companion object { 7 | 8 | fun success(@NonNull data: T): Resource { 9 | return Resource(Status.SUCCESS, data) 10 | } 11 | 12 | fun error(throwable: Throwable): Resource { 13 | return Resource(status = Status.ERROR, data = null, error = throwable) 14 | } 15 | 16 | fun loading(): Resource = Resource(Status.LOADING, null) 17 | } 18 | } 19 | 20 | enum class Status { 21 | SUCCESS, 22 | LOADING, 23 | ERROR 24 | } 25 | 26 | // We'll handle our reponse status with this classes. 27 | 28 | // How to use? 29 | class HomeViewModel(app: Application) : BaseViewModel(app) { 30 | 31 | private val disposable = CompositeDisposable() 32 | val bestPodcastsLiveData = MutableLiveData>() 33 | 34 | fun getBestPodcasts(region: String, explicitContent: Int) { 35 | disposable.add(baseApi.getBestPodcasts(region, explicitContent) 36 | .subscribeOn(Schedulers.io()) 37 | .map { Resource.success(it) } // Map your data to your Resource class 38 | .onErrorReturn { Resource.error(it) } // When an error occured map it to your Resource class 39 | .observeOn(AndroidSchedulers.mainThread()) 40 | .subscribe { 41 | when (it?.status) { 42 | Status.SUCCESS -> bestPodcastsLiveData.postValue(it) 43 | // Post your response to livedata 44 | Status.LOADING -> Log.v("BestPodcasts", "Loading") 45 | // Loading state 46 | Status.ERROR -> Log.v("BestPodcasts", "${it.error?.printStackTrace()}") 47 | // Uh-oh! An error occured. 48 | } 49 | }) 50 | } 51 | 52 | override fun onCleared() { 53 | super.onCleared() 54 | disposable.clear() // Don't need disposable any more. 55 | } 56 | } 57 | 58 | // Now you are able to use your data in UI. 59 | class HomeFragment : BaseFragment(HomeViewModel::class.java) { 60 | 61 | override fun init() { 62 | initBestPodcasts() 63 | } 64 | 65 | private fun initBestPodcasts() { 66 | 67 | viewModel.getBestPodcasts(viewModel.currentLocation, 0) 68 | 69 | viewModel.bestPodcastsLiveData.observe(this@HomeFragment, Observer> { 70 | (mBinding.recyclerViewBestPodcasts.adapter as BestPodcastsAdapter).submitList(it.data?.channels) 71 | }) 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /codes/ObservableDelegation.kt: -------------------------------------------------------------------------------- 1 | /* Kotlin Delegated Properties - Observable 2 | Delegates.observable() takes two arguments: the initial value and a handler 3 | for modifications.The handler gets called every time we assign to the property */ 4 | class User { 5 | var name: String by Delegates.observable("no name") { 6 | prop, old, new -> 7 | println("$old -> $new") 8 | } 9 | } 10 | fun main() { 11 | val user = User() 12 | user.name = "first" 13 | user.name = "second" 14 | } 15 | /* Output: 16 | no name -> first 17 | first -> second */ 18 | /* Users Adapter */ 19 | internal var userList: List by Delegates.observable(emptyList()) { 20 | _, _, _ -> notifyDataSetChanged() 21 | } 22 | /* When your data reached or changed just assign the list. 23 | It will call notifyDataSetChanged() */ 24 | -------------------------------------------------------------------------------- /codes/PackageLevelFunctions.kt: -------------------------------------------------------------------------------- 1 | // Kotlin provides package-level functions succeeding static methods in Java with a more practical way. 2 | 3 | // Just create a .kt file in a convenient package. Then implement like below: 4 | package com.example.app 5 | 6 | fun sum(a: Int, b: Int) { 7 | return a + b 8 | } 9 | 10 | // Finally, call them from any classes 11 | // You need to import the function (IDE will help you): 12 | import com.example.app.sum 13 | 14 | sum(2 + 1) 15 | -------------------------------------------------------------------------------- /codes/RandomExtFuncInKotlin1-3.kt: -------------------------------------------------------------------------------- 1 | /* 2 | random() extension functions for collections, ranges, 3 | and arrays in Kotlin 1.3 4 | */ 5 | 6 | // Pick a random element from a List 7 | val contestants = listOf("Todd", "Anna", "Emma") 8 | println("Winner: ${contestants.random()}") 9 | 10 | // Generate a String or random letters 11 | val randomWordLetters = 'A' .. 'Z' 12 | val randomWord = (0..10).map { randomWordLetters.random() } 13 | .joinToString(separator = "") 14 | println(randomWord) -------------------------------------------------------------------------------- /codes/RangeUsing.kt: -------------------------------------------------------------------------------- 1 | // iterating in the range 1 to 100 2 | for(i in 1..100) {..} 3 | 4 | //iterating backwards, in the range 100 to 1 5 | for(i in 100 downTo 1) {..} 6 | 7 | //iterating over an array, getting every other element 8 | val array = arrayOf("a", "b", "x") 9 | for(i in 1 until array.size step 2) {..} 10 | 11 | //iterating over an array with the item index and destructuring 12 | for((index, element) in array.withIndex()) {..} 13 | 14 | //iterating over a map 15 | val map = mapOf(1 to "one", 2 to "two") 16 | for ((key, value) in map) {..} 17 | -------------------------------------------------------------------------------- /codes/ReifiedTypeParameters.kt: -------------------------------------------------------------------------------- 1 | /* 2 | 'reified' type is used to know the type without 3 | passing the class as a parameter in a function. 4 | */ 5 | 6 | inline fun Context.open() 7 | = startActivity(Intent(this, T::class.java)) 8 | 9 | // usage 10 | open() -------------------------------------------------------------------------------- /codes/RepeatFunction.kt: -------------------------------------------------------------------------------- 1 | /*inline fun repeat(times: Int, action: (Int) -> Unit) 2 | Executes the given function action specified number of times. 3 | A zero-based index of current iteration is passed as a parameter to action. 4 | */ 5 | 6 | // Say awesome ten times 7 | repeat(10) { 8 | println("Kotlin is Awesome!") 9 | } 10 | 11 | repeat(0) { 12 | error(""" ¯\_(ツ)_/¯ """) 13 | } -------------------------------------------------------------------------------- /codes/RoomTypeConverter.kt: -------------------------------------------------------------------------------- 1 | // Reading-Writing lists from/to RoomDB with Moshi 2 | 3 | object DataConverter { 4 | 5 | @TypeConverter 6 | @JvmStatic 7 | fun stringToList(data: String?): List? { 8 | if (data == null) { 9 | return emptyList() 10 | } 11 | 12 | val moshi = Moshi.Builder().build() 13 | val type = Types.newParameterizedType(List::class.java, ListItem::class.java) 14 | val adapter = moshi.adapter>(type) 15 | return adapter.fromJson(data) 16 | } 17 | 18 | @TypeConverter 19 | @JvmStatic 20 | fun listToString(objects: List): String { 21 | val moshi = Moshi.Builder().build() 22 | val type = Types.newParameterizedType(List::class.java, ListItem::class.java) 23 | val adapter = moshi.adapter>(type) 24 | return adapter.toJson(objects) 25 | } 26 | } 27 | 28 | // -- Don't forget to add your TypeConverter to Database. -- 29 | 30 | @Database( 31 | entities = [ 32 | ForecastEntity::class, 33 | CurrentWeatherEntity::class, 34 | CitiesForSearchEntity::class 35 | ], 36 | version = 2 37 | ) 38 | @TypeConverters(DataConverter::class) 39 | abstract class WeatherDatabase : RoomDatabase() { 40 | 41 | abstract fun forecastDao(): ForecastDao 42 | 43 | abstract fun currentWeatherDao(): CurrentWeatherDao 44 | 45 | abstract fun citiesForSearchDao(): CitiesForSearchDao 46 | } 47 | -------------------------------------------------------------------------------- /codes/RxJavaFirebaseStorageSample.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Get images from firebase only whose names are known 3 | */ 4 | 5 | class ProductDetailFragment : BaseFragment(ProductDetailViewModel::class.java) { 6 | /* 7 | * some stuff 8 | */ 9 | val images: List? = productEntity.getImageList() 10 | // images = ["sample1.png","sample2.png"] 11 | 12 | disposable.add( 13 | viewModel.getFullImagePaths(it).subscribe { slides -> 14 | // slides = arraylist of full image paths from Firebase Storage. 15 | // Sample1.png : https://firebasestorage.googleapis.com/v0/b/yourapp-android.appspot.com/o/sample1.png? 16 | // alt=media&token=3ba40117-19ec-4be1-8621-ca23da8f46bc 17 | }) 18 | } 19 | 20 | class ProductDetailViewModel(app: Application) : BaseViewModel(app) { 21 | 22 | val storage = FirebaseStorage.getInstance() 23 | val storageRef = storage.reference 24 | 25 | init { 26 | (app as App).component.inject(this) 27 | } 28 | 29 | private fun getFullImagePathFromFirebase(imageName: String): Single { 30 | return Single.create { single -> 31 | storageRef.child(imageName).downloadUrl 32 | .addOnSuccessListener { 33 | single.onSuccess(it.toString()) 34 | }.addOnFailureListener { 35 | single.onSuccess("") 36 | Log.d("FirebaseImages", "Child name not found.") 37 | } 38 | } 39 | } 40 | 41 | fun getFullImagePaths(imageList: List): Observable> { 42 | return Observable 43 | .fromIterable(imageList) 44 | .flatMap { getFullImagePathFromFirebase(it).toObservable() } 45 | .toList() 46 | .toObservable() 47 | } 48 | } -------------------------------------------------------------------------------- /codes/SafeConstantNullCheck.java: -------------------------------------------------------------------------------- 1 | private static final String CONSTANT_STRING = "constant_string"; 2 | 3 | // NPE PRONE 4 | if(responseTitle.equals(CONSTANT_STRING)){ 5 | 6 | } 7 | 8 | // RIGHT WAY 9 | if (CONSTANT_STRING.equals(responseTitle)){ 10 | 11 | } -------------------------------------------------------------------------------- /codes/SealedClass.kt: -------------------------------------------------------------------------------- 1 | sealed class Operation { 2 | class Add(val value: Int) : Operation() 3 | class Substract(val value: Int) : Operation() 4 | class Multipy(val value: Int) : Operation() 5 | class Divide(val value: Int) : Operation() 6 | } 7 | 8 | fun execute(x: Int, operation: Operation) = when (operation) { 9 | is Operation.Add -> x + operation.value 10 | is Operation.Substract -> x - operation.value 11 | is Operation.Multipy -> x * operation.value 12 | is Operation.Divide -> x / operation.value 13 | } -------------------------------------------------------------------------------- /codes/Sequence.kt: -------------------------------------------------------------------------------- 1 | fun main() { 2 | 3 | } 4 | 5 | val data = mutableListOf() 6 | 7 | fun initData() { 8 | data.clear() 9 | System.gc() 10 | for (i in 0..1_000_000) { 11 | data.add(i) 12 | } 13 | } 14 | 15 | // When you process a bigger collection with more than one processing step, 16 | // it will take more time. 17 | fun processCollectionWithoutSequence() { 18 | data.filter { it % 2 == 0 }.forEach { 19 | 20 | } 21 | } 22 | 23 | // Use Sequence for bigger collections with more than one processing. 24 | 25 | // Sequence are more efficient and faster for collection processing 26 | // with more than single processing step. 27 | fun processCollectionWithSequence() { 28 | data.asSequence().filter { it % 2 == 0 }.forEach { 29 | 30 | } 31 | } -------------------------------------------------------------------------------- /codes/SmartCast.kt: -------------------------------------------------------------------------------- 1 | fun foo(x: Any) { 2 | if (x is String) { 3 | print(x.length) // x is automatically cast to String 4 | } 5 | } 6 | 7 | // Such smart casts work for if statement or when-expressions as well: 8 | if (x is String && x.length > 0) { 9 | print(x.length) // x is automatically cast to String 10 | } 11 | 12 | when (x) { 13 | is Int -> print(x+1) 14 | is String -> print(x.length+1) 15 | is IntArray -> print(x.sum()) 16 | } -------------------------------------------------------------------------------- /codes/StopGradleProcesses.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./gradlew --stop 3 | -------------------------------------------------------------------------------- /codes/StringTemplates.kt: -------------------------------------------------------------------------------- 1 | val name: String = "Android Daily Tips" 2 | 3 | println("Lenght of name is ${name.lenght}") -------------------------------------------------------------------------------- /codes/TailrecUsage.kt: -------------------------------------------------------------------------------- 1 | /* 2 | By using tailrec we let the compiler know that it can replace 3 | the method call with a for loop or goto statement. 4 | 5 | You can only use it if the last call in a function is only calling 6 | itself and only itself. 7 | */ 8 | tailrec fun findFixPoint(x: Double = 1.0): Double 9 | = if (x == Math.cos(x)) x else findFixPoint(Math.cos(x)) -------------------------------------------------------------------------------- /codes/Transient.kt: -------------------------------------------------------------------------------- 1 | /** 2 | * Marks the JVM backing field of the annotated property as transient, 3 | * meaning that it is not part of the default serialized form of the object. 4 | * 5 | * When to use? 6 | * For example it can be used for request classes. 7 | * Transient values will be ignored on your POST request. 8 | */ 9 | 10 | @Parcelize 11 | @JsonClass(generateAdapter = true) 12 | data class FilterRequest( 13 | @Json(name = "color") 14 | var color: String? = null, 15 | @Json(name = "sort") 16 | var sort: String? = null, 17 | @Json(name = "currency") 18 | val currency: String? = null, 19 | @Json(name = "lang") 20 | val lang: String? = null, 21 | @Transient // Ignored when converted to Json value. 22 | var selectedStartDate: LocalDate? = null, 23 | @Transient // Ignored when converted to Json value. 24 | var selectedEndDate: LocalDate? = null 25 | ) : Parcelable -------------------------------------------------------------------------------- /codes/TypeAliases.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Type aliases provide alternative names for existing types. If the type name is too long you can introduce a different shorter name and use the new one instead. 3 | */ 4 | 5 | interface RestaurantPatron { // For example, take a gander at this. 6 | fun makeReservation(restaurant: Organization<(Currency, Coupon?) -> Sustenance>) 7 | fun visit(restaurant: Organization<(Currency, Coupon?) -> Sustenance>) 8 | fun complainAbout(restaurant: Organization<(Currency, Coupon?) -> Sustenance>) 9 | } 10 | 11 | // Create a typealias 12 | typealias Restaurant = Organization<(Currency, Coupon?) -> Sustenance> 13 | 14 | // That's all!! 15 | interface RestaurantPatron { 16 | fun makeReservation(restaurant: Restaurant) 17 | fun visit(restaurant: Restaurant) 18 | fun complainAbout(restaurant: Restaurant) 19 | } -------------------------------------------------------------------------------- /codes/UsingApplySample.kt: -------------------------------------------------------------------------------- 1 | //It can be more concise 2 | val textView = TextView(this) 3 | textview.visibility = View.VISIBLE 4 | textview.text = "test" 5 | 6 | //Efficient approach 7 | val textView = TextView(this).apply { 8 | visibility = View.VISIBLE 9 | text = "test" 10 | } -------------------------------------------------------------------------------- /codes/ViewModelExtension.kt: -------------------------------------------------------------------------------- 1 | 2 | //Extension functions for View Model Providers 3 | inline fun Fragment.viewModel(factory: Factory, body: T.() -> Unit): T { 4 | val vm = ViewModelProviders.of(this, factory)[T::class.java] 5 | vm.body() 6 | return vm 7 | } 8 | 9 | 10 | //Movies Fragment 11 | moviesViewModel = viewModel(viewModelFactory) { 12 | observe(movies, ::getList) 13 | failure(failure, ::handleFailure) 14 | } -------------------------------------------------------------------------------- /codes/WhenInKotlin1-3.kt: -------------------------------------------------------------------------------- 1 | /* 2 | Starting in Kotlin 1.3, we can capture the value being 3 | considered in when into a variable that is only in scope 4 | for the when block! Now we can rewrite our example above 5 | into a single expression! 6 | */ 7 | 8 | when(val answer = theAnswer()){ 9 | 42 -> "You got the right answer!" 10 | else -> "Sorry, $answer is not correct" 11 | } -------------------------------------------------------------------------------- /codes/usingParcelizeInKotlin.kt: -------------------------------------------------------------------------------- 1 | // Using Parcelable in Kotlin 2 | 3 | @Parcelize 4 | data class Student(val id: String, val name: String, val grade: String) : Parcelable 5 | 6 | //For Using @Parcelize annotation add the code below into your gradle. 7 | 8 | androidExtensions { 9 | experimental = true 10 | } 11 | -------------------------------------------------------------------------------- /screenshots/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/.DS_Store -------------------------------------------------------------------------------- /screenshots/1kbDownloadWithDevice.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/1kbDownloadWithDevice.png -------------------------------------------------------------------------------- /screenshots/6MobileSecurityTips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/6MobileSecurityTips.png -------------------------------------------------------------------------------- /screenshots/ActivityRecognition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ActivityRecognition.png -------------------------------------------------------------------------------- /screenshots/AndroidActionMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidActionMode.png -------------------------------------------------------------------------------- /screenshots/AndroidArchitecture.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidArchitecture.jpg -------------------------------------------------------------------------------- /screenshots/AndroidCoroutinesContinuation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidCoroutinesContinuation.png -------------------------------------------------------------------------------- /screenshots/AndroidLocalizedPushNotifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidLocalizedPushNotifications.png -------------------------------------------------------------------------------- /screenshots/AndroidPerformanceTips.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidPerformanceTips.png -------------------------------------------------------------------------------- /screenshots/AndroidQFeatures.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidQFeatures.png -------------------------------------------------------------------------------- /screenshots/AndroidStudioReleaseNewFeatures.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidStudioReleaseNewFeatures.jpg -------------------------------------------------------------------------------- /screenshots/AndroidViewHierarchy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AndroidViewHierarchy.png -------------------------------------------------------------------------------- /screenshots/AnyTryCatch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AnyTryCatch.png -------------------------------------------------------------------------------- /screenshots/ApiCallsAndSuspendFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ApiCallsAndSuspendFunctions.png -------------------------------------------------------------------------------- /screenshots/ApkSignatureSchemeV2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ApkSignatureSchemeV2.png -------------------------------------------------------------------------------- /screenshots/AppActions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AppActions.png -------------------------------------------------------------------------------- /screenshots/AppComponentFactory.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AppComponentFactory.png -------------------------------------------------------------------------------- /screenshots/AppFgBgListener.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AppFgBgListener.png -------------------------------------------------------------------------------- /screenshots/ApplyChanges.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ApplyChanges.jpg -------------------------------------------------------------------------------- /screenshots/ArrayListToString.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ArrayListToString.png -------------------------------------------------------------------------------- /screenshots/ArtVsDalvik.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ArtVsDalvik.jpg -------------------------------------------------------------------------------- /screenshots/AsyncToSync.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AsyncToSync.png -------------------------------------------------------------------------------- /screenshots/Average.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Average.png -------------------------------------------------------------------------------- /screenshots/AvoidMemoryLeaksWithInnerClasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/AvoidMemoryLeaksWithInnerClasses.png -------------------------------------------------------------------------------- /screenshots/BackPressedOnFragments.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/BackPressedOnFragments.jpg -------------------------------------------------------------------------------- /screenshots/BitmapExtension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/BitmapExtension.png -------------------------------------------------------------------------------- /screenshots/BuildscriptVsAllprojects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/BuildscriptVsAllprojects.png -------------------------------------------------------------------------------- /screenshots/CheckNetworkConnection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CheckNetworkConnection.png -------------------------------------------------------------------------------- /screenshots/CheckingLocationServices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CheckingLocationServices.png -------------------------------------------------------------------------------- /screenshots/CheckingPermissions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CheckingPermissions.png -------------------------------------------------------------------------------- /screenshots/CommitVsCommitAllowingStateLoss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CommitVsCommitAllowingStateLoss.png -------------------------------------------------------------------------------- /screenshots/CommonGradleFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CommonGradleFile.png -------------------------------------------------------------------------------- /screenshots/ConstraintLayoutAspectRatio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ConstraintLayoutAspectRatio.png -------------------------------------------------------------------------------- /screenshots/ConstructorInjection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ConstructorInjection.png -------------------------------------------------------------------------------- /screenshots/CoroutineScopeVssupervisorScope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CoroutineScopeVssupervisorScope.png -------------------------------------------------------------------------------- /screenshots/CoroutineViewModel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CoroutineViewModel.png -------------------------------------------------------------------------------- /screenshots/Coroutines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Coroutines.png -------------------------------------------------------------------------------- /screenshots/CoroutinesAsyncManager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CoroutinesAsyncManager.png -------------------------------------------------------------------------------- /screenshots/CoroutinesContinuationUsage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CoroutinesContinuationUsage.png -------------------------------------------------------------------------------- /screenshots/CoroutinesVsRxKotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CoroutinesVsRxKotlin.png -------------------------------------------------------------------------------- /screenshots/CreatingHiddenFiles.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/CreatingHiddenFiles.jpg -------------------------------------------------------------------------------- /screenshots/DaggerAndroidInjector.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DaggerAndroidInjector.png -------------------------------------------------------------------------------- /screenshots/DalvikVsArt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DalvikVsArt.png -------------------------------------------------------------------------------- /screenshots/DataBindingSeekBarColor.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DataBindingSeekBarColor.jpg -------------------------------------------------------------------------------- /screenshots/DbEntityMapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DbEntityMapper.png -------------------------------------------------------------------------------- /screenshots/DeepLinkWithNavigationComponent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DeepLinkWithNavigationComponent.png -------------------------------------------------------------------------------- /screenshots/DefiningMapWithKotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DefiningMapWithKotlin.png -------------------------------------------------------------------------------- /screenshots/DelegatingSettersGetters.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DelegatingSettersGetters.jpg -------------------------------------------------------------------------------- /screenshots/Dexguard.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Dexguard.jpg -------------------------------------------------------------------------------- /screenshots/DiImplCosts.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DiImplCosts.jpg -------------------------------------------------------------------------------- /screenshots/DowloadingFileOkhttpOkio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DowloadingFileOkhttpOkio.png -------------------------------------------------------------------------------- /screenshots/DrawableVsMipMapFolders.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/DrawableVsMipMapFolders.jpg -------------------------------------------------------------------------------- /screenshots/EditTextListenerImpl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/EditTextListenerImpl.png -------------------------------------------------------------------------------- /screenshots/EditTextManualFocusForward.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/EditTextManualFocusForward.jpg -------------------------------------------------------------------------------- /screenshots/EfficientSplashScreen.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/EfficientSplashScreen.png -------------------------------------------------------------------------------- /screenshots/EfficientStringConcat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/EfficientStringConcat.png -------------------------------------------------------------------------------- /screenshots/ElvisOperator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ElvisOperator.png -------------------------------------------------------------------------------- /screenshots/EncryptedSharedPreferences.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/EncryptedSharedPreferences.png -------------------------------------------------------------------------------- /screenshots/ExecuteBodyIfDebugMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ExecuteBodyIfDebugMode.png -------------------------------------------------------------------------------- /screenshots/ExtensionFuncForRxSubscriptions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ExtensionFuncForRxSubscriptions.png -------------------------------------------------------------------------------- /screenshots/FancyWayToSetOnClickListeners.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FancyWayToSetOnClickListeners.png -------------------------------------------------------------------------------- /screenshots/FeatureModule.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FeatureModule.png -------------------------------------------------------------------------------- /screenshots/FilterGooglePlacesAutocomplete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FilterGooglePlacesAutocomplete.png -------------------------------------------------------------------------------- /screenshots/FirstAndPredicate.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FirstAndPredicate.jpg -------------------------------------------------------------------------------- /screenshots/FlattenArray.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FlattenArray.png -------------------------------------------------------------------------------- /screenshots/FlowVsObservable.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FlowVsObservable.jpg -------------------------------------------------------------------------------- /screenshots/FragmentArgumentDelegate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FragmentArgumentDelegate.png -------------------------------------------------------------------------------- /screenshots/FragmentContainerView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FragmentContainerView.png -------------------------------------------------------------------------------- /screenshots/FragmentLiveDataLifeCycleOwner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FragmentLiveDataLifeCycleOwner.png -------------------------------------------------------------------------------- /screenshots/FunctionInterfaces.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/FunctionInterfaces.jpg -------------------------------------------------------------------------------- /screenshots/GitFetch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/GitFetch.png -------------------------------------------------------------------------------- /screenshots/GitPull.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/GitPull.png -------------------------------------------------------------------------------- /screenshots/GradleConfigurationFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/GradleConfigurationFile.png -------------------------------------------------------------------------------- /screenshots/HandlingApiResultWithSealedClass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/HandlingApiResultWithSealedClass.png -------------------------------------------------------------------------------- /screenshots/HandlingGenericApiResponseWithCoroutines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/HandlingGenericApiResponseWithCoroutines.png -------------------------------------------------------------------------------- /screenshots/HashCodeForNullableTypes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/HashCodeForNullableTypes.png -------------------------------------------------------------------------------- /screenshots/HowToGetPrimaryColorOfTheme.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/HowToGetPrimaryColorOfTheme.png -------------------------------------------------------------------------------- /screenshots/HowToResolveAppLaunchingTimeDelay.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/HowToResolveAppLaunchingTimeDelay.png -------------------------------------------------------------------------------- /screenshots/HowToStoreDataLocally.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/HowToStoreDataLocally.png -------------------------------------------------------------------------------- /screenshots/ImplicitNullCheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ImplicitNullCheck.png -------------------------------------------------------------------------------- /screenshots/InfixFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/InfixFunctions.png -------------------------------------------------------------------------------- /screenshots/InteritanceWithDataClasses.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/InteritanceWithDataClasses.jpg -------------------------------------------------------------------------------- /screenshots/JetpackCompose.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/JetpackCompose.png -------------------------------------------------------------------------------- /screenshots/JoinToString.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/JoinToString.png -------------------------------------------------------------------------------- /screenshots/JvmOverloads.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/JvmOverloads.png -------------------------------------------------------------------------------- /screenshots/KaptIncrementalCompilation.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KaptIncrementalCompilation.jpg -------------------------------------------------------------------------------- /screenshots/KeyFeaturesToIncreaseReachAndEngagement.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KeyFeaturesToIncreaseReachAndEngagement.png -------------------------------------------------------------------------------- /screenshots/KeyboardShowHideExt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KeyboardShowHideExt.png -------------------------------------------------------------------------------- /screenshots/KotlinAsClassClash.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinAsClassClash.jpg -------------------------------------------------------------------------------- /screenshots/KotlinDelegateForInitializing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinDelegateForInitializing.png -------------------------------------------------------------------------------- /screenshots/KotlinDelegationBy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinDelegationBy.png -------------------------------------------------------------------------------- /screenshots/KotlinDsl.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinDsl.png -------------------------------------------------------------------------------- /screenshots/KotlinInIs.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinInIs.jpg -------------------------------------------------------------------------------- /screenshots/KotlinReadableAndCleanCode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinReadableAndCleanCode.png -------------------------------------------------------------------------------- /screenshots/KotlinRun.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinRun.jpg -------------------------------------------------------------------------------- /screenshots/KotlinStandartFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinStandartFunctions.png -------------------------------------------------------------------------------- /screenshots/KotlinStyleSupportVersionCheck.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinStyleSupportVersionCheck.jpg -------------------------------------------------------------------------------- /screenshots/KotlinWayToAddOrRemoveView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinWayToAddOrRemoveView.png -------------------------------------------------------------------------------- /screenshots/KotlinWayToCreateSingletons.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinWayToCreateSingletons.png -------------------------------------------------------------------------------- /screenshots/KotlinWhereUsage.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/KotlinWhereUsage.jpg -------------------------------------------------------------------------------- /screenshots/LaunchVsAsync.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LaunchVsAsync.jpg -------------------------------------------------------------------------------- /screenshots/LaunchWhenStarted.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LaunchWhenStarted.png -------------------------------------------------------------------------------- /screenshots/LazyLoading.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LazyLoading.png -------------------------------------------------------------------------------- /screenshots/LetApplyRunAlsoWith.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LetApplyRunAlsoWith.jpg -------------------------------------------------------------------------------- /screenshots/ListImplDiscuss.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ListImplDiscuss.png -------------------------------------------------------------------------------- /screenshots/LiveData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LiveData.png -------------------------------------------------------------------------------- /screenshots/LiveDataGenericErrorHandling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LiveDataGenericErrorHandling.png -------------------------------------------------------------------------------- /screenshots/LiveDataTransformations.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LiveDataTransformations.png -------------------------------------------------------------------------------- /screenshots/LocalFirstWithCoroutines.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LocalFirstWithCoroutines.jpg -------------------------------------------------------------------------------- /screenshots/LocalFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LocalFunctions.png -------------------------------------------------------------------------------- /screenshots/LocalReturn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LocalReturn.png -------------------------------------------------------------------------------- /screenshots/LocusId.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LocusId.jpg -------------------------------------------------------------------------------- /screenshots/LogginWithLiveTemplate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LogginWithLiveTemplate.png -------------------------------------------------------------------------------- /screenshots/Looper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Looper.png -------------------------------------------------------------------------------- /screenshots/LuhnCheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/LuhnCheck.png -------------------------------------------------------------------------------- /screenshots/MapAssociate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MapAssociate.png -------------------------------------------------------------------------------- /screenshots/Mapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Mapper.png -------------------------------------------------------------------------------- /screenshots/MasteringKotlinStandartFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MasteringKotlinStandartFunctions.png -------------------------------------------------------------------------------- /screenshots/MemoryOptimization.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MemoryOptimization.png -------------------------------------------------------------------------------- /screenshots/MoshiOverGson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MoshiOverGson.png -------------------------------------------------------------------------------- /screenshots/MultiDimensionalFlavorConfigFields.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MultiDimensionalFlavorConfigFields.png -------------------------------------------------------------------------------- /screenshots/MviArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MviArchitecture.png -------------------------------------------------------------------------------- /screenshots/MvpArchitecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/MvpArchitecture.png -------------------------------------------------------------------------------- /screenshots/NamingImportExample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/NamingImportExample.png -------------------------------------------------------------------------------- /screenshots/NetworkCallWithRxJavaAndViewModel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/NetworkCallWithRxJavaAndViewModel.png -------------------------------------------------------------------------------- /screenshots/NewlineAtEndOfFile.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/NewlineAtEndOfFile.png -------------------------------------------------------------------------------- /screenshots/NotationForPlatformTypes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/NotationForPlatformTypes.png -------------------------------------------------------------------------------- /screenshots/ObservableDelegation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ObservableDelegation.png -------------------------------------------------------------------------------- /screenshots/ObservingLiveData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ObservingLiveData.png -------------------------------------------------------------------------------- /screenshots/PackageInfo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/PackageInfo.png -------------------------------------------------------------------------------- /screenshots/PackageLevelFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/PackageLevelFunctions.png -------------------------------------------------------------------------------- /screenshots/ParcelableVsSerializable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ParcelableVsSerializable.png -------------------------------------------------------------------------------- /screenshots/PerformanceTips.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/PerformanceTips.jpg -------------------------------------------------------------------------------- /screenshots/Preconditions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Preconditions.png -------------------------------------------------------------------------------- /screenshots/ProguardKeep.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ProguardKeep.png -------------------------------------------------------------------------------- /screenshots/PropertyOverride.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/PropertyOverride.png -------------------------------------------------------------------------------- /screenshots/RandomExtFuncInKotlin1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RandomExtFuncInKotlin1-3.png -------------------------------------------------------------------------------- /screenshots/RangeUsing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RangeUsing.png -------------------------------------------------------------------------------- /screenshots/ReadFromJson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ReadFromJson.png -------------------------------------------------------------------------------- /screenshots/RecyclerViewLayoutManagerWithXml.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RecyclerViewLayoutManagerWithXml.jpg -------------------------------------------------------------------------------- /screenshots/RecyclerviewSetup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RecyclerviewSetup.png -------------------------------------------------------------------------------- /screenshots/ReifiedTypeFindFragment.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ReifiedTypeFindFragment.jpg -------------------------------------------------------------------------------- /screenshots/ReifiedTypeParameters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ReifiedTypeParameters.png -------------------------------------------------------------------------------- /screenshots/RelationBetweenLivedataAndSubClasses.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RelationBetweenLivedataAndSubClasses.png -------------------------------------------------------------------------------- /screenshots/RepeatFunction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RepeatFunction.png -------------------------------------------------------------------------------- /screenshots/RoomTypeConverter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RoomTypeConverter.png -------------------------------------------------------------------------------- /screenshots/RoomWithDagger.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RoomWithDagger.png -------------------------------------------------------------------------------- /screenshots/RxDebounceWithKotlinCoroutines.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RxDebounceWithKotlinCoroutines.jpg -------------------------------------------------------------------------------- /screenshots/RxJavaConcatUsage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RxJavaConcatUsage.png -------------------------------------------------------------------------------- /screenshots/RxJavaFirebaseStorageSample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/RxJavaFirebaseStorageSample.png -------------------------------------------------------------------------------- /screenshots/SafeConstantNullCheck.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SafeConstantNullCheck.png -------------------------------------------------------------------------------- /screenshots/SealedClass.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SealedClass.png -------------------------------------------------------------------------------- /screenshots/Sequence.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Sequence.png -------------------------------------------------------------------------------- /screenshots/SetTargetFragment.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SetTargetFragment.png -------------------------------------------------------------------------------- /screenshots/SingleLiveData.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SingleLiveData.png -------------------------------------------------------------------------------- /screenshots/SingleRecyclerViewAdapter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SingleRecyclerViewAdapter.png -------------------------------------------------------------------------------- /screenshots/SmartCasts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SmartCasts.png -------------------------------------------------------------------------------- /screenshots/SomeJavaIssuesAddressedInKotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/SomeJavaIssuesAddressedInKotlin.png -------------------------------------------------------------------------------- /screenshots/StethoTip.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/StethoTip.jpg -------------------------------------------------------------------------------- /screenshots/StopGradleProcesses.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/StopGradleProcesses.jpg -------------------------------------------------------------------------------- /screenshots/StringTemplates.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/StringTemplates.png -------------------------------------------------------------------------------- /screenshots/TailrecUsage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/TailrecUsage.png -------------------------------------------------------------------------------- /screenshots/TakeIf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/TakeIf.png -------------------------------------------------------------------------------- /screenshots/TestingWithMockito.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/TestingWithMockito.png -------------------------------------------------------------------------------- /screenshots/ToolsToImproveRendering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ToolsToImproveRendering.png -------------------------------------------------------------------------------- /screenshots/Transient.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Transient.png -------------------------------------------------------------------------------- /screenshots/TypeAliases.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/TypeAliases.png -------------------------------------------------------------------------------- /screenshots/Typealias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/Typealias.png -------------------------------------------------------------------------------- /screenshots/UsefulViewPagerExtensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/UsefulViewPagerExtensions.png -------------------------------------------------------------------------------- /screenshots/UsingApplySample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/UsingApplySample.png -------------------------------------------------------------------------------- /screenshots/UtilityFunctions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/UtilityFunctions.png -------------------------------------------------------------------------------- /screenshots/VcsShortcutsForMDD.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/VcsShortcutsForMDD.png -------------------------------------------------------------------------------- /screenshots/ViewLifeCycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ViewLifeCycle.png -------------------------------------------------------------------------------- /screenshots/ViewModelExtSafeLaunch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ViewModelExtSafeLaunch.png -------------------------------------------------------------------------------- /screenshots/ViewModelExtension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ViewModelExtension.png -------------------------------------------------------------------------------- /screenshots/ViewVisiblityExt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/ViewVisiblityExt.png -------------------------------------------------------------------------------- /screenshots/WhatsNewInAndroidPie.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/WhatsNewInAndroidPie.jpg -------------------------------------------------------------------------------- /screenshots/WhenExhaustive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/WhenExhaustive.png -------------------------------------------------------------------------------- /screenshots/WhenInKotlin1-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/WhenInKotlin1-3.png -------------------------------------------------------------------------------- /screenshots/WhenWithMixedObjects.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/WhenWithMixedObjects.jpg -------------------------------------------------------------------------------- /screenshots/WhyUseModularization.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/WhyUseModularization.jpg -------------------------------------------------------------------------------- /screenshots/backgroundwork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/backgroundwork.png -------------------------------------------------------------------------------- /screenshots/easyspannableonkotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/easyspannableonkotlin.png -------------------------------------------------------------------------------- /screenshots/layoutparams.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/layoutparams.png -------------------------------------------------------------------------------- /screenshots/mapComprasion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/mapComprasion.png -------------------------------------------------------------------------------- /screenshots/usingParcelizeInKotlin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/usingParcelizeInKotlin.png -------------------------------------------------------------------------------- /screenshots/zipWithNextAndWindowed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MobileTipsters/android-daily-tips/ed7756ed394598a546fba4dd3b9dd16a79442f54/screenshots/zipWithNextAndWindowed.png --------------------------------------------------------------------------------