├── .gitignore ├── .idea ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── encodings.xml ├── gradle.xml ├── markdown-navigator.xml ├── markdown-navigator │ └── profiles_settings.xml ├── misc.xml ├── runConfigurations.xml └── vcs.xml ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── hankkin │ │ └── jetpack_note │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ └── component.json │ ├── java │ │ └── com │ │ │ └── hankkin │ │ │ └── jetpack_note │ │ │ ├── JetApplication.kt │ │ │ ├── ViewModelFactory.kt │ │ │ ├── data │ │ │ ├── Converters.kt │ │ │ ├── Executors.kt │ │ │ ├── Listing.kt │ │ │ ├── NetworkState.kt │ │ │ ├── bean │ │ │ │ ├── Component.kt │ │ │ │ ├── Gank.kt │ │ │ │ └── User.kt │ │ │ ├── db │ │ │ │ ├── HomeDB.kt │ │ │ │ ├── HomeDao.kt │ │ │ │ ├── UserDB.kt │ │ │ │ └── UserDao.kt │ │ │ ├── net │ │ │ │ ├── Api.kt │ │ │ │ └── HttpClient.kt │ │ │ └── respository │ │ │ │ ├── HomeRepository.kt │ │ │ │ ├── PagingRespository.kt │ │ │ │ └── gank │ │ │ │ ├── GankDataSource.kt │ │ │ │ ├── GankRespository.kt │ │ │ │ └── GankSourceFactory.kt │ │ │ ├── ext │ │ │ ├── ActivityExt.kt │ │ │ └── FragmentExt.kt │ │ │ ├── ui │ │ │ ├── AboutFragment.kt │ │ │ ├── CodeFragment.kt │ │ │ ├── MainActivity.kt │ │ │ ├── MoreSampleFragment.kt │ │ │ ├── SettingFragment.kt │ │ │ ├── adapter │ │ │ │ ├── HomeListAdapter.kt │ │ │ │ ├── PagingDemoAdapter.kt │ │ │ │ └── PagingWithNetWorkAdapter.kt │ │ │ ├── home │ │ │ │ ├── HomeFragment.kt │ │ │ │ └── HomeListViewModel.kt │ │ │ ├── lifecycles │ │ │ │ ├── BoundLocationManager.java │ │ │ │ └── LifecyclesFragment.kt │ │ │ ├── livedata │ │ │ │ ├── LiveDataFragment.kt │ │ │ │ └── LiveDataViewModel.kt │ │ │ ├── navigation │ │ │ │ ├── NavigationFragment.kt │ │ │ │ ├── activity │ │ │ │ │ ├── BottomNavSampleActivity.kt │ │ │ │ │ └── NavSampleActivity.kt │ │ │ │ └── fg │ │ │ │ │ ├── SampleArgsFragment.kt │ │ │ │ │ ├── SampleDashboardFragment.kt │ │ │ │ │ ├── SampleHomeFragment.kt │ │ │ │ │ └── SampleNotificationFragment.kt │ │ │ ├── other │ │ │ │ ├── CommonWebActivity.kt │ │ │ │ └── WebFragment.kt │ │ │ ├── paging │ │ │ │ ├── PagingDemoFragment.kt │ │ │ │ ├── PagingWithDaoActivity.kt │ │ │ │ ├── PagingWithDaoViewModel.kt │ │ │ │ ├── PagingWithNetWorkActivity.kt │ │ │ │ └── PagingWithNetWorkViewModel.kt │ │ │ └── viewmodel │ │ │ │ ├── DataShareFragment.kt │ │ │ │ ├── DemoViewModel.kt │ │ │ │ ├── ViewModelFragment.kt │ │ │ │ └── ViewModelShareActivity.kt │ │ │ ├── utils │ │ │ ├── AppUtils.kt │ │ │ ├── CommonUtils.kt │ │ │ ├── Constants.kt │ │ │ ├── FloatWindowUtils.kt │ │ │ ├── Injection.kt │ │ │ ├── StatusBarUtil.java │ │ │ └── ViewHelper.kt │ │ │ ├── widget │ │ │ ├── CoolIndicator.java │ │ │ ├── CoolIndicatorLayout.java │ │ │ ├── DrawableWrapper.java │ │ │ ├── ShiftDrawable.java │ │ │ └── TabLayoutMediator.java │ │ │ └── workers │ │ │ └── SeedDatabaseWorker.kt │ └── res │ │ ├── anim │ │ ├── slide_in_left.xml │ │ ├── slide_in_right.xml │ │ ├── slide_out_left.xml │ │ └── slide_out_right.xml │ │ ├── color │ │ ├── nav_item_icon.xml │ │ └── nav_item_txt.xml │ │ ├── drawable-v21 │ │ ├── ic_menu_camera.xml │ │ ├── ic_menu_gallery.xml │ │ ├── ic_menu_manage.xml │ │ ├── ic_menu_send.xml │ │ ├── ic_menu_share.xml │ │ └── ic_menu_slideshow.xml │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── bottom_sheet_bg.xml │ │ ├── btn_shadow.xml │ │ ├── btn_theme.xml │ │ ├── default_drawable_indicator.xml │ │ ├── ic_baseline_add.xml │ │ ├── ic_baseline_remove.xml │ │ ├── ic_dashboard_black_24dp.xml │ │ ├── ic_home_black_24dp.xml │ │ ├── ic_launcher_background.xml │ │ ├── ic_notifications_black_24dp.xml │ │ ├── laptop.jpeg │ │ ├── rectangle.xml │ │ ├── seekbar.xml │ │ └── side_nav_bar.xml │ │ ├── layout │ │ ├── activity_article_detail.xml │ │ ├── activity_bottom_nav_sample.xml │ │ ├── activity_main.xml │ │ ├── activity_more_sample.xml │ │ ├── activity_nav_sample.xml │ │ ├── activity_paging_with_dao.xml │ │ ├── activity_paging_with_net_work.xml │ │ ├── activity_view_model_share.xml │ │ ├── adapter_paging_item.xml │ │ ├── adapter_paging_with_network_item.xml │ │ ├── app_bar_nav_sample.xml │ │ ├── content_main.xml │ │ ├── content_nav_sample.xml │ │ ├── fragment_about.xml │ │ ├── fragment_code.xml │ │ ├── fragment_data_share.xml │ │ ├── fragment_home.xml │ │ ├── fragment_lifecycles.xml │ │ ├── fragment_live_data.xml │ │ ├── fragment_more_sample.xml │ │ ├── fragment_navigation.xml │ │ ├── fragment_sample_args.xml │ │ ├── fragment_sample_dashboard.xml │ │ ├── fragment_sample_home.xml │ │ ├── fragment_sample_notification.xml │ │ ├── fragment_setting.xml │ │ ├── fragment_view_model.xml │ │ ├── fragment_web.xml │ │ ├── layout_about_dialog.xml │ │ ├── layout_float_view.xml │ │ ├── layout_loading.xml │ │ ├── layout_rv_home_header.xml │ │ ├── layout_toolbar.xml │ │ ├── list_item_home.xml │ │ ├── nav_header_main.xml │ │ ├── nav_header_nav_sample.xml │ │ └── paging_demo_fragment.xml │ │ ├── menu │ │ ├── activity_main_drawer.xml │ │ ├── activity_nav_sample_drawer.xml │ │ ├── article_detail_menu.xml │ │ ├── bottom_nav_menu.xml │ │ ├── main.xml │ │ ├── nav_sample.xml │ │ └── web_menu.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ ├── about_csdn.png │ │ ├── about_github.png │ │ ├── about_jianshu.png │ │ ├── about_juejin.png │ │ ├── back.png │ │ ├── bg_args.webp │ │ ├── bg_jump.webp │ │ ├── bg_lifecycles.webp │ │ ├── bg_livedata.webp │ │ ├── bg_navigation.webp │ │ ├── bg_notification.webp │ │ ├── bg_paging.webp │ │ ├── bg_sample_drawerlayout.webp │ │ ├── bg_work.webp │ │ ├── close.png │ │ ├── ic_launcher.png │ │ ├── icon_grid.png │ │ ├── icon_lin.png │ │ ├── jetpack.png │ │ ├── jetpack_donut.webp │ │ ├── menu_about.png │ │ ├── menu_circle.png │ │ ├── menu_home.png │ │ ├── menu_know.png │ │ ├── menu_more.png │ │ ├── menu_nav.png │ │ └── menu_set.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── navigation │ │ ├── navigation_bottom_sample.xml │ │ └── navigation_main.xml │ │ ├── values-v21 │ │ └── styles.xml │ │ ├── values │ │ ├── anim.xml │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── strings.xml │ │ ├── styles.xml │ │ └── textsize.xml │ │ └── xml │ │ └── provider_paths.xml │ └── test │ └── java │ └── com │ └── hankkin │ └── jetpack_note │ └── ExampleUnitTest.kt ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/caches 5 | /.idea/libraries 6 | /.idea/modules.xml 7 | /.idea/workspace.xml 8 | /.idea/navEditor.xml 9 | /.idea/assetWizardSettings.xml 10 | .DS_Store 11 | /build 12 | /captures 13 | .externalNativeBuild 14 | -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/markdown-navigator/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/hankkin/jetpack_note/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note 2 | 3 | import androidx.test.InstrumentationRegistry 4 | import androidx.test.runner.AndroidJUnit4 5 | 6 | import org.junit.Test 7 | import org.junit.runner.RunWith 8 | 9 | import org.junit.Assert.* 10 | 11 | /** 12 | * Instrumented test, which will execute on an Android device. 13 | * 14 | * See [testing documentation](http://d.android.com/tools/testing). 15 | */ 16 | @RunWith(AndroidJUnit4::class) 17 | class ExampleInstrumentedTest { 18 | @Test 19 | fun useAppContext() { 20 | // Context of the app under test. 21 | val appContext = InstrumentationRegistry.getTargetContext() 22 | assertEquals("com.hankkin.aac_note", appContext.packageName) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 39 | 40 | 44 | 45 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 61 | 62 | 67 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/assets/component.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "id": "1", 4 | "title": "Navigation", 5 | "description": "处理应用内导航所需的一切", 6 | "link": "https://juejin.im/post/5d1202fc6fb9a07ef90ca7a1" 7 | }, 8 | { 9 | "id": "2", 10 | "title": "Navigation—More", 11 | "description": "为什么切换Fragment会重绘?", 12 | "link": "https://juejin.im/post/5d12cfea6fb9a07ed4411040" 13 | }, 14 | { 15 | "id": "3", 16 | "title": "Lifecycles", 17 | "description": "管理您的 Activity 和 Fragment 生命周期", 18 | "link": "https://juejin.im/post/5d15bbb86fb9a07f03574e56" 19 | }, 20 | { 21 | "id": "4", 22 | "title": "LiveData", 23 | "description": "在底层数据库更改时通知视图", 24 | "link": "https://juejin.im/post/5d247b036fb9a07eee5ef3df" 25 | }, 26 | { 27 | "id": "5", 28 | "title": "ViewModel", 29 | "description": "以注重生命周期的方式管理界面相关的数据", 30 | "link": "https://juejin.im/post/5d2d4172e51d4510835e0346" 31 | }, 32 | { 33 | "id": "6", 34 | "title": "Paging", 35 | "description": "逐步从您的数据源按需加载信息", 36 | "link": "https://juejin.im/post/5d63f620f265da03970bc76d" 37 | }, 38 | { 39 | "id": "7", 40 | "title": "Room", 41 | "description": "流畅地访问 SQLite 数据库", 42 | "link": "" 43 | }, 44 | { 45 | "id": "8", 46 | "title": "WorkManager", 47 | "description": "管理您的 Android 后台作业", 48 | "link": "" 49 | } 50 | ] -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/JetApplication.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note 2 | 3 | import android.app.Application 4 | import com.tencent.bugly.Bugly 5 | 6 | /** 7 | * created by ${Hankkin} 8 | * on 2019-06-12 9 | */ 10 | 11 | class JetApplication : Application() { 12 | 13 | override fun onCreate() { 14 | super.onCreate() 15 | Bugly.init(applicationContext, "4d0b425df7", false) 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ViewModelFactory.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note 2 | 3 | import android.app.Application 4 | import androidx.lifecycle.ViewModel 5 | import androidx.lifecycle.ViewModelProvider 6 | import com.hankkin.jetpack_note.data.respository.HomeRepository 7 | import com.hankkin.jetpack_note.data.respository.PagingRespository 8 | import com.hankkin.jetpack_note.data.respository.gank.GankRespository 9 | import com.hankkin.jetpack_note.ui.home.HomeListViewModel 10 | import com.hankkin.jetpack_note.ui.livedata.LiveDataViewModel 11 | import com.hankkin.jetpack_note.ui.paging.PagingWithDaoViewModel 12 | import com.hankkin.jetpack_note.ui.paging.PagingWithNetWorkViewModel 13 | import com.hankkin.jetpack_note.utils.Injection 14 | 15 | /** 16 | * @author Hankkin 17 | * @date 2019-05-30 18 | */ 19 | class ViewModelFactory( 20 | private val homeRepository: HomeRepository, 21 | private val pagingRepository: PagingRespository, 22 | private val gankRespository: GankRespository 23 | ) : ViewModelProvider.NewInstanceFactory() { 24 | 25 | @Suppress("UNCHECKED_CAST") 26 | override fun create(modelClass: Class): T = 27 | with(modelClass) { 28 | when { 29 | isAssignableFrom(HomeListViewModel::class.java) -> { 30 | HomeListViewModel(homeRepository) 31 | } 32 | isAssignableFrom((LiveDataViewModel::class.java)) -> { 33 | LiveDataViewModel() 34 | } 35 | isAssignableFrom(PagingWithDaoViewModel::class.java) -> { 36 | PagingWithDaoViewModel(pagingRepository) 37 | } 38 | isAssignableFrom(PagingWithNetWorkViewModel::class.java) -> { 39 | PagingWithNetWorkViewModel(gankRespository) 40 | } 41 | else -> 42 | throw IllegalArgumentException("Unknown ViewModel: ${modelClass.name}") 43 | } 44 | 45 | } as T 46 | 47 | 48 | companion object { 49 | private var INSTANCE: ViewModelFactory? = null 50 | fun getInstance(application: Application) = 51 | INSTANCE ?: synchronized(ViewModelFactory::class.java) { 52 | INSTANCE ?: ViewModelFactory( 53 | Injection.provideHomeRepository(application), 54 | Injection.providePagingRepository(application), 55 | Injection.provideGankRespository() 56 | ) 57 | } 58 | } 59 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/Converters.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.data 18 | 19 | import androidx.room.TypeConverter 20 | import java.util.Calendar 21 | 22 | /** 23 | * Type converters to allow Room to reference complex data types. 24 | */ 25 | class Converters { 26 | @TypeConverter fun calendarToDatestamp(calendar: Calendar): Long = calendar.timeInMillis 27 | 28 | @TypeConverter fun datestampToCalendar(value: Long): Calendar = 29 | Calendar.getInstance().apply { timeInMillis = value } 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/Executors.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.data 18 | 19 | import java.util.concurrent.Executors 20 | 21 | private val IO_EXECUTOR = Executors.newSingleThreadExecutor() 22 | 23 | /** 24 | * Utility method to run blocks on a dedicated background thread, used for io/database work. 25 | */ 26 | fun ioThread(f : () -> Unit) { 27 | IO_EXECUTOR.execute(f) 28 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/Listing.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.data 18 | 19 | import androidx.lifecycle.LiveData 20 | import androidx.paging.PagedList 21 | 22 | /** 23 | * Data class that is necessary for a UI to show a listing and interact w/ the rest of the system 24 | * 封装需要监听的对象和执行的操作,用于上拉下拉操作 25 | * pagedList : 数据列表 26 | * networkState : 网络状态 27 | * refreshState : 刷新状态 28 | * refresh : 刷新操作 29 | * retry : 重试操作 30 | */ 31 | data class Listing( 32 | // the LiveData of paged lists for the UI to observe 33 | val pagedList: LiveData>, 34 | // represents the network request status to show to the user 35 | val networkState: LiveData, 36 | // represents the refresh status to show to the user. Separate from networkState, this 37 | // value is importantly only when refresh is requested. 38 | val refreshState: LiveData, 39 | // refreshes the whole data and fetches it from scratch. 40 | val refresh: () -> Unit, 41 | // retries any failed requests. 42 | val retry: () -> Unit) -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/NetworkState.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017 The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.data 18 | 19 | enum class Status { 20 | RUNNING, 21 | SUCCESS, 22 | FAILED, 23 | HIDDEN 24 | } 25 | 26 | @Suppress("DataClassPrivateConstructor") 27 | data class NetworkState private constructor( 28 | val status: Status 29 | ) { 30 | companion object { 31 | val LOADED = NetworkState(Status.SUCCESS) 32 | val LOADING = NetworkState(Status.RUNNING) 33 | val HIDDEN = NetworkState(Status.HIDDEN) 34 | val FAILED = NetworkState(Status.FAILED) 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/bean/Component.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.bean 2 | 3 | import androidx.room.ColumnInfo 4 | import androidx.room.Entity 5 | import androidx.room.PrimaryKey 6 | import java.io.Serializable 7 | 8 | /** 9 | * @author Hankkin 10 | * @date 2019-05-30 11 | */ 12 | @Entity(tableName = "component") 13 | data class Component( 14 | @PrimaryKey @ColumnInfo(name = "id") val id: String, 15 | val title: String, 16 | val description: String, 17 | val link: String 18 | ) : Serializable { 19 | override fun toString() = title 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/bean/Gank.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.bean 2 | 3 | import java.io.Serializable 4 | 5 | 6 | data class GankResponse(val error: Boolean, val results: List) 7 | 8 | data class Gank( 9 | val _id: String = "", 10 | val createdAt: String = "", 11 | val desc: String = "", 12 | val images: MutableList = mutableListOf(), 13 | val source: String = "", 14 | val type: String = "", 15 | val publishedAt: String = "", 16 | val url: String = "", 17 | val used: Boolean = false, 18 | val who: String = "" 19 | ) : Serializable { 20 | val published: String 21 | get() = publishedAt.substring(0, 10) 22 | } 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/bean/User.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.bean 2 | 3 | import androidx.room.Entity 4 | import androidx.room.PrimaryKey 5 | 6 | /** 7 | * created by ${Hankkin} 8 | * on 2019-07-08 9 | */ 10 | @Entity 11 | data class User(@PrimaryKey(autoGenerate = true) val id: Int, val name: String) -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/db/HomeDB.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.data.db 18 | 19 | import android.content.Context 20 | import androidx.room.Database 21 | import androidx.room.Room 22 | import androidx.room.RoomDatabase 23 | import androidx.room.TypeConverters 24 | import androidx.sqlite.db.SupportSQLiteDatabase 25 | import androidx.work.OneTimeWorkRequestBuilder 26 | import androidx.work.WorkManager 27 | import com.hankkin.jetpack_note.data.Converters 28 | import com.hankkin.jetpack_note.data.bean.Component 29 | import com.hankkin.jetpack_note.utils.Constants.DATABASE_NAME 30 | import com.hankkin.jetpack_note.workers.SeedDatabaseWorker 31 | 32 | /** 33 | * The Room database for this app 34 | */ 35 | @Database(entities = [Component::class], version = 1, exportSchema = false) 36 | @TypeConverters(Converters::class) 37 | abstract class HomeDB : RoomDatabase() { 38 | 39 | abstract fun homeDao(): HomeDao 40 | 41 | companion object { 42 | 43 | // For Singleton instantiation 44 | @Volatile private var instance: HomeDB? = null 45 | 46 | fun getInstance(context: Context): HomeDB { 47 | return instance ?: synchronized(this) { 48 | instance 49 | ?: buildDatabase(context).also { instance = it } 50 | } 51 | } 52 | 53 | // Create and pre-populate the database. See this article for more details: 54 | // https://medium.com/google-developers/7-pro-tips-for-room-fbadea4bfbd1#4785 55 | private fun buildDatabase(context: Context): HomeDB { 56 | return Room.databaseBuilder(context, HomeDB::class.java, DATABASE_NAME) 57 | .addCallback(object : RoomDatabase.Callback() { 58 | override fun onCreate(db: SupportSQLiteDatabase) { 59 | super.onCreate(db) 60 | val request = OneTimeWorkRequestBuilder().build() 61 | WorkManager.getInstance(context).enqueue(request) 62 | } 63 | }) 64 | .build() 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/db/HomeDao.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.db 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.room.Dao 5 | import androidx.room.Insert 6 | import androidx.room.OnConflictStrategy 7 | import androidx.room.Query 8 | import com.hankkin.jetpack_note.data.bean.Component 9 | 10 | /** 11 | * @author Hankkin 12 | * @date 2019-05-30 13 | */ 14 | @Dao 15 | interface HomeDao { 16 | 17 | @Query("SELECT * FROM component ORDER BY id") 18 | fun getComponents(): LiveData> 19 | 20 | @Insert(onConflict = OnConflictStrategy.REPLACE) 21 | fun insertAll(plants: List) 22 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/db/UserDao.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.db 2 | 3 | import androidx.paging.DataSource 4 | import androidx.room.Dao 5 | import androidx.room.Delete 6 | import androidx.room.Insert 7 | import androidx.room.Query 8 | import com.hankkin.jetpack_note.data.bean.User 9 | 10 | /** 11 | * created by Hankkin 12 | * on 2019-07-19 13 | */ 14 | @Dao 15 | interface UserDao { 16 | 17 | 18 | @Query("SELECT * FROM User ORDER BY name COLLATE NOCASE ASC") 19 | fun queryUsersByName(): DataSource.Factory 20 | 21 | @Insert 22 | fun insert(users: List) 23 | 24 | @Insert 25 | fun insert(user: User) 26 | 27 | @Delete 28 | fun delete(user: User) 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/net/Api.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.net 2 | 3 | import com.hankkin.jetpack_note.data.bean.GankResponse 4 | import retrofit2.Call 5 | import retrofit2.http.GET 6 | import retrofit2.http.Path 7 | 8 | /** 9 | * created by Hankkin 10 | * on 2019-07-30 11 | */ 12 | interface Api { 13 | 14 | @GET("data/Android/{count}/{page}") 15 | fun getGank( 16 | @Path("count") count: Int, 17 | @Path("page") page: Int 18 | ): Call 19 | 20 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/net/HttpClient.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.net 2 | 3 | import okhttp3.OkHttpClient 4 | import okhttp3.logging.HttpLoggingInterceptor 5 | import retrofit2.Retrofit 6 | import retrofit2.converter.gson.GsonConverterFactory 7 | 8 | /** 9 | * created by Hankkin 10 | * on 2019-07-30 11 | */ 12 | object HttpClient { 13 | 14 | private const val BASE_URL = "http://gank.io/api/" 15 | 16 | val instance: Api = create() 17 | 18 | private fun create(): Api { 19 | val logger = HttpLoggingInterceptor() 20 | logger.level = HttpLoggingInterceptor.Level.BASIC 21 | 22 | val client = OkHttpClient.Builder() 23 | .addInterceptor(logger) 24 | .build() 25 | 26 | return Retrofit.Builder() 27 | .baseUrl(BASE_URL) 28 | .client(client) 29 | .addConverterFactory(GsonConverterFactory.create()) 30 | .build() 31 | .create(Api::class.java) 32 | } 33 | 34 | 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/respository/HomeRepository.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.respository 2 | 3 | import com.hankkin.jetpack_note.data.db.HomeDao 4 | 5 | /** 6 | * @author Hankkin 7 | * @date 2019-05-30 8 | */ 9 | class HomeRepository private constructor(private val homeDao: HomeDao) { 10 | 11 | 12 | fun getPlants() = homeDao.getComponents() 13 | 14 | companion object { 15 | 16 | // For Singleton instantiation 17 | @Volatile private var instance: HomeRepository? = null 18 | 19 | fun getInstance(plantDao: HomeDao) = 20 | instance ?: synchronized(this) { 21 | instance 22 | ?: HomeRepository(plantDao).also { instance = it } 23 | } 24 | } 25 | 26 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/respository/PagingRespository.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.respository 2 | 3 | import androidx.paging.Config 4 | import androidx.paging.toLiveData 5 | import com.hankkin.jetpack_note.data.bean.User 6 | import com.hankkin.jetpack_note.data.db.UserDao 7 | import com.hankkin.jetpack_note.data.ioThread 8 | 9 | /** 10 | * created by Hankkin 11 | * on 2019-07-26 12 | */ 13 | class PagingRespository private constructor(private val userDao: UserDao) { 14 | 15 | 16 | fun getAllUsers() = userDao.queryUsersByName().toLiveData( 17 | Config( 18 | /** 19 | * A good page size is a value that fills at least a screen worth of content on a large 20 | * device so the User is unlikely to see a null item. 21 | * You can play with this constant to observe the paging behavior. 22 | *

23 | * It's possible to vary this with list device size, but often unnecessary, unless a 24 | * user scrolling on a large device is expected to scroll through items more quickly 25 | * than a small device, such as when the large device uses a grid layout of items. 26 | */ 27 | pageSize = 20, 28 | 29 | /** 30 | * If placeholders are enabled, PagedList will report the full size but some items might 31 | * be null in onBind method (PagedListAdapter triggers a rebind when data is loaded). 32 | *

33 | * If placeholders are disabled, onBind will never receive null but as more pages are 34 | * loaded, the scrollbars will jitter as new pages are loaded. You should probably 35 | * disable scrollbars if you disable placeholders. 36 | */ 37 | enablePlaceholders = true, 38 | 39 | /** 40 | * Maximum number of items a PagedList should hold in memory at once. 41 | *

42 | * This number triggers the PagedList to start dropping distant pages as more are loaded. 43 | */ 44 | maxSize = 200 45 | ) 46 | ) 47 | 48 | fun insert(text: CharSequence) = ioThread { 49 | userDao.insert(User(id = 0, name = text.toString())) 50 | } 51 | 52 | fun remove(cheese: User) = ioThread { 53 | userDao.delete(cheese) 54 | } 55 | 56 | companion object { 57 | @Volatile private var instance: PagingRespository? = null 58 | 59 | fun getInstance(userDao: UserDao) = 60 | instance ?: synchronized(this) { 61 | instance 62 | ?: PagingRespository(userDao).also { instance = it } 63 | } 64 | } 65 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/respository/gank/GankRespository.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.respository.gank 2 | 3 | import androidx.lifecycle.Transformations 4 | import androidx.paging.LivePagedListBuilder 5 | import androidx.paging.PagedList 6 | import com.hankkin.jetpack_note.data.Listing 7 | import com.hankkin.jetpack_note.data.bean.Gank 8 | 9 | /** 10 | * created by Hankkin 11 | * on 2019-07-30 12 | */ 13 | class GankRespository { 14 | 15 | companion object { 16 | 17 | private const val PAGE_SIZE = 20 18 | 19 | @Volatile 20 | private var instance: GankRespository? = null 21 | 22 | fun getInstance() = 23 | instance ?: synchronized(this) { 24 | instance 25 | ?: GankRespository().also { instance = it } 26 | } 27 | } 28 | 29 | fun getGank(): Listing { 30 | val sourceFactory = GankSourceFactory() 31 | val config = PagedList.Config.Builder() 32 | .setPageSize(PAGE_SIZE) 33 | .setInitialLoadSizeHint(PAGE_SIZE * 2) 34 | .setEnablePlaceholders(false) 35 | .build() 36 | val livePageList = LivePagedListBuilder(sourceFactory, config).build() 37 | val refreshState = Transformations.switchMap(sourceFactory.sourceLiveData) { it.initialLoad } 38 | return Listing( 39 | pagedList = livePageList, 40 | networkState = Transformations.switchMap(sourceFactory.sourceLiveData) { it.netWorkState }, 41 | retry = { sourceFactory.sourceLiveData.value?.retryAllFailed() }, 42 | refresh = { sourceFactory.sourceLiveData.value?.invalidate() }, 43 | refreshState = refreshState 44 | ) 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/data/respository/gank/GankSourceFactory.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.data.respository.gank 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.paging.DataSource 5 | import com.hankkin.jetpack_note.data.bean.Gank 6 | import com.hankkin.jetpack_note.data.net.Api 7 | import com.hankkin.jetpack_note.utils.Injection 8 | 9 | /** 10 | * created by Hankkin 11 | * on 2019-07-30 12 | * 干货数据工厂 13 | */ 14 | class GankSourceFactory(private val api: Api = Injection.provideApi()) : DataSource.Factory(){ 15 | 16 | val sourceLiveData = MutableLiveData() 17 | 18 | override fun create(): DataSource { 19 | val source = GankDataSource(api) 20 | sourceLiveData.postValue(source) 21 | return source 22 | } 23 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ext/ActivityExt.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ext 2 | 3 | import android.content.ClipData 4 | import android.content.ClipboardManager 5 | import android.content.Context 6 | import android.view.View 7 | import androidx.appcompat.app.ActionBar 8 | import androidx.appcompat.app.AppCompatActivity 9 | import androidx.appcompat.widget.Toolbar 10 | import androidx.fragment.app.Fragment 11 | import androidx.fragment.app.FragmentActivity 12 | import androidx.lifecycle.ViewModel 13 | import androidx.lifecycle.ViewModelProviders 14 | import com.google.android.material.snackbar.Snackbar 15 | import com.hankkin.jetpack_note.R 16 | import com.hankkin.jetpack_note.ViewModelFactory 17 | import com.hankkin.jetpack_note.utils.StatusBarUtil 18 | 19 | 20 | fun FragmentActivity.snackBarShow(view: View?, str: String) { 21 | view?.let { Snackbar.make(it, str, Snackbar.LENGTH_SHORT).show() } 22 | } 23 | 24 | fun AppCompatActivity.snackBarShow(view: View?, str: String) { 25 | view?.let { Snackbar.make(it, str, Snackbar.LENGTH_SHORT).show() } 26 | } 27 | 28 | fun AppCompatActivity.setupToolBar(toolbar: Toolbar, action: ActionBar.() -> Unit) { 29 | toolbar.setTitleTextColor(resources.getColor(R.color.black)) 30 | setSupportActionBar(toolbar) 31 | supportActionBar?.run { 32 | action() 33 | } 34 | } 35 | 36 | fun AppCompatActivity.setLightMode() { 37 | StatusBarUtil.setLightMode(this) 38 | } 39 | 40 | fun FragmentActivity.clipTxt(txt: String) { 41 | val cm = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager 42 | val mClipData = ClipData.newPlainText("Label", txt) 43 | cm.primaryClip = mClipData 44 | } 45 | 46 | 47 | fun AppCompatActivity.obtainViewModel(viewModelClass: Class) = 48 | ViewModelProviders.of(this, application?.let { ViewModelFactory.getInstance(it) }).get(viewModelClass) 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ext/FragmentExt.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ext 2 | 3 | import android.content.ClipData 4 | import android.content.ClipboardManager 5 | import android.content.Context 6 | import android.view.View 7 | import androidx.appcompat.app.AppCompatActivity 8 | import androidx.fragment.app.Fragment 9 | import androidx.fragment.app.FragmentActivity 10 | import androidx.lifecycle.ViewModel 11 | import androidx.lifecycle.ViewModelProviders 12 | import com.google.android.material.snackbar.Snackbar 13 | import com.hankkin.jetpack_note.ViewModelFactory 14 | 15 | /** 16 | * created by ${Hankkin} 17 | * on 2019-06-12 18 | */ 19 | 20 | fun Fragment.snackBarShow(view: View, str: String) { 21 | Snackbar.make(view, str, Snackbar.LENGTH_SHORT).show() 22 | } 23 | 24 | fun Fragment.clipTxt(txt: String) { 25 | val cm = activity?.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager 26 | val mClipData = ClipData.newPlainText("Label", txt) 27 | cm.primaryClip = mClipData 28 | } 29 | 30 | fun Fragment.obtainViewModel(viewModelClass: Class) = 31 | ViewModelProviders.of(this, activity?.application?.let { ViewModelFactory.getInstance(it) }).get(viewModelClass) -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/AboutFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui 2 | 3 | 4 | import android.os.Bundle 5 | import androidx.fragment.app.Fragment 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import android.widget.ImageView 10 | import android.widget.TextView 11 | import com.google.android.material.bottomsheet.BottomSheetDialog 12 | import com.hankkin.jetpack_note.R 13 | import com.hankkin.jetpack_note.ui.other.CommonWebActivity 14 | import com.hankkin.jetpack_note.utils.AppUtils 15 | import com.hankkin.jetpack_note.utils.CommonUtils 16 | import com.hankkin.jetpack_note.utils.Constants 17 | import kotlinx.android.synthetic.main.fragment_about.* 18 | 19 | /** 20 | * 关于我们 21 | */ 22 | class AboutFragment : Fragment() { 23 | 24 | override fun onCreateView( 25 | inflater: LayoutInflater, container: ViewGroup?, 26 | savedInstanceState: Bundle? 27 | ): View? { 28 | return inflater.inflate(R.layout.fragment_about, container, false) 29 | } 30 | 31 | override fun onActivityCreated(savedInstanceState: Bundle?) { 32 | super.onActivityCreated(savedInstanceState) 33 | context?.run { 34 | tv_about_version_code.text = "V ${AppUtils.getVersionName(this)}" 35 | iv_about_github.setOnClickListener { CommonWebActivity.loadUrl(this, Constants.AboutUrl.GITHUB, Constants.AboutUrl.GITHUB_TITLE) } 36 | iv_about_juejin.setOnClickListener { CommonWebActivity.loadUrl(this, Constants.AboutUrl.JUEJIN, Constants.AboutUrl.JUEJIN_TITLE) } 37 | iv_about_jianshu.setOnClickListener { CommonWebActivity.loadUrl(this, Constants.AboutUrl.JIANSHU, Constants.AboutUrl.JIANSHU_TITLE) } 38 | iv_about_csdn.setOnClickListener { CommonWebActivity.loadUrl(this, Constants.AboutUrl.CSDN, Constants.AboutUrl.CSDN_TITLE) } 39 | tv_about_rate.setOnClickListener { CommonUtils.gradeApp(this) } 40 | tv_about_blog.setOnClickListener { CommonWebActivity.loadUrl(this, Constants.AboutUrl.BLOG, Constants.AboutUrl.BLOG_TITLE) } 41 | } 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/CodeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.fragment.app.Fragment 8 | import com.hankkin.jetpack_note.databinding.FragmentCodeBinding 9 | import com.hankkin.jetpack_note.databinding.FragmentLifecyclesBinding 10 | 11 | class CodeFragment : Fragment() { 12 | 13 | override fun onCreateView( 14 | inflater: LayoutInflater, 15 | container: ViewGroup?, 16 | savedInstanceState: Bundle? 17 | ): View? { 18 | return FragmentCodeBinding.inflate(inflater, container, false).root 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/MoreSampleFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui 2 | 3 | 4 | import android.os.Bundle 5 | import android.os.Handler 6 | import androidx.fragment.app.Fragment 7 | import android.view.LayoutInflater 8 | import android.view.View 9 | import android.view.ViewGroup 10 | import androidx.viewpager2.adapter.FragmentStateAdapter 11 | 12 | import com.hankkin.jetpack_note.R 13 | import com.hankkin.jetpack_note.ui.livedata.LiveDataFragment 14 | import com.hankkin.jetpack_note.ui.viewmodel.ViewModelFragment 15 | import com.hankkin.jetpack_note.widget.TabLayoutMediator 16 | import kotlinx.android.synthetic.main.fragment_more_sample.* 17 | import kotlinx.android.synthetic.main.layout_loading.* 18 | 19 | 20 | /** 21 | *More Demo 22 | */ 23 | class MoreSampleFragment : Fragment() { 24 | 25 | private val mTitles = arrayOf("LiveData", "ViewModel", "Room", "WorkManager", "Camera2") 26 | private val mFgs by lazy { 27 | arrayOf( 28 | LiveDataFragment(), 29 | ViewModelFragment(), 30 | CodeFragment(), 31 | CodeFragment(), 32 | CodeFragment() 33 | ) 34 | } 35 | 36 | override fun onCreateView( 37 | inflater: LayoutInflater, container: ViewGroup?, 38 | savedInstanceState: Bundle? 39 | ): View? { 40 | return inflater.inflate(R.layout.fragment_more_sample, container, false) 41 | } 42 | 43 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 44 | super.onViewCreated(view, savedInstanceState) 45 | Handler().postDelayed({ 46 | setUI() 47 | loading.visibility = View.GONE 48 | }, 500) 49 | } 50 | 51 | private fun setUI() { 52 | vp.adapter = object : FragmentStateAdapter(this) { 53 | override fun getItemCount() = mFgs.size 54 | override fun createFragment(position: Int) = mFgs[position] 55 | } 56 | vp.offscreenPageLimit = mTitles.size 57 | TabLayoutMediator(tab, vp, 58 | TabLayoutMediator.OnConfigureTabCallback { tab, position -> tab.text = mTitles[position] }).attach() 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/SettingFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui 2 | 3 | 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.fragment.app.Fragment 9 | import com.hankkin.jetpack_note.R 10 | import com.hankkin.jetpack_note.ui.other.CommonWebActivity 11 | import com.hankkin.jetpack_note.utils.Constants 12 | import com.tencent.bugly.beta.Beta 13 | import kotlinx.android.synthetic.main.fragment_setting.* 14 | 15 | 16 | /** 17 | *设置 18 | */ 19 | class SettingFragment : Fragment() { 20 | 21 | override fun onCreateView( 22 | inflater: LayoutInflater, container: ViewGroup?, 23 | savedInstanceState: Bundle? 24 | ): View? { 25 | return inflater.inflate(R.layout.fragment_setting, container, false) 26 | } 27 | 28 | override fun onActivityCreated(savedInstanceState: Bundle?) { 29 | super.onActivityCreated(savedInstanceState) 30 | ll_setting_update.setOnClickListener { 31 | Beta.checkUpgrade(true, false) 32 | } 33 | ll_setting_github.setOnClickListener { 34 | activity?.let { it1 -> CommonWebActivity.loadUrl(it1, Constants.AboutUrl.JETPACK, Constants.AboutUrl.JETPACK_TITLE) } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/adapter/HomeListAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.adapter 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.Toast 7 | import androidx.navigation.findNavController 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.ListAdapter 10 | import androidx.recyclerview.widget.RecyclerView 11 | import com.hankkin.jetpack_note.data.bean.Component 12 | import com.hankkin.jetpack_note.databinding.ListItemHomeBinding 13 | import com.hankkin.jetpack_note.ui.home.HomeFragmentDirections 14 | 15 | class HomeListAdapter : ListAdapter((ComponentDiffCallback())) { 16 | 17 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { 18 | return ViewHolder( 19 | ListItemHomeBinding.inflate( 20 | LayoutInflater.from(parent.context), parent, false 21 | ) 22 | ) 23 | } 24 | 25 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 26 | val item = getItem(position) 27 | holder.apply { 28 | bind(createOnClickListener(item.link, item.title), item) 29 | itemView.tag = item 30 | } 31 | } 32 | 33 | private fun createOnClickListener(link: String, title: String): View.OnClickListener { 34 | return View.OnClickListener { 35 | if (link.isEmpty()) { 36 | Toast.makeText(it.context, "敬请期待...", Toast.LENGTH_SHORT).show() 37 | } else { 38 | val direction = HomeFragmentDirections.actionNavigationFragmentToWebFragment(link, title) 39 | it.findNavController().navigate(direction) 40 | } 41 | } 42 | } 43 | 44 | 45 | class ViewHolder( 46 | private val binding: ListItemHomeBinding 47 | ) : RecyclerView.ViewHolder(binding.root) { 48 | fun bind(listener: View.OnClickListener, item: Component) { 49 | binding.apply { 50 | clickListener = listener 51 | component = item 52 | executePendingBindings() 53 | } 54 | } 55 | } 56 | } 57 | 58 | private class ComponentDiffCallback : DiffUtil.ItemCallback() { 59 | 60 | override fun areItemsTheSame(oldItem: Component, newItem: Component): Boolean { 61 | return oldItem.link == newItem.link 62 | } 63 | 64 | override fun areContentsTheSame(oldItem: Component, newItem: Component): Boolean { 65 | return oldItem == newItem 66 | } 67 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/adapter/PagingDemoAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.adapter 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import android.widget.Toast 7 | import androidx.paging.PagedListAdapter 8 | import androidx.recyclerview.widget.DiffUtil 9 | import androidx.recyclerview.widget.RecyclerView 10 | import com.hankkin.jetpack_note.data.bean.User 11 | import com.hankkin.jetpack_note.databinding.AdapterPagingItemBinding 12 | 13 | /** 14 | * created by Hankkin 15 | * on 2019-07-19 16 | */ 17 | class PagingDemoAdapter : PagedListAdapter(diffCallback) { 18 | 19 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 20 | ViewHolder(AdapterPagingItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)) 21 | 22 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 23 | val item = getItem(position) 24 | holder.apply { 25 | bind(createOnClickListener(item), item) 26 | itemView.tag = item 27 | } 28 | } 29 | 30 | private fun createOnClickListener(item: User?): View.OnClickListener { 31 | return View.OnClickListener { 32 | Toast.makeText(it.context, item?.name, Toast.LENGTH_SHORT).show() 33 | } 34 | } 35 | 36 | 37 | class ViewHolder(private val binding: AdapterPagingItemBinding) : RecyclerView.ViewHolder(binding.root) { 38 | fun bind(listener: View.OnClickListener, item: User?) { 39 | binding.apply { 40 | clickListener = listener 41 | user = item 42 | executePendingBindings() 43 | } 44 | } 45 | } 46 | 47 | companion object { 48 | /** 49 | * This diff callback informs the PagedListAdapter how to compute list differences when new 50 | * PagedLists arrive. 51 | *

52 | * When you add a Cheese with the 'Add' button, the PagedListAdapter uses diffCallback to 53 | * detect there's only a single item difference from before, so it only needs to animate and 54 | * rebind a single view. 55 | * 56 | * @see android.support.v7.util.DiffUtil 57 | */ 58 | private val diffCallback = object : DiffUtil.ItemCallback() { 59 | override fun areItemsTheSame(oldItem: User, newItem: User): Boolean = 60 | oldItem.id == newItem.id 61 | 62 | /** 63 | * Note that in kotlin, == checking on data classes compares all contents, but in Java, 64 | * typically you'll implement Object#equals, and use it to compare object contents. 65 | */ 66 | override fun areContentsTheSame(oldItem: User, newItem: User): Boolean = 67 | oldItem == newItem 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/adapter/PagingWithNetWorkAdapter.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.adapter 2 | 3 | import android.view.LayoutInflater 4 | import android.view.View 5 | import android.view.ViewGroup 6 | import androidx.paging.PagedListAdapter 7 | import androidx.recyclerview.widget.DiffUtil 8 | import androidx.recyclerview.widget.RecyclerView 9 | import com.hankkin.jetpack_note.data.NetworkState 10 | import com.hankkin.jetpack_note.data.bean.Gank 11 | import com.hankkin.jetpack_note.databinding.AdapterPagingWithNetworkItemBinding 12 | import com.hankkin.jetpack_note.ui.other.CommonWebActivity 13 | 14 | /** 15 | * created by Hankkin 16 | * on 2019-07-30 17 | */ 18 | class PagingWithNetWorkAdapter : PagedListAdapter(diffCallback) { 19 | 20 | private var networkState: NetworkState? = null 21 | 22 | 23 | override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = 24 | ViewHolder(AdapterPagingWithNetworkItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)) 25 | 26 | override fun onBindViewHolder(holder: ViewHolder, position: Int) { 27 | val item = getItem(position) 28 | holder.apply { 29 | bind(createOnClickListener(item), item) 30 | itemView.tag = item 31 | } 32 | } 33 | 34 | 35 | class ViewHolder(private val binding: AdapterPagingWithNetworkItemBinding) : RecyclerView.ViewHolder(binding.root) { 36 | fun bind(listener: View.OnClickListener, item: Gank?) { 37 | binding.apply { 38 | clickListener = listener 39 | gank = item 40 | executePendingBindings() 41 | } 42 | } 43 | } 44 | 45 | private fun createOnClickListener(item: Gank?): View.OnClickListener { 46 | return View.OnClickListener { 47 | item?.run { 48 | CommonWebActivity.loadUrl(it.context, url, desc) 49 | } 50 | } 51 | } 52 | 53 | companion object { 54 | /** 55 | * This diff callback informs the PagedListAdapter how to compute list differences when new 56 | * PagedLists arrive. 57 | *

58 | * When you add a Cheese with the 'Add' button, the PagedListAdapter uses diffCallback to 59 | * detect there's only a single item difference from before, so it only needs to animate and 60 | * rebind a single view. 61 | * 62 | * @see android.support.v7.util.DiffUtil 63 | */ 64 | private val diffCallback = object : DiffUtil.ItemCallback() { 65 | override fun areItemsTheSame(oldItem: Gank, newItem: Gank): Boolean = 66 | oldItem._id == newItem._id 67 | 68 | /** 69 | * Note that in kotlin, == checking on data classes compares all contents, but in Java, 70 | * typically you'll implement Object#equals, and use it to compare object contents. 71 | */ 72 | override fun areContentsTheSame(oldItem: Gank, newItem: Gank): Boolean = 73 | oldItem == newItem 74 | } 75 | } 76 | 77 | private fun hasExtraRow() = networkState != null && networkState != NetworkState.HIDDEN 78 | 79 | fun setNetworkState(newNetworkState: NetworkState) { 80 | val previousState = this.networkState 81 | val hadExtraRow = hasExtraRow() 82 | this.networkState = newNetworkState 83 | val hasExtraRow = hasExtraRow() 84 | if (hadExtraRow != hasExtraRow) { 85 | if (hadExtraRow) { 86 | notifyItemRemoved(super.getItemCount()) 87 | } else { 88 | notifyItemInserted(super.getItemCount()) 89 | } 90 | } else if (hasExtraRow && previousState != newNetworkState) { 91 | notifyItemChanged(itemCount - 1) 92 | } 93 | } 94 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/home/HomeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.home 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.fragment.app.Fragment 8 | import androidx.fragment.app.viewModels 9 | import androidx.lifecycle.Observer 10 | import androidx.recyclerview.widget.GridLayoutManager 11 | import androidx.recyclerview.widget.LinearLayoutManager 12 | import com.hankkin.jetpack_note.R 13 | import com.hankkin.jetpack_note.ui.adapter.HomeListAdapter 14 | import com.hankkin.jetpack_note.databinding.FragmentHomeBinding 15 | import com.hankkin.jetpack_note.ext.obtainViewModel 16 | import com.hankkin.jetpack_note.utils.Injection 17 | 18 | class HomeFragment : Fragment() { 19 | 20 | private var isLine: Boolean = false 21 | private lateinit var viewModel: HomeListViewModel 22 | 23 | override fun onCreateView( 24 | inflater: LayoutInflater, 25 | container: ViewGroup?, 26 | savedInstanceState: Bundle? 27 | ): View? { 28 | val binding = FragmentHomeBinding.inflate(inflater, container, false) 29 | context ?: return binding.root 30 | val adapter = HomeListAdapter() 31 | binding.rvHome.adapter = adapter 32 | subscribeUi(adapter, binding) 33 | return binding.root 34 | } 35 | 36 | 37 | private fun subscribeUi(adapter: HomeListAdapter, binding: FragmentHomeBinding) { 38 | viewModel = obtainViewModel(HomeListViewModel::class.java) 39 | viewModel.listData.observe(viewLifecycleOwner, Observer { data -> 40 | if (data != null) adapter.submitList(data) 41 | }) 42 | binding.fab.setOnClickListener { 43 | binding.rvHome.layoutManager = if (isLine) GridLayoutManager(context,2) else LinearLayoutManager(context) 44 | binding.fab.setImageResource(if (isLine) R.mipmap.icon_lin else R.mipmap.icon_grid) 45 | isLine = !isLine 46 | } 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/home/HomeListViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.home 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.ViewModel 5 | import com.hankkin.jetpack_note.data.bean.Component 6 | import com.hankkin.jetpack_note.data.respository.HomeRepository 7 | 8 | /** 9 | * @author Hankkin 10 | * @date 2019-05-30 11 | */ 12 | class HomeListViewModel internal constructor(homeRepository: HomeRepository) : ViewModel() { 13 | 14 | val listData: LiveData> = homeRepository.getPlants() 15 | 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/lifecycles/BoundLocationManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019, The Android Open Source Project 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.ui.lifecycles; 18 | 19 | import android.content.Context; 20 | import android.location.Location; 21 | import android.location.LocationListener; 22 | import android.location.LocationManager; 23 | import android.util.Log; 24 | import androidx.lifecycle.Lifecycle; 25 | import androidx.lifecycle.LifecycleObserver; 26 | import androidx.lifecycle.LifecycleOwner; 27 | import androidx.lifecycle.OnLifecycleEvent; 28 | import com.hankkin.jetpack_note.utils.FloatWindowUtils; 29 | 30 | public class BoundLocationManager { 31 | public static void bindLocationListenerIn(LifecycleOwner lifecycleOwner, 32 | LocationListener listener, Context context) { 33 | new BoundLocationListener(lifecycleOwner, listener, context); 34 | } 35 | 36 | @SuppressWarnings("MissingPermission") 37 | static class BoundLocationListener implements LifecycleObserver { 38 | private final Context mContext; 39 | private LocationManager mLocationManager; 40 | private final LocationListener mListener; 41 | 42 | BoundLocationListener(LifecycleOwner lifecycleOwner, 43 | LocationListener listener, Context context) { 44 | mContext = context; 45 | mListener = listener; 46 | lifecycleOwner.getLifecycle().addObserver(this); 47 | } 48 | 49 | @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) 50 | void addLocationListener() { 51 | mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE); 52 | mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, mListener); 53 | FloatWindowUtils.INSTANCE.addViewContent("Lifecycles-ON_RESUME--开启定位监听"); 54 | Location lastLocation = mLocationManager.getLastKnownLocation( 55 | LocationManager.GPS_PROVIDER); 56 | if (lastLocation != null) { 57 | mListener.onLocationChanged(lastLocation); 58 | } 59 | } 60 | 61 | 62 | @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) 63 | void removeLocationListener() { 64 | if (mLocationManager == null) { 65 | return; 66 | } 67 | mLocationManager.removeUpdates(mListener); 68 | mLocationManager = null; 69 | FloatWindowUtils.INSTANCE.addViewContent("Lifecycles-ON_PAUSE--停止定位监听"); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/lifecycles/LifecyclesFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.lifecycles 2 | 3 | import android.Manifest 4 | import android.annotation.SuppressLint 5 | import android.location.Location 6 | import android.location.LocationListener 7 | import android.os.Bundle 8 | import android.view.LayoutInflater 9 | import android.view.View 10 | import android.view.ViewGroup 11 | import android.widget.Toast 12 | import androidx.fragment.app.Fragment 13 | import com.hankkin.jetpack_note.R 14 | import com.hankkin.jetpack_note.ext.snackBarShow 15 | import com.hankkin.jetpack_note.utils.FloatWindowUtils 16 | import com.tbruyelle.rxpermissions2.RxPermissions 17 | import com.yhao.floatwindow.FloatWindow 18 | import kotlinx.android.synthetic.main.fragment_lifecycles.* 19 | 20 | class LifecyclesFragment : Fragment() { 21 | 22 | private var mGpsListener: MyLocationListener? = null 23 | 24 | override fun onCreateView( 25 | inflater: LayoutInflater, 26 | container: ViewGroup?, 27 | savedInstanceState: Bundle? 28 | ): View? { 29 | return inflater.inflate(R.layout.fragment_lifecycles, container, false) 30 | } 31 | 32 | override fun onActivityCreated(savedInstanceState: Bundle?) { 33 | super.onActivityCreated(savedInstanceState) 34 | setUI() 35 | } 36 | 37 | private fun setUI() { 38 | 39 | btn_add_obserber.setOnClickListener { 40 | if (FloatWindow.get() == null) { 41 | FloatWindowUtils.init(activity?.application!!) 42 | } 43 | FloatWindowUtils.show() 44 | } 45 | 46 | btn_location.setOnClickListener { 47 | if (mGpsListener != null) { 48 | snackBarShow(ll_life_root, getString(R.string.has_location_hint)) 49 | return@setOnClickListener 50 | } 51 | mGpsListener = MyLocationListener() 52 | requestPermission() 53 | } 54 | 55 | } 56 | 57 | 58 | @SuppressLint("CheckResult") 59 | private fun requestPermission() { 60 | RxPermissions(activity!!) 61 | .requestEach(Manifest.permission.ACCESS_FINE_LOCATION) 62 | .subscribe { p0 -> 63 | when { 64 | p0.granted -> { 65 | BoundLocationManager.bindLocationListenerIn(this, mGpsListener, activity?.applicationContext) 66 | } 67 | p0.shouldShowRequestPermissionRationale -> { 68 | snackBarShow(ll_life_root, "请在设置-应用-权限管理中开启权限") 69 | } 70 | else -> snackBarShow(ll_life_root, "权限被拒绝,无法启用定位功能") 71 | } 72 | } 73 | } 74 | 75 | 76 | private inner class MyLocationListener : LocationListener { 77 | override fun onLocationChanged(location: Location) { 78 | tv_life_location.text = location.latitude.toString() + ", " + location.longitude 79 | } 80 | 81 | override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} 82 | 83 | override fun onProviderEnabled(provider: String) { 84 | Toast.makeText( 85 | context, 86 | "Provider enabled: $provider", Toast.LENGTH_SHORT 87 | ).show() 88 | } 89 | 90 | override fun onProviderDisabled(provider: String) {} 91 | } 92 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/livedata/LiveDataFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.livedata 2 | 3 | 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.fragment.app.Fragment 9 | import androidx.lifecycle.MutableLiveData 10 | import androidx.lifecycle.Observer 11 | import androidx.lifecycle.ViewModelProviders 12 | import com.hankkin.jetpack_note.R 13 | import com.hankkin.jetpack_note.ext.obtainViewModel 14 | import com.hankkin.jetpack_note.utils.FloatWindowUtils 15 | import com.yhao.floatwindow.FloatWindow 16 | import kotlinx.android.synthetic.main.fragment_live_data.* 17 | 18 | 19 | /** 20 | *LiveData 21 | */ 22 | class LiveDataFragment : Fragment() { 23 | 24 | private lateinit var liveData: MutableLiveData 25 | private var mId = -1 26 | 27 | private val viewModel: LiveDataViewModel by lazy { obtainViewModel(LiveDataViewModel::class.java) } 28 | 29 | override fun onCreateView( 30 | inflater: LayoutInflater, container: ViewGroup?, 31 | savedInstanceState: Bundle? 32 | ): View? { 33 | return inflater.inflate(R.layout.fragment_live_data, container, false) 34 | } 35 | 36 | override fun onActivityCreated(savedInstanceState: Bundle?) { 37 | super.onActivityCreated(savedInstanceState) 38 | liveData = MutableLiveData() 39 | btn_observer_data.setOnClickListener { 40 | if (FloatWindow.get() == null) { 41 | FloatWindowUtils.init(activity?.application!!) 42 | } 43 | FloatWindowUtils.show() 44 | 45 | //创建一个观察者去更新UI 46 | val statusObserver = Observer { lifeStatus -> 47 | FloatWindowUtils.addViewContent("LiveData-onChanged: $lifeStatus") 48 | } 49 | liveData.observeForever(statusObserver) 50 | } 51 | 52 | //改变ViewModel中idLiveData中的值 53 | btn_observer_map.setOnClickListener { 54 | mId++ 55 | viewModel.id.postValue(mId) 56 | } 57 | //当idLiveData变化后,UserBean也会改变且更新Textview的文本 58 | viewModel.bean.observe( 59 | this, 60 | Observer { tv_livedata_map.text = if (it == null) "未查找到User" else "为你查找到的User为:${it.name}" }) 61 | } 62 | 63 | override fun onStart() { 64 | super.onStart() 65 | liveData.value = "onStart()" 66 | } 67 | 68 | override fun onPause() { 69 | super.onPause() 70 | liveData.value = "onPause()" 71 | } 72 | 73 | override fun onStop() { 74 | super.onStop() 75 | liveData.value = "onStop()" 76 | } 77 | 78 | override fun onDestroy() { 79 | super.onDestroy() 80 | liveData.value = "onDestroy()" 81 | } 82 | 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/livedata/LiveDataViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.livedata 2 | 3 | import androidx.arch.core.util.Function 4 | import androidx.lifecycle.LiveData 5 | import androidx.lifecycle.MutableLiveData 6 | import androidx.lifecycle.Transformations 7 | import androidx.lifecycle.ViewModel 8 | import com.hankkin.jetpack_note.data.bean.User 9 | 10 | /** 11 | * @author Hankkin 12 | * @date 2019-05-30 13 | */ 14 | class LiveDataViewModel : ViewModel() { 15 | val data = listOf( 16 | User(0, "Hankkin"), 17 | User(1, "Tony"), 18 | User(2, "Bob"), 19 | User(3, "Lucy") 20 | ) 21 | 22 | val id = MutableLiveData() 23 | //map转换返回User实体 24 | val bean: LiveData = Transformations.map(id, Function { 25 | return@Function findUserById(id.value!!) 26 | }) 27 | //根据id查找User 28 | private fun findUserById(id: Int): User? { 29 | return data.find { it.id == id } 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/NavigationFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.fragment.app.Fragment 8 | import androidx.navigation.fragment.findNavController 9 | import com.hankkin.jetpack_note.R 10 | import com.hankkin.jetpack_note.databinding.FragmentNavigationBinding 11 | 12 | class NavigationFragment : Fragment() { 13 | 14 | override fun onCreateView( 15 | inflater: LayoutInflater, 16 | container: ViewGroup?, savedInstanceState: Bundle? 17 | ): View? { 18 | val binding = FragmentNavigationBinding.inflate(inflater, container, false) 19 | clickEvent(binding) 20 | return binding.root 21 | } 22 | 23 | private fun clickEvent(binding: FragmentNavigationBinding) { 24 | binding.btnNav.setOnClickListener { 25 | findNavController().navigate(R.id.navSampleActivity) 26 | } 27 | binding.btnBottom.setOnClickListener { 28 | findNavController().navigate(R.id.bottomNavSampleActivity) 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/activity/BottomNavSampleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation.activity 2 | 3 | import android.os.Bundle 4 | import androidx.appcompat.app.AppCompatActivity 5 | import androidx.navigation.NavController 6 | import androidx.navigation.Navigation 7 | import androidx.navigation.ui.setupWithNavController 8 | import com.hankkin.jetpack_note.R 9 | import com.hankkin.jetpack_note.utils.StatusBarUtil 10 | import kotlinx.android.synthetic.main.activity_bottom_nav_sample.* 11 | import kotlinx.android.synthetic.main.app_bar_nav_sample.toolbar 12 | 13 | class BottomNavSampleActivity : AppCompatActivity() { 14 | 15 | private lateinit var navController: NavController 16 | 17 | override fun onCreate(savedInstanceState: Bundle?) { 18 | super.onCreate(savedInstanceState) 19 | setContentView(R.layout.activity_bottom_nav_sample) 20 | initView() 21 | } 22 | 23 | private fun initView() { 24 | StatusBarUtil.setLightMode(this) 25 | setSupportActionBar(toolbar) 26 | supportActionBar?.setDisplayHomeAsUpEnabled(true) 27 | supportActionBar?.setDisplayShowTitleEnabled(true) 28 | toolbar.setTitleTextColor(resources.getColor(R.color.black)) 29 | navController = Navigation.findNavController(this, R.id.fragment_home_sample) 30 | toolbar.setNavigationOnClickListener { 31 | navController.navigateUp() 32 | } 33 | initBottomNavigation() 34 | } 35 | 36 | private fun initBottomNavigation() { 37 | bottom_navigation_view?.setupWithNavController(navController) 38 | navController.addOnDestinationChangedListener { _, destination, _ -> 39 | toolbar.title = destination.label 40 | } 41 | } 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/activity/NavSampleActivity.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation.activity 2 | 3 | import android.os.Bundle 4 | import android.view.Menu 5 | import android.view.MenuItem 6 | import androidx.appcompat.app.ActionBarDrawerToggle 7 | import androidx.appcompat.app.AppCompatActivity 8 | import androidx.appcompat.widget.Toolbar 9 | import androidx.core.view.GravityCompat 10 | import androidx.drawerlayout.widget.DrawerLayout 11 | import com.google.android.material.floatingactionbutton.FloatingActionButton 12 | import com.google.android.material.navigation.NavigationView 13 | import com.hankkin.jetpack_note.R 14 | import com.hankkin.jetpack_note.ui.MoreSampleFragment 15 | import com.hankkin.jetpack_note.utils.StatusBarUtil 16 | import kotlinx.android.synthetic.main.activity_nav_sample.* 17 | 18 | class NavSampleActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelectedListener { 19 | 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | setContentView(R.layout.activity_nav_sample) 23 | 24 | StatusBarUtil.setLightMode(this) 25 | 26 | val toolbar: Toolbar = findViewById(R.id.toolbar) 27 | toolbar.setTitleTextColor(resources.getColor(R.color.black)) 28 | setSupportActionBar(toolbar) 29 | 30 | val fab: FloatingActionButton = findViewById(R.id.fab) 31 | fab.setOnClickListener { _ -> 32 | finish() 33 | } 34 | val navView: NavigationView = findViewById(R.id.nav_view) 35 | val toggle = ActionBarDrawerToggle( 36 | this, drawer_layout, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close 37 | ) 38 | drawer_layout.addDrawerListener(toggle) 39 | toggle.syncState() 40 | 41 | navView.setNavigationItemSelectedListener(this) 42 | } 43 | 44 | override fun onBackPressed() { 45 | val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) 46 | if (drawerLayout.isDrawerOpen(GravityCompat.START)) { 47 | drawerLayout.closeDrawer(GravityCompat.START) 48 | } else { 49 | super.onBackPressed() 50 | } 51 | } 52 | 53 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 54 | menuInflater.inflate(R.menu.nav_sample, menu) 55 | return true 56 | } 57 | 58 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 59 | return when (item.itemId) { 60 | R.id.action_settings -> true 61 | else -> super.onOptionsItemSelected(item) 62 | } 63 | } 64 | 65 | override fun onNavigationItemSelected(item: MenuItem): Boolean { 66 | when (item.itemId) { 67 | R.id.nav_home -> { 68 | // Handle the camera action 69 | 70 | } 71 | R.id.nav_gallery -> { 72 | val transaction = supportFragmentManager.beginTransaction() 73 | transaction.add(R.id.container, MoreSampleFragment()) 74 | transaction.commit() 75 | } 76 | R.id.nav_slideshow -> { 77 | 78 | } 79 | R.id.nav_tools -> { 80 | 81 | } 82 | R.id.nav_share -> { 83 | 84 | } 85 | R.id.nav_send -> { 86 | 87 | } 88 | } 89 | val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout) 90 | drawerLayout.closeDrawer(GravityCompat.START) 91 | return true 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/fg/SampleArgsFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation.fg 2 | 3 | 4 | import android.os.Bundle 5 | import androidx.fragment.app.Fragment 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import androidx.navigation.fragment.findNavController 10 | import androidx.navigation.fragment.navArgs 11 | 12 | import com.hankkin.jetpack_note.R 13 | import kotlinx.android.synthetic.main.activity_main.* 14 | import kotlinx.android.synthetic.main.fragment_sample_args.* 15 | 16 | /** 17 | * A simple [Fragment] subclass. 18 | * 19 | */ 20 | class SampleArgsFragment : Fragment() { 21 | 22 | private val args: SampleArgsFragmentArgs by navArgs() 23 | 24 | override fun onCreateView( 25 | inflater: LayoutInflater, container: ViewGroup?, 26 | savedInstanceState: Bundle? 27 | ): View? { 28 | // Inflate the layout for this fragment 29 | return inflater.inflate(R.layout.fragment_sample_args, container, false) 30 | } 31 | 32 | 33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 34 | super.onViewCreated(view, savedInstanceState) 35 | 36 | requireActivity().toolbar.title = resources.getString(R.string.title_args) 37 | tv_sample_args_content.text = 38 | if (args.argumentFlag == 0) args.argumentNormal 39 | else args.argumentBean.title 40 | 41 | btn_nav_args_jump.setOnClickListener { 42 | findNavController().navigate(R.id.action_argsSampleFragment_to_homeSampleFragment) 43 | } 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/fg/SampleDashboardFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation.fg 2 | 3 | 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.fragment.app.Fragment 9 | import androidx.navigation.fragment.findNavController 10 | import androidx.navigation.fragment.navArgs 11 | import com.hankkin.jetpack_note.R 12 | import kotlinx.android.synthetic.main.fragment_sample_dashboard.* 13 | 14 | /** 15 | * A simple [Fragment] subclass. 16 | * 17 | */ 18 | class SampleDashboardFragment : Fragment() { 19 | 20 | override fun onCreateView( 21 | inflater: LayoutInflater, container: ViewGroup?, 22 | savedInstanceState: Bundle? 23 | ): View? { 24 | return inflater.inflate(R.layout.fragment_sample_dashboard, container, false) 25 | } 26 | 27 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 28 | super.onViewCreated(view, savedInstanceState) 29 | btn_nav_dashboard_jump.setOnClickListener { 30 | findNavController().navigate(R.id.action_dashBoardSampleFragment_to_notificationSampleFragment) 31 | } 32 | } 33 | 34 | override fun setUserVisibleHint(isVisibleToUser: Boolean) { 35 | super.setUserVisibleHint(isVisibleToUser) 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/fg/SampleHomeFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation.fg 2 | 3 | 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import androidx.fragment.app.Fragment 9 | import androidx.navigation.fragment.findNavController 10 | import com.hankkin.jetpack_note.R 11 | import com.hankkin.jetpack_note.data.bean.Component 12 | import kotlinx.android.synthetic.main.fragment_sample_home.* 13 | 14 | /** 15 | * A simple [Fragment] subclass. 16 | * 17 | */ 18 | class SampleHomeFragment : Fragment() { 19 | 20 | override fun onCreateView( 21 | inflater: LayoutInflater, container: ViewGroup?, 22 | savedInstanceState: Bundle? 23 | ): View? { 24 | return inflater.inflate(R.layout.fragment_sample_home, container, false) 25 | } 26 | 27 | 28 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 29 | super.onViewCreated(view, savedInstanceState) 30 | 31 | val navController = findNavController() 32 | //jump 33 | btn_nav_sample_jump.setOnClickListener { 34 | navController.navigate(R.id.action_homeSampleFragment_to_dashBoardSampleFragment) 35 | } 36 | //jump with action 37 | btn_nav_sample_jump_action.setOnClickListener { 38 | navController.navigate(R.id.action_homeSampleFragment_to_dashBoardSampleFragment_action) 39 | } 40 | 41 | 42 | val component = Component("1", "我是传递过来实体类Component类型参数", "", "") 43 | //基本类型跳转 44 | btn_nav_sample_jump_argument_normal.setOnClickListener { 45 | val directions = 46 | SampleHomeFragmentDirections.actionHomeSampleFragmentToArgsSampleFragment( 47 | 0, 48 | "我是传递过来基本类型String参数", 49 | component 50 | ) 51 | navController.navigate(directions) 52 | } 53 | //自定义实体类型跳转 注意 实体类需要序列化 54 | btn_nav_sample_jump_argument_bean.setOnClickListener { 55 | val directions = 56 | SampleHomeFragmentDirections.actionHomeSampleFragmentToArgsSampleFragment( 57 | 1, 58 | "", 59 | component 60 | ) 61 | navController.navigate(directions) 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/navigation/fg/SampleNotificationFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.navigation.fg 2 | 3 | 4 | import android.app.NotificationChannel 5 | import android.app.NotificationManager 6 | import android.content.Context 7 | import android.os.Build 8 | import android.os.Bundle 9 | import android.view.LayoutInflater 10 | import android.view.View 11 | import android.view.ViewGroup 12 | import androidx.core.app.NotificationCompat 13 | import androidx.fragment.app.Fragment 14 | import androidx.navigation.fragment.findNavController 15 | import com.hankkin.jetpack_note.R 16 | import com.hankkin.jetpack_note.ext.snackBarShow 17 | import kotlinx.android.synthetic.main.fragment_sample_notification.* 18 | 19 | /** 20 | * A simple [Fragment] subclass. 21 | * 22 | */ 23 | class SampleNotificationFragment : Fragment() { 24 | 25 | override fun onCreateView( 26 | inflater: LayoutInflater, container: ViewGroup?, 27 | savedInstanceState: Bundle? 28 | ): View? { 29 | return inflater.inflate(R.layout.fragment_sample_notification, container, false) 30 | } 31 | 32 | 33 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 34 | super.onViewCreated(view, savedInstanceState) 35 | 36 | tv_deep_link_args_hint.text = arguments?.getString("deep_args") 37 | 38 | btn_nav_dashboard_jump_home.setOnClickListener { 39 | findNavController().navigate(R.id.action_notificationSampleFragment_to_homeSampleFragment) 40 | } 41 | 42 | btn_nav_deep_link.setOnClickListener { 43 | val args = Bundle() 44 | args.putString("deep_args",et_deep_link.text.toString()) 45 | val deep = findNavController().createDeepLink() 46 | .setDestination(R.id.notificationSampleFragment) 47 | .setArguments(args) 48 | .createPendingIntent() 49 | 50 | val notificationManager = 51 | context?.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager 52 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 53 | notificationManager.createNotificationChannel( 54 | NotificationChannel( 55 | "deeplink", "Deep Links", NotificationManager.IMPORTANCE_HIGH) 56 | ) 57 | } 58 | 59 | val builder = NotificationCompat.Builder( 60 | context!!, "deeplink") 61 | .setContentTitle(resources.getString(R.string.app_name)) 62 | .setContentText("Navigation 深层链接测试") 63 | .setSmallIcon(R.mipmap.jetpack) 64 | .setContentIntent(deep) 65 | .setAutoCancel(true) 66 | notificationManager.notify(0, builder.build()) 67 | 68 | requireActivity().snackBarShow(view,getString(R.string.deeplink_hint)) 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/other/WebFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.other 2 | 3 | import android.os.Bundle 4 | import android.view.* 5 | import android.widget.LinearLayout 6 | import androidx.fragment.app.Fragment 7 | import androidx.navigation.fragment.navArgs 8 | import com.hankkin.jetpack_note.R 9 | import com.hankkin.jetpack_note.widget.CoolIndicatorLayout 10 | import com.hankkin.jetpack_note.databinding.FragmentWebBinding 11 | import com.hankkin.jetpack_note.ext.clipTxt 12 | import com.hankkin.jetpack_note.ext.snackBarShow 13 | import com.hankkin.jetpack_note.utils.CommonUtils 14 | import com.just.agentweb.AgentWeb 15 | import com.just.agentweb.AgentWebSettingsImpl 16 | import com.just.agentweb.DefaultWebClient 17 | import kotlinx.android.synthetic.main.activity_main.* 18 | 19 | class WebFragment : Fragment() { 20 | 21 | private val args: WebFragmentArgs by navArgs() 22 | private lateinit var mAgentWeb: AgentWeb 23 | private lateinit var binding: FragmentWebBinding 24 | 25 | 26 | override fun onCreateView( 27 | inflater: LayoutInflater, 28 | container: ViewGroup?, 29 | savedInstanceState: Bundle? 30 | ): View? { 31 | setHasOptionsMenu(true) 32 | binding = FragmentWebBinding.inflate(inflater, container, false) 33 | requireActivity().toolbar.title = args.title 34 | return binding.root 35 | } 36 | 37 | override fun onActivityCreated(savedInstanceState: Bundle?) { 38 | super.onActivityCreated(savedInstanceState) 39 | initWeb() 40 | } 41 | 42 | private fun initWeb() { 43 | mAgentWeb = AgentWeb.with(this) 44 | .setAgentWebParent(binding.webView, LinearLayout.LayoutParams(-1, -1)) 45 | .setCustomIndicator(CoolIndicatorLayout(context)) 46 | .setAgentWebWebSettings(AgentWebSettingsImpl.getInstance()) 47 | .setSecurityType(AgentWeb.SecurityType.STRICT_CHECK) 48 | .interceptUnkownUrl() 49 | .setOpenOtherPageWays(DefaultWebClient.OpenOtherPageWays.ASK) 50 | .createAgentWeb() 51 | .go(args.link) 52 | } 53 | 54 | override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) { 55 | inflater.inflate(R.menu.web_menu, menu) 56 | menu.findItem(R.id.action_settings).isVisible = false 57 | super.onCreateOptionsMenu(menu, inflater) 58 | } 59 | 60 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 61 | when (item.itemId) { 62 | R.id.action_share -> CommonUtils.share(requireActivity(), args.link) 63 | R.id.action_website -> CommonUtils.openBrowser(requireActivity(), args.link) 64 | R.id.action_copy -> { 65 | requireActivity().clipTxt(args.link) 66 | requireActivity().snackBarShow(binding.llCommonWeb, getString(R.string.clip_hint)) 67 | } 68 | else -> { 69 | return false 70 | } 71 | } 72 | return super.onOptionsItemSelected(item) 73 | } 74 | 75 | 76 | override fun onDestroy() { 77 | super.onDestroy() 78 | mAgentWeb.webLifeCycle.onDestroy() 79 | } 80 | 81 | override fun onResume() { 82 | super.onResume() 83 | mAgentWeb.webLifeCycle.onResume() 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/paging/PagingDemoFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.paging 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import androidx.fragment.app.Fragment 8 | import androidx.navigation.Navigation 9 | import androidx.navigation.fragment.findNavController 10 | import com.hankkin.jetpack_note.R 11 | import kotlinx.android.synthetic.main.paging_demo_fragment.* 12 | 13 | class PagingDemoFragment : Fragment() { 14 | 15 | companion object { 16 | fun newInstance() = PagingDemoFragment() 17 | } 18 | 19 | 20 | override fun onCreateView( 21 | inflater: LayoutInflater, container: ViewGroup?, 22 | savedInstanceState: Bundle? 23 | ): View? { 24 | return inflater.inflate(R.layout.paging_demo_fragment, container, false) 25 | } 26 | 27 | override fun onActivityCreated(savedInstanceState: Bundle?) { 28 | super.onActivityCreated(savedInstanceState) 29 | btn_paging_dao.setOnClickListener { findNavController().navigate(R.id.pagingWithDaoActivity) } 30 | btn_paging_net.setOnClickListener { findNavController().navigate(R.id.pagingWithNetWorkActivity) } 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/paging/PagingWithDaoActivity.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.paging 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import android.view.MenuItem 6 | import androidx.lifecycle.Observer 7 | import androidx.lifecycle.ViewModelProviders 8 | import com.hankkin.jetpack_note.R 9 | import com.hankkin.jetpack_note.ext.obtainViewModel 10 | import com.hankkin.jetpack_note.ext.setLightMode 11 | import com.hankkin.jetpack_note.ext.setupToolBar 12 | import com.hankkin.jetpack_note.ui.adapter.PagingDemoAdapter 13 | import kotlinx.android.synthetic.main.activity_paging_with_dao.* 14 | import kotlinx.android.synthetic.main.layout_toolbar.* 15 | 16 | class PagingWithDaoActivity : AppCompatActivity() { 17 | 18 | private lateinit var viewModel: PagingWithDaoViewModel 19 | 20 | override fun onCreate(savedInstanceState: Bundle?) { 21 | super.onCreate(savedInstanceState) 22 | setContentView(R.layout.activity_paging_with_dao) 23 | setLightMode() 24 | setupToolBar(toolbar) { 25 | title = resources.getString(R.string.paging_with_dao) 26 | setDisplayHomeAsUpEnabled(true) 27 | } 28 | viewModel = obtainViewModel(PagingWithDaoViewModel::class.java) 29 | val adapter = PagingDemoAdapter() 30 | rv_paging.adapter = adapter 31 | viewModel.allUsers.observe(this, Observer(adapter::submitList)) 32 | } 33 | 34 | 35 | override fun onOptionsItemSelected(item: MenuItem?): Boolean { 36 | when (item?.itemId) { 37 | android.R.id.home -> finish() 38 | } 39 | return super.onOptionsItemSelected(item) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/paging/PagingWithDaoViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.paging 2 | 3 | import androidx.lifecycle.ViewModel 4 | import com.hankkin.jetpack_note.data.respository.PagingRespository 5 | import com.hankkin.jetpack_note.data.bean.User 6 | 7 | class PagingWithDaoViewModel internal constructor(private val pagingRespository: PagingRespository) : ViewModel() { 8 | 9 | val allUsers = pagingRespository.getAllUsers() 10 | 11 | fun insert(text: CharSequence) { 12 | pagingRespository.insert(text) 13 | } 14 | 15 | fun remove(user: User) { 16 | pagingRespository.remove(user) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/paging/PagingWithNetWorkActivity.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.paging 2 | 3 | import androidx.appcompat.app.AppCompatActivity 4 | import android.os.Bundle 5 | import android.view.MenuItem 6 | import androidx.databinding.DataBindingUtil 7 | import androidx.lifecycle.Observer 8 | import com.hankkin.jetpack_note.R 9 | import com.hankkin.jetpack_note.data.NetworkState 10 | import com.hankkin.jetpack_note.databinding.ActivityPagingWithNetWorkBinding 11 | import com.hankkin.jetpack_note.ext.obtainViewModel 12 | import com.hankkin.jetpack_note.ext.setLightMode 13 | import com.hankkin.jetpack_note.ext.setupToolBar 14 | import com.hankkin.jetpack_note.ui.adapter.PagingWithNetWorkAdapter 15 | import kotlinx.android.synthetic.main.layout_toolbar.* 16 | 17 | class PagingWithNetWorkActivity : AppCompatActivity() { 18 | 19 | private lateinit var mViewModel: PagingWithNetWorkViewModel 20 | private lateinit var mDataBinding: ActivityPagingWithNetWorkBinding 21 | 22 | override fun onCreate(savedInstanceState: Bundle?) { 23 | super.onCreate(savedInstanceState) 24 | mDataBinding = DataBindingUtil.setContentView(this,R.layout.activity_paging_with_net_work) 25 | setLightMode() 26 | setupToolBar(toolbar) { 27 | title = resources.getString(R.string.paging_with_network) 28 | setDisplayHomeAsUpEnabled(true) 29 | } 30 | mViewModel = obtainViewModel(PagingWithNetWorkViewModel::class.java) 31 | mDataBinding.vm = mViewModel 32 | mDataBinding.lifecycleOwner = this 33 | 34 | val adapter = PagingWithNetWorkAdapter() 35 | mDataBinding.rvPagingWithNetwork.adapter = adapter 36 | mDataBinding.vm?.gankList?.observe(this, Observer { adapter.submitList(it) }) 37 | mDataBinding.vm?.refreshState?.observe(this, Observer { 38 | mDataBinding.rvPagingWithNetwork.post { 39 | mDataBinding.swipeRefresh.isRefreshing = it == NetworkState.LOADING 40 | } 41 | }) 42 | 43 | mDataBinding.vm?.netWorkState?.observe(this, Observer { 44 | adapter.setNetworkState(it) 45 | }) 46 | } 47 | 48 | override fun onOptionsItemSelected(item: MenuItem?): Boolean { 49 | when (item?.itemId) { 50 | android.R.id.home -> finish() 51 | } 52 | return super.onOptionsItemSelected(item) 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/paging/PagingWithNetWorkViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.paging 2 | 3 | import androidx.lifecycle.ViewModel 4 | import com.hankkin.jetpack_note.data.respository.gank.GankRespository 5 | 6 | /** 7 | * created by Hankkin 8 | * on 2019-07-30 9 | */ 10 | class PagingWithNetWorkViewModel( 11 | private val gankRespository: GankRespository 12 | ) : ViewModel() { 13 | 14 | private val mData = gankRespository.getGank() 15 | 16 | val gankList = mData.pagedList 17 | 18 | val netWorkState = mData.networkState 19 | 20 | val refreshState = mData.refreshState 21 | 22 | fun refresh() { 23 | mData.refresh.invoke() 24 | } 25 | 26 | fun retry() { 27 | mData.retry.invoke() 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/viewmodel/DataShareFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.viewmodel 2 | 3 | 4 | import android.os.Bundle 5 | import android.view.LayoutInflater 6 | import android.view.View 7 | import android.view.ViewGroup 8 | import android.widget.SeekBar 9 | import androidx.fragment.app.Fragment 10 | import androidx.lifecycle.Observer 11 | import androidx.lifecycle.ViewModelProviders 12 | import com.hankkin.jetpack_note.R 13 | import kotlinx.android.synthetic.main.fragment_data_share.* 14 | 15 | 16 | /** 17 | * DataShare 18 | */ 19 | class DataShareFragment : Fragment() { 20 | 21 | private lateinit var mViewModel: DemoViewModel 22 | 23 | override fun onCreateView( 24 | inflater: LayoutInflater, container: ViewGroup?, 25 | savedInstanceState: Bundle? 26 | ): View? { 27 | mViewModel = ViewModelProviders.of(activity!!).get(DemoViewModel::class.java) 28 | return inflater.inflate(R.layout.fragment_data_share, container, false) 29 | } 30 | 31 | 32 | override fun onActivityCreated(savedInstanceState: Bundle?) { 33 | super.onActivityCreated(savedInstanceState) 34 | subscribeSeekBar() 35 | } 36 | 37 | private fun subscribeSeekBar() { 38 | // 监听SeekBar改变ViewModel的中的值 39 | seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { 40 | override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) { 41 | if (fromUser) { 42 | mViewModel.seekbarValue.value = progress 43 | } 44 | } 45 | 46 | override fun onStartTrackingTouch(seekBar: SeekBar) {} 47 | 48 | override fun onStopTrackingTouch(seekBar: SeekBar) {} 49 | }) 50 | // 当ViewModel中的值发生变化时,更新SeekBar 51 | activity?.let { 52 | mViewModel.seekbarValue.observe(it, Observer { value -> 53 | if (value != null) { 54 | seekBar.progress = value 55 | } 56 | }) 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/viewmodel/DemoViewModel.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.viewmodel 2 | 3 | import androidx.lifecycle.MutableLiveData 4 | import androidx.lifecycle.ViewModel 5 | 6 | /** 7 | * created by ${Hankkin} 8 | * on 2019-06-17 9 | */ 10 | 11 | class DemoViewModel : ViewModel() { 12 | 13 | var time: Long? = null 14 | 15 | var seekbarValue = MutableLiveData() 16 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/viewmodel/ViewModelFragment.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.viewmodel 2 | 3 | 4 | import android.os.Bundle 5 | import android.os.SystemClock 6 | import android.view.LayoutInflater 7 | import android.view.View 8 | import android.view.ViewGroup 9 | import androidx.fragment.app.Fragment 10 | import androidx.lifecycle.ViewModelProviders 11 | import androidx.navigation.fragment.findNavController 12 | import com.hankkin.jetpack_note.R 13 | import kotlinx.android.synthetic.main.fragment_view_model.* 14 | 15 | /** 16 | *ViewModel 17 | */ 18 | class ViewModelFragment : Fragment() { 19 | 20 | override fun onCreateView( 21 | inflater: LayoutInflater, container: ViewGroup?, 22 | savedInstanceState: Bundle? 23 | ): View? { 24 | return inflater.inflate(R.layout.fragment_view_model, container, false) 25 | } 26 | 27 | 28 | override fun onActivityCreated(savedInstanceState: Bundle?) { 29 | super.onActivityCreated(savedInstanceState) 30 | val vm = ViewModelProviders.of(this).get(DemoViewModel::class.java) 31 | if (vm.time == null) { 32 | vm.time = SystemClock.elapsedRealtime() 33 | } 34 | chronometer.base = vm.time!! 35 | chronometer.start() 36 | 37 | btn_fragment_share.setOnClickListener { 38 | findNavController().navigate(R.id.viewModelShareActivity) 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/ui/viewmodel/ViewModelShareActivity.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.ui.viewmodel 2 | 3 | import android.os.Bundle 4 | import android.view.MenuItem 5 | import androidx.appcompat.app.AppCompatActivity 6 | import com.hankkin.jetpack_note.R 7 | import com.hankkin.jetpack_note.ext.setLightMode 8 | import com.hankkin.jetpack_note.ext.setupToolBar 9 | import com.hankkin.jetpack_note.utils.StatusBarUtil 10 | import kotlinx.android.synthetic.main.activity_view_model_share.* 11 | 12 | class ViewModelShareActivity : AppCompatActivity() { 13 | 14 | override fun onCreate(savedInstanceState: Bundle?) { 15 | super.onCreate(savedInstanceState) 16 | setContentView(R.layout.activity_view_model_share) 17 | setLightMode() 18 | setupToolBar(toolbar) { 19 | setDisplayHomeAsUpEnabled(true) 20 | } 21 | } 22 | 23 | override fun onOptionsItemSelected(item: MenuItem?): Boolean { 24 | when (item?.itemId) { 25 | android.R.id.home -> finish() 26 | } 27 | return super.onOptionsItemSelected(item) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/utils/AppUtils.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.utils 2 | 3 | import android.content.Context 4 | import android.content.pm.ApplicationInfo 5 | 6 | 7 | object AppUtils{ 8 | 9 | /** 10 | * 获取应用程序名称 11 | */ 12 | @Synchronized 13 | fun getAppName(context: Context): String? { 14 | try { 15 | val packageManager = context.getPackageManager() 16 | val packageInfo = packageManager.getPackageInfo( 17 | context.getPackageName(), 0) 18 | val labelRes = packageInfo.applicationInfo.labelRes 19 | return context.getResources().getString(labelRes) 20 | } catch (e: Exception) { 21 | e.printStackTrace() 22 | } 23 | 24 | return null 25 | } 26 | 27 | /** 28 | * [获取应用程序版本名称信息] 29 | * @param context 30 | * @return 当前应用的版本名称 31 | */ 32 | @Synchronized 33 | fun getVersionName(context: Context): String? { 34 | try { 35 | val packageManager = context.getPackageManager() 36 | val packageInfo = packageManager.getPackageInfo( 37 | context.getPackageName(), 0) 38 | return packageInfo.versionName 39 | } catch (e: Exception) { 40 | e.printStackTrace() 41 | } 42 | 43 | return null 44 | } 45 | 46 | 47 | /** 48 | * [获取应用程序版本名称信息] 49 | * @param context 50 | * @return 当前应用的版本名称 51 | */ 52 | @Synchronized 53 | fun getVersionCode(context: Context): Int { 54 | try { 55 | val packageManager = context.getPackageManager() 56 | val packageInfo = packageManager.getPackageInfo( 57 | context.getPackageName(), 0) 58 | return packageInfo.versionCode 59 | } catch (e: Exception) { 60 | e.printStackTrace() 61 | } 62 | 63 | return 0 64 | } 65 | 66 | 67 | /** 68 | * [获取应用程序版本名称信息] 69 | * @param context 70 | * @return 当前应用的版本名称 71 | */ 72 | @Synchronized 73 | fun getPackageName(context: Context): String? { 74 | try { 75 | val packageManager = context.getPackageManager() 76 | val packageInfo = packageManager.getPackageInfo( 77 | context.getPackageName(), 0) 78 | return packageInfo.packageName 79 | } catch (e: Exception) { 80 | e.printStackTrace() 81 | } 82 | 83 | return null 84 | } 85 | 86 | 87 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/utils/CommonUtils.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.utils 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.content.Intent 6 | import android.content.pm.ApplicationInfo 7 | import android.content.pm.PackageManager 8 | import android.net.Uri 9 | import android.widget.Toast 10 | import java.util.* 11 | 12 | 13 | object CommonUtils { 14 | 15 | fun share(context: Activity, text: String) { 16 | val intent = Intent(Intent.ACTION_SEND) 17 | intent.type = "text/plain" 18 | intent.putExtra(Intent.EXTRA_TEXT, text) 19 | context.startActivity(intent) 20 | } 21 | 22 | fun openBrowser(context: Activity, url: String) { 23 | val intent = Intent() 24 | intent.action = "android.intent.action.VIEW" 25 | val mUri = Uri.parse(url) 26 | intent.data = mUri 27 | context.startActivity(intent) 28 | } 29 | 30 | fun openBroswer(context: Activity, url: String) { 31 | val intent = Intent() 32 | intent.setAction("android.intent.action.VIEW") 33 | intent.setData(Uri.parse(url)) 34 | context.startActivity(intent) 35 | } 36 | 37 | fun feedBack(context: Activity) { 38 | val intent = Intent(Intent.ACTION_SEND) 39 | intent.type = "message/rfc822" 40 | intent.putExtra(Intent.EXTRA_EMAIL, "1019283569@qq.com") 41 | intent.putExtra(Intent.EXTRA_SUBJECT, "您的建议") 42 | intent.putExtra(Intent.EXTRA_TEXT, "希望能得到您的建议") 43 | context.startActivity(Intent.createChooser(intent, "Select email application")) 44 | } 45 | 46 | fun gradeApp(context: Context) { 47 | try { 48 | val uri = Uri.parse("market://details?id=${context.packageName}") 49 | val intent = Intent(Intent(Intent.ACTION_VIEW, uri)) 50 | intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) 51 | context.startActivity(intent) 52 | } catch (e: Exception) { 53 | Toast.makeText(context,"您的手机还没有安装任何安装安装应用市场",Toast.LENGTH_SHORT).show() 54 | } 55 | } 56 | 57 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/utils/Constants.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Google LLC 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package com.hankkin.jetpack_note.utils 18 | 19 | /** 20 | * Constants used throughout the app. 21 | */ 22 | object Constants { 23 | const val DATABASE_NAME = "JetpackNote-db" 24 | const val COMPONENT_DATA_FILENAME = "component.json" 25 | 26 | object AboutUrl { 27 | const val JETPACK = "https://github.com/Hankkin/JetPack_Note" 28 | const val JETPACK_TITLE = "JetPack_Note" 29 | const val GITHUB = "https://github.com/Hankkin" 30 | const val GITHUB_TITLE = "Github" 31 | const val JUEJIN = "https://juejin.im/user/55dea68160b291d79422c1bb" 32 | const val JUEJIN_TITLE = "稀土掘金" 33 | const val JIANSHU = "https://www.jianshu.com/u/1ff65e347973" 34 | const val JIANSHU_TITLE = "简书" 35 | const val CSDN = "https://blog.csdn.net/lyhhj" 36 | const val CSDN_TITLE = "CSDN" 37 | const val BLOG = "http://hankkin.club" 38 | const val BLOG_TITLE = "博客" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/utils/Injection.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.utils 2 | 3 | import android.content.Context 4 | import com.hankkin.jetpack_note.data.db.HomeDB 5 | import com.hankkin.jetpack_note.data.respository.HomeRepository 6 | import com.hankkin.jetpack_note.data.respository.PagingRespository 7 | import com.hankkin.jetpack_note.data.db.UserDB 8 | import com.hankkin.jetpack_note.data.net.Api 9 | import com.hankkin.jetpack_note.data.net.HttpClient 10 | import com.hankkin.jetpack_note.data.respository.gank.GankRespository 11 | 12 | /** 13 | * @author Hankkin 14 | * @date 2019-05-30 15 | */ 16 | object Injection { 17 | 18 | 19 | fun provideHomeRepository(context: Context) = 20 | HomeRepository.getInstance( 21 | HomeDB.getInstance(context.applicationContext).homeDao() 22 | ) 23 | 24 | fun providePagingRepository(context: Context) = 25 | PagingRespository.getInstance( 26 | UserDB.get(context.applicationContext).userDao() 27 | ) 28 | 29 | fun provideGankRespository() = GankRespository.getInstance() 30 | 31 | fun provideApi(): Api = HttpClient.instance 32 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/utils/ViewHelper.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.utils 2 | 3 | import android.content.Context 4 | import android.view.LayoutInflater 5 | import android.widget.ImageView 6 | import android.widget.TextView 7 | import com.google.android.material.bottomsheet.BottomSheetDialog 8 | import com.hankkin.jetpack_note.R 9 | import com.hankkin.jetpack_note.ui.other.CommonWebActivity 10 | 11 | /** 12 | * created by Hankkin 13 | * on 2019-07-31 14 | */ 15 | object ViewHelper { 16 | /** 17 | * about dialog 18 | */ 19 | fun showAboutDialog(context: Context): Boolean { 20 | LayoutInflater.from(context).inflate(R.layout.layout_about_dialog, null) 21 | .apply { 22 | findViewById(R.id.tv_about_version_code).setText(AppUtils.getVersionName(context)) 23 | findViewById(R.id.iv_about_github).setOnClickListener { CommonWebActivity.loadUrl(context, Constants.AboutUrl.GITHUB, Constants.AboutUrl.GITHUB_TITLE) } 24 | findViewById(R.id.iv_about_juejin).setOnClickListener { CommonWebActivity.loadUrl(context, Constants.AboutUrl.JUEJIN, Constants.AboutUrl.JUEJIN_TITLE) } 25 | findViewById(R.id.iv_about_jianshu).setOnClickListener { CommonWebActivity.loadUrl(context, Constants.AboutUrl.JIANSHU, Constants.AboutUrl.JIANSHU_TITLE) } 26 | findViewById(R.id.iv_about_csdn).setOnClickListener { CommonWebActivity.loadUrl(context, Constants.AboutUrl.CSDN, Constants.AboutUrl.CSDN_TITLE) } 27 | val bottomSheet = BottomSheetDialog(context, R.style.BottomSheetDialog) 28 | findViewById(R.id.tv_about_close).setOnClickListener { bottomSheet.dismiss() } 29 | findViewById(R.id.tv_about_rate).setOnClickListener { CommonUtils.gradeApp(context) } 30 | bottomSheet.setContentView(this) 31 | bottomSheet.show() 32 | } 33 | return false 34 | } 35 | } -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/widget/CoolIndicatorLayout.java: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | * Copyright (C) Justson(https://github.com/Justson/AgentWeb) 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | package com.hankkin.jetpack_note.widget; 19 | 20 | import android.app.Activity; 21 | import android.content.Context; 22 | import android.os.Build; 23 | import android.util.AttributeSet; 24 | import android.view.View; 25 | import androidx.annotation.Nullable; 26 | import com.hankkin.jetpack_note.R; 27 | import com.just.agentweb.AgentWebUtils; 28 | import com.just.agentweb.BaseIndicatorView; 29 | 30 | /** 31 | * @author cenxiaozhong 32 | * @date 2018/2/23 33 | * @since 1.0.0 34 | */ 35 | public class CoolIndicatorLayout extends BaseIndicatorView { 36 | 37 | 38 | private static final String TAG = CoolIndicatorLayout.class.getSimpleName(); 39 | private CoolIndicator mCoolIndicator = null; 40 | 41 | 42 | public CoolIndicatorLayout(Context context) { 43 | this(context, null); 44 | } 45 | 46 | public CoolIndicatorLayout(Context context, @Nullable AttributeSet attrs) { 47 | this(context, attrs, -1); 48 | } 49 | 50 | public CoolIndicatorLayout(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { 51 | super(context, attrs, defStyleAttr); 52 | mCoolIndicator = CoolIndicator.create((Activity) context); 53 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 54 | mCoolIndicator.setProgressDrawable(context.getResources().getDrawable(R.drawable.default_drawable_indicator, context.getTheme())); 55 | } else { 56 | mCoolIndicator.setProgressDrawable(context.getResources().getDrawable(R.drawable.default_drawable_indicator)); 57 | } 58 | 59 | this.addView(mCoolIndicator, offerLayoutParams()); 60 | 61 | } 62 | 63 | @Override 64 | public void show() { 65 | this.setVisibility(View.VISIBLE); 66 | mCoolIndicator.start(); 67 | } 68 | 69 | @Override 70 | public void setProgress(int newProgress) { 71 | } 72 | 73 | @Override 74 | public void hide() { 75 | mCoolIndicator.complete(); 76 | } 77 | 78 | @Override 79 | public LayoutParams offerLayoutParams() { 80 | return new LayoutParams(-1, AgentWebUtils.dp2px(getContext(), 3)); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /app/src/main/java/com/hankkin/jetpack_note/workers/SeedDatabaseWorker.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note.workers 2 | 3 | import android.content.Context 4 | import android.util.Log 5 | import androidx.work.CoroutineWorker 6 | import androidx.work.WorkerParameters 7 | import com.google.gson.Gson 8 | import com.google.gson.reflect.TypeToken 9 | import com.google.gson.stream.JsonReader 10 | import com.hankkin.jetpack_note.data.bean.Component 11 | import com.hankkin.jetpack_note.data.db.HomeDB 12 | import com.hankkin.jetpack_note.utils.Constants.COMPONENT_DATA_FILENAME 13 | import kotlinx.coroutines.coroutineScope 14 | 15 | /** 16 | * @author Hankkin 17 | * @date 2019-05-30 18 | */ 19 | class SeedDatabaseWorker ( 20 | context: Context, 21 | workerParams: WorkerParameters 22 | ): CoroutineWorker(context, workerParams) { 23 | 24 | private val TAG by lazy { SeedDatabaseWorker::class.java.simpleName } 25 | 26 | override suspend fun doWork(): Result = coroutineScope { 27 | 28 | try { 29 | applicationContext.assets.open(COMPONENT_DATA_FILENAME).use { inputStream -> 30 | JsonReader(inputStream.reader()).use { jsonReader -> 31 | val plantType = object : TypeToken>() {}.type 32 | val plantList: List = Gson().fromJson(jsonReader,plantType) 33 | val database = HomeDB.getInstance(applicationContext) 34 | database.homeDao().insertAll(plantList) 35 | 36 | Result.success() 37 | } 38 | } 39 | } catch (ex: Exception) { 40 | Log.e(TAG, "Error seeding database", ex) 41 | Result.failure() 42 | } 43 | } 44 | } -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_in_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_left.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/anim/slide_out_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/color/nav_item_icon.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/color/nav_item_txt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_camera.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_gallery.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_manage.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_send.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_share.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v21/ic_menu_slideshow.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bottom_sheet_bg.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_shadow.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_theme.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | 11 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/default_drawable_indicator.xml: -------------------------------------------------------------------------------- 1 | 2 | 25 | 26 | 27 | 28 | 32 | 33 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_add.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_baseline_remove.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_dashboard_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_home_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_notifications_black_24dp.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/laptop.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/drawable/laptop.jpeg -------------------------------------------------------------------------------- /app/src/main/res/drawable/rectangle.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/seekbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_article_detail.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 15 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_bottom_nav_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | 20 | 21 | 29 | 30 | 31 | 32 | 33 | 41 | 42 | 50 | 51 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 13 | 18 | 22 | 23 | 30 | 31 | 32 | 33 | 40 | 41 | 42 | 52 | 53 | 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_more_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_nav_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 16 | 17 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_paging_with_dao.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | 15 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_paging_with_net_work.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 18 | 19 | 20 | 21 | 22 | 27 | 28 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_view_model_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 20 | 21 | 27 | 28 | 29 | 34 | 41 | 42 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 61 | 62 | 68 | 69 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_paging_item.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 15 | 25 | 26 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_paging_with_network_item.xml: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 10 | 13 | 14 | 15 | 16 | 22 | 35 | 36 | 39 | 45 | 52 | 53 | 54 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /app/src/main/res/layout/app_bar_nav_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 22 | 23 | 24 | 25 | 29 | 30 | 31 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/content_nav_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 20 | 21 | 33 | 34 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_code.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_data_share.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 14 | 15 | 23 | 24 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_more_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 20 | 21 | 22 | 23 | 24 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_navigation.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 14 | 15 | 16 | 27 | 28 | 37 | 38 | 48 | 49 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_sample_args.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | 26 | 27 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_sample_dashboard.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | 26 | 27 | 36 | 37 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_sample_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | 25 | 35 | 36 | 47 | 48 | 59 | 60 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_sample_notification.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 16 | 23 | 24 | 31 | 32 | 40 | 41 | 49 | 50 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_setting.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 14 | 15 | 24 | 29 | 30 | 36 | 37 | 38 | 42 | 43 | 52 | 57 | 58 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 9 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_rv_home_header.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/layout/layout_toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/layout/list_item_home.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 9 | 12 | 13 | 14 | 25 | 26 | 36 | 37 | 43 | 49 | 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /app/src/main/res/layout/nav_header_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 21 | 22 | 30 | 31 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/nav_header_nav_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 23 | 24 | 31 | 32 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /app/src/main/res/layout/paging_demo_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 16 | 17 | 26 | 27 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/menu/activity_main_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 |

5 | 6 | 7 | 11 | 12 | 16 | 17 | 21 | 22 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | 39 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /app/src/main/res/menu/activity_nav_sample_drawer.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 11 | 15 | 19 | 23 | 24 | 25 | 26 | 27 | 31 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/menu/article_detail_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/menu/bottom_nav_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/menu/nav_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/menu/web_menu.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/about_csdn.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/about_csdn.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/about_github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/about_github.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/about_jianshu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/about_jianshu.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/about_juejin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/about_juejin.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/back.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/back.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_args.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_args.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_jump.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_jump.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_lifecycles.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_lifecycles.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_livedata.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_livedata.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_navigation.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_navigation.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_notification.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_notification.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_paging.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_paging.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_sample_drawerlayout.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_sample_drawerlayout.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/bg_work.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/bg_work.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/close.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/icon_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/icon_grid.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/icon_lin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/icon_lin.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/jetpack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/jetpack.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/jetpack_donut.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/jetpack_donut.webp -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_about.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_circle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_circle.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_home.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_know.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_know.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_more.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_more.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_nav.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_nav.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/menu_set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xhdpi/menu_set.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/navigation/navigation_bottom_sample.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | 13 | 14 | 16 | 17 | 23 | 24 | 26 | 27 | 28 | 29 | 30 | 34 | 35 | 37 | 38 | 39 | 40 | 44 | 45 | 48 | 49 | 52 | 53 | 56 | 57 | 59 | 60 | 61 | 65 | 66 | 68 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/values/anim.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 200 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | #FFFFFF 4 | #FFFFFF 5 | #057FFF 6 | #057FFF 7 | 8 | 9 | #FFFFFF 10 | #000000 11 | #424242 12 | #757575 13 | #fafafa 14 | #dddddd 15 | #f75acb 16 | #1ae8ff 17 | 18 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 8dp 6 | 176dp 7 | 16dp 8 | 9 | 2dp 10 | 4dp 11 | 6dp 12 | 8dp 13 | 10dp 14 | 12dp 15 | 14dp 16 | 16dp 17 | 18dp 18 | 20dp 19 | 22dp 20 | 24dp 21 | -------------------------------------------------------------------------------- /app/src/main/res/values/drawables.xml: -------------------------------------------------------------------------------- 1 | 2 | @mipmap/menu_home 3 | @mipmap/menu_nav 4 | @mipmap/menu_know 5 | @mipmap/menu_circle 6 | @mipmap/menu_more 7 | @mipmap/menu_set 8 | @mipmap/menu_about 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | 22 | 23 | 28 | 29 | 30 | 34 | 35 | 39 | 40 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /app/src/main/res/values/textsize.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8sp 4 | 10sp 5 | 12sp 6 | 14sp 7 | 16sp 8 | 18sp 9 | 20sp 10 | 22sp 11 | -------------------------------------------------------------------------------- /app/src/main/res/xml/provider_paths.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/test/java/com/hankkin/jetpack_note/ExampleUnitTest.kt: -------------------------------------------------------------------------------- 1 | package com.hankkin.jetpack_note 2 | 3 | import org.junit.Test 4 | 5 | import org.junit.Assert.* 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * See [testing documentation](http://d.android.com/tools/testing). 11 | */ 12 | class ExampleUnitTest { 13 | @Test 14 | fun addition_isCorrect() { 15 | assertEquals(4, 2 + 2) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | ext { 5 | // Sdk and tools 6 | compileSdkVersion = 28 7 | minSdkVersion = 19 8 | targetSdkVersion = 28 9 | versionCode = 101 10 | versionName = "1.0.1" 11 | 12 | kotlinVersion = '1.3.31' 13 | gradleVersion = '3.4.1' 14 | 15 | lifecycleVersion = '2.2.0-alpha01' 16 | navigationVersion = '2.0.0' 17 | materialVersion = '1.0.0' 18 | roomVersion = '2.1.0-beta01' 19 | workVersion = '2.1.0-alpha02' 20 | paging_version = "2.1.0" 21 | gsonVersion = '2.8.2' 22 | fragmentVersion = '1.1.0-alpha09' 23 | viewPager2Version = '1.0.0-alpha05' 24 | agentWebVersion = '4.0.2' 25 | retrofitVersion = '2.5.0' 26 | okhttpLoggingInterceptorVersion = "3.9.0" 27 | 28 | supportLibraryVersion = '1.1.0-alpha05' 29 | constraintLayoutVersion = '2.0.0-beta1' 30 | 31 | junitVersion = '4.12' 32 | espressoVersion = '3.1.1' 33 | } 34 | repositories { 35 | maven { url 'https://jitpack.io' } 36 | maven { url 'https://maven.fabric.io/public' } 37 | google() 38 | jcenter() 39 | } 40 | dependencies { 41 | classpath "com.android.tools.build:gradle:${gradleVersion}" 42 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion" 43 | classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion" 44 | } 45 | } 46 | 47 | allprojects { 48 | repositories { 49 | maven { url 'https://jitpack.io' } 50 | maven { url 'https://maven.fabric.io/public' } 51 | google() 52 | jcenter() 53 | } 54 | } 55 | 56 | task clean(type: Delete) { 57 | delete rootProject.buildDir 58 | } 59 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | # IDE (e.g. Android Studio) users: 3 | # Gradle settings configured through the IDE *will override* 4 | # any settings specified in this file. 5 | # For more details on how to configure your build environment visit 6 | # http://www.gradle.org/docs/current/userguide/build_environment.html 7 | # Specifies the JVM arguments used for the daemon process. 8 | # The setting is particularly useful for tweaking memory settings. 9 | org.gradle.jvmargs=-Xmx1536m 10 | # When configured, Gradle will run in incubating parallel mode. 11 | # This option should only be used with decoupled projects. More details, visit 12 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 13 | # org.gradle.parallel=true 14 | # AndroidX package structure to make it clearer which packages are bundled with the 15 | # Android operating system, and which are packaged with your app's APK 16 | # https://developer.android.com/topic/libraries/support-library/androidx-rn 17 | android.useAndroidX=true 18 | # Automatically convert third-party libraries to use AndroidX 19 | android.enableJetifier=true 20 | # Kotlin code style for this project: "official" or "obsolete": 21 | kotlin.code.style=official 22 | #jetpack 23 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hankkin/JetPack_Note/769e41c237509b43cad32cc774961a7c3961602d/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Thu May 30 09:47:35 CST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip 7 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | --------------------------------------------------------------------------------