From d3a31d91a1a6989074855bfc7405edb35d2da668 Mon Sep 17 00:00:00 2001 From: TimChen Date: Sun, 11 Sep 2022 15:25:56 +0800 Subject: [PATCH 01/33] Reduce warnings --- .idea/misc.xml | 1 + .../associate/training/canvas/view/CanvasListFragment.kt | 6 +++--- .../com/example/associate/training/dummy/DummyRepository.kt | 2 +- .../training/lifecycle/aware/LiveDataTimerViewModel.java | 4 ++-- .../training/lifecycle/aware/LocationActivity.java | 2 +- .../training/lifecycle/aware/SavedStateViewModel.java | 2 +- app/src/main/res/layout/activity_chrono_3.xml | 1 - app/src/main/res/layout/activity_main.xml | 1 - 8 files changed, 9 insertions(+), 10 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index da4611c..e80f899 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -11,6 +11,7 @@ + diff --git a/app/src/main/java/com/example/associate/training/canvas/view/CanvasListFragment.kt b/app/src/main/java/com/example/associate/training/canvas/view/CanvasListFragment.kt index ec78c3c..c871302 100644 --- a/app/src/main/java/com/example/associate/training/canvas/view/CanvasListFragment.kt +++ b/app/src/main/java/com/example/associate/training/canvas/view/CanvasListFragment.kt @@ -18,7 +18,7 @@ import com.example.associate.training.databinding.ActivityMainBinding class CanvasListFragment : Fragment() { - private lateinit var adapter: TestAdapter + private lateinit var adapter: CanvasListAdapter private lateinit var binding: ActivityMainBinding override fun onViewCreated(view: View, savedInstanceState: Bundle?) { @@ -36,7 +36,7 @@ class CanvasListFragment : Fragment() { } private fun setupAdapter() { - adapter = TestAdapter(CanvasViewType.values().toList(), activity as AppCompatActivity) + adapter = CanvasListAdapter(CanvasViewType.values().toList(), activity as AppCompatActivity) binding.tutorsRecyclerView.layoutManager = LinearLayoutManager(binding.root.context) binding.tutorsRecyclerView.adapter = adapter } @@ -45,7 +45,7 @@ class CanvasListFragment : Fragment() { enum class CanvasViewType { XFERS_MODE, CIRCULAR_AVATAR, SAVE_LAYER, SAVE_RESTORE } -class TestAdapter(private val entries: List, private val activity: AppCompatActivity) : +class CanvasListAdapter(private val entries: List, private val activity: AppCompatActivity) : RecyclerView.Adapter() { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { diff --git a/app/src/main/java/com/example/associate/training/dummy/DummyRepository.kt b/app/src/main/java/com/example/associate/training/dummy/DummyRepository.kt index c73427e..0779d82 100644 --- a/app/src/main/java/com/example/associate/training/dummy/DummyRepository.kt +++ b/app/src/main/java/com/example/associate/training/dummy/DummyRepository.kt @@ -16,7 +16,7 @@ sealed class Result { // Create the repository to fetch the dummy api, and build the response data structure // TODO: Implement the coroutine flow as https://github.com/TouhidApps/Kotlin-Coroutine-Example // -class DummyRepository() { +class DummyRepository { private val loginUrl = "https://dummyapi.io/data/v1/user?limit=10" private val appID = "62adc6ad2aa7570c08535305" // Function that makes the network request, blocking the current thread diff --git a/app/src/main/java/com/example/associate/training/lifecycle/aware/LiveDataTimerViewModel.java b/app/src/main/java/com/example/associate/training/lifecycle/aware/LiveDataTimerViewModel.java index 63e1580..6ea33ca 100644 --- a/app/src/main/java/com/example/associate/training/lifecycle/aware/LiveDataTimerViewModel.java +++ b/app/src/main/java/com/example/associate/training/lifecycle/aware/LiveDataTimerViewModel.java @@ -15,9 +15,9 @@ public class LiveDataTimerViewModel extends ViewModel { private static final int ONE_SECOND = 1000; - private MutableLiveData mElapsedTime = new MutableLiveData<>(); + private final MutableLiveData mElapsedTime = new MutableLiveData<>(); - private long mInitialTime; + private final long mInitialTime; private final Timer timer; public LiveDataTimerViewModel() { diff --git a/app/src/main/java/com/example/associate/training/lifecycle/aware/LocationActivity.java b/app/src/main/java/com/example/associate/training/lifecycle/aware/LocationActivity.java index 922938c..feec080 100644 --- a/app/src/main/java/com/example/associate/training/lifecycle/aware/LocationActivity.java +++ b/app/src/main/java/com/example/associate/training/lifecycle/aware/LocationActivity.java @@ -19,7 +19,7 @@ public class LocationActivity extends AppCompatActivity { private static final int REQUEST_LOCATION_PERMISSION_CODE = 1; - private LocationListener mGpsListener = new MyLocationListener(); + private final LocationListener mGpsListener = new MyLocationListener(); @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, diff --git a/app/src/main/java/com/example/associate/training/lifecycle/aware/SavedStateViewModel.java b/app/src/main/java/com/example/associate/training/lifecycle/aware/SavedStateViewModel.java index 2fcbb8e..e2c5709 100644 --- a/app/src/main/java/com/example/associate/training/lifecycle/aware/SavedStateViewModel.java +++ b/app/src/main/java/com/example/associate/training/lifecycle/aware/SavedStateViewModel.java @@ -24,7 +24,7 @@ public class SavedStateViewModel extends ViewModel { private static final String NAME_KEY = "name"; - private SavedStateHandle mState; + private final SavedStateHandle mState; public SavedStateViewModel(SavedStateHandle savedStateHandle) { mState = savedStateHandle; diff --git a/app/src/main/res/layout/activity_chrono_3.xml b/app/src/main/res/layout/activity_chrono_3.xml index f1baf31..f8111d8 100644 --- a/app/src/main/res/layout/activity_chrono_3.xml +++ b/app/src/main/res/layout/activity_chrono_3.xml @@ -1,6 +1,5 @@ Date: Fri, 16 Sep 2022 15:10:38 +0800 Subject: [PATCH 02/33] Practice the Koin component https://insert-koin.io/docs/quickstart/android-viewmodel --- app/build.gradle | 6 +++ app/src/main/AndroidManifest.xml | 4 ++ .../associate/training/MainActivity.kt | 2 + .../busschedule/BusScheduleApplication.kt | 25 +++++++++++++ .../associate/training/koin/KoinActivity.kt | 37 +++++++++++++++++++ app/src/main/res/layout/activity_blur.xml | 1 - app/src/main/res/layout/activity_koin.xml | 15 ++++++++ 7 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/com/example/associate/training/koin/KoinActivity.kt create mode 100644 app/src/main/res/layout/activity_koin.xml diff --git a/app/build.gradle b/app/build.gradle index 3c20376..a2904ab 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -77,6 +77,9 @@ dependencies { // LiveData implementation "androidx.lifecycle:lifecycle-livedata-ktx:2.3.1" + // Koin for Android + implementation "io.insert-koin:koin-android:3.0.1" + // Testing-only dependencies testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.navigation:navigation-testing:2.4.2' @@ -86,6 +89,9 @@ dependencies { androidTestImplementation "androidx.test.espresso:espresso-core:$espresso_version" androidTestImplementation "androidx.test.espresso:espresso-contrib:$espresso_version" + // Koin Test + testImplementation "io.insert-koin:koin-test:3.0.1" + testImplementation "io.insert-koin:koin-test-junit4:3.0.1" androidTestImplementation 'androidx.navigation:navigation-testing:2.4.2' debugImplementation 'androidx.fragment:fragment-testing:1.4.1' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f3b4f6b..96717cd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -82,6 +82,10 @@ android:name=".pic.PicActivity" android:exported="true"/> + + \ No newline at end of file diff --git a/app/src/main/java/com/example/associate/training/MainActivity.kt b/app/src/main/java/com/example/associate/training/MainActivity.kt index 6aca687..13bf41b 100644 --- a/app/src/main/java/com/example/associate/training/MainActivity.kt +++ b/app/src/main/java/com/example/associate/training/MainActivity.kt @@ -10,6 +10,7 @@ import com.example.associate.training.canvas.CanvasActivity import com.example.associate.training.databinding.ActivityMainBinding import com.example.associate.training.dummy.DummyActivity import com.example.associate.training.inventory.InventoryActivity +import com.example.associate.training.koin.KoinActivity import com.example.associate.training.lifecycle.LifecycleActivity import com.example.associate.training.pic.PicActivity import com.example.associate.training.word.WordActivity @@ -34,6 +35,7 @@ open class MainActivity : AppCompatActivity() { open fun getList(): List { return listOf( + Entry("KoinActivity", KoinActivity::class.java), Entry("CanvasActivity", CanvasActivity::class.java), Entry("ViewsActivity", PicActivity::class.java), Entry("WorkManager", WorkManagerActivity::class.java), diff --git a/app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt b/app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt index ae01c31..1c86951 100644 --- a/app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt +++ b/app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt @@ -18,8 +18,33 @@ package com.example.associate.training.busschedule import android.app.Application import com.example.associate.training.busschedule.database.AppDatabase import com.example.associate.training.inventory.data.ItemRoomDatabase +import com.example.associate.training.koin.HelloRepository +import com.example.associate.training.koin.HelloRepositoryImpl +import com.example.associate.training.koin.MyViewModel +import org.koin.android.ext.koin.androidContext +import org.koin.android.ext.koin.androidLogger +import org.koin.androidx.viewmodel.dsl.viewModel +import org.koin.core.context.startKoin +import org.koin.dsl.module + +val appModule = module { + + // single instance of HelloRepository + single { HelloRepositoryImpl() } + + // MyViewModel ViewModel + viewModel { MyViewModel(get()) } +} class BusScheduleApplication : Application() { val database: AppDatabase by lazy { AppDatabase.getDatabase(this) } val inventoryDatabase: ItemRoomDatabase by lazy { ItemRoomDatabase.getDatabase(this) } + override fun onCreate() { + super.onCreate() + // Start Koin + startKoin{ + androidContext(this@BusScheduleApplication) + modules(appModule) + } + } } diff --git a/app/src/main/java/com/example/associate/training/koin/KoinActivity.kt b/app/src/main/java/com/example/associate/training/koin/KoinActivity.kt new file mode 100644 index 0000000..668f49a --- /dev/null +++ b/app/src/main/java/com/example/associate/training/koin/KoinActivity.kt @@ -0,0 +1,37 @@ +package com.example.associate.training.koin + +import android.os.Bundle +import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.ViewModel +import com.example.associate.training.R +import org.koin.androidx.viewmodel.ext.android.viewModel + +class KoinActivity : AppCompatActivity() { + // Lazy Inject ViewModel + val myViewModel: MyViewModel by viewModel() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_koin) + } + + override fun onResume() { + super.onResume() + val textView: TextView = findViewById(R.id.koin_title) + textView.text = myViewModel.sayHello() + } +} + +interface HelloRepository { + fun giveHello(): String +} + +class HelloRepositoryImpl() : HelloRepository { + override fun giveHello() = "Hello Koin" +} + +class MyViewModel(val repo : HelloRepository) : ViewModel() { + + fun sayHello() = "${repo.giveHello()} from $this" +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_blur.xml b/app/src/main/res/layout/activity_blur.xml index ab4f0c0..ca6ba87 100644 --- a/app/src/main/res/layout/activity_blur.xml +++ b/app/src/main/res/layout/activity_blur.xml @@ -42,7 +42,6 @@ android:text="@string/blur_title" android:textAppearance="@style/TextAppearance.AppCompat.Large" /> - + + + + + From 8539ae0c66e21d132728eadc8e8110f1dc78927c Mon Sep 17 00:00:00 2001 From: HsiaoTing Chen Date: Fri, 16 Sep 2022 15:27:00 +0800 Subject: [PATCH 03/33] Refinement --- ...Application.kt => AssociateApplication.kt} | 22 +++---------------- .../busschedule/FullScheduleFragment.kt | 21 ++++-------------- .../busschedule/StopScheduleFragment.kt | 18 ++------------- .../training/inventory/AddItemFragment.kt | 19 ++-------------- .../training/inventory/ItemDetailFragment.kt | 22 +++---------------- .../training/inventory/ItemListFragment.kt | 22 +++---------------- 6 files changed, 17 insertions(+), 107 deletions(-) rename app/src/main/java/com/example/associate/training/{busschedule/BusScheduleApplication.kt => AssociateApplication.kt} (55%) diff --git a/app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt b/app/src/main/java/com/example/associate/training/AssociateApplication.kt similarity index 55% rename from app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt rename to app/src/main/java/com/example/associate/training/AssociateApplication.kt index 1c86951..155bfda 100644 --- a/app/src/main/java/com/example/associate/training/busschedule/BusScheduleApplication.kt +++ b/app/src/main/java/com/example/associate/training/AssociateApplication.kt @@ -1,19 +1,4 @@ -package com.example.associate.training.busschedule -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ +package com.example.associate.training import android.app.Application import com.example.associate.training.busschedule.database.AppDatabase @@ -22,7 +7,6 @@ import com.example.associate.training.koin.HelloRepository import com.example.associate.training.koin.HelloRepositoryImpl import com.example.associate.training.koin.MyViewModel import org.koin.android.ext.koin.androidContext -import org.koin.android.ext.koin.androidLogger import org.koin.androidx.viewmodel.dsl.viewModel import org.koin.core.context.startKoin import org.koin.dsl.module @@ -36,14 +20,14 @@ val appModule = module { viewModel { MyViewModel(get()) } } -class BusScheduleApplication : Application() { +class AssociateApplication : Application() { val database: AppDatabase by lazy { AppDatabase.getDatabase(this) } val inventoryDatabase: ItemRoomDatabase by lazy { ItemRoomDatabase.getDatabase(this) } override fun onCreate() { super.onCreate() // Start Koin startKoin{ - androidContext(this@BusScheduleApplication) + androidContext(this@AssociateApplication) modules(appModule) } } diff --git a/app/src/main/java/com/example/associate/training/busschedule/FullScheduleFragment.kt b/app/src/main/java/com/example/associate/training/busschedule/FullScheduleFragment.kt index 98a92e8..1e36513 100644 --- a/app/src/main/java/com/example/associate/training/busschedule/FullScheduleFragment.kt +++ b/app/src/main/java/com/example/associate/training/busschedule/FullScheduleFragment.kt @@ -1,18 +1,4 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ + package com.example.associate.training.busschedule import android.os.Bundle @@ -25,6 +11,7 @@ import androidx.lifecycle.coroutineScope import androidx.navigation.findNavController import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.example.associate.training.AssociateApplication import com.example.associate.training.busschedule.viewmodels.BusScheduleViewModel import com.example.associate.training.busschedule.viewmodels.BusScheduleViewModelFactory import com.example.associate.training.databinding.FragmentFullScheduleBinding @@ -40,7 +27,7 @@ class FullScheduleFragment: Fragment() { private val viewModel: BusScheduleViewModel by activityViewModels { BusScheduleViewModelFactory( - (activity?.application as BusScheduleApplication).database.scheduleDao() + (activity?.application as AssociateApplication).database.scheduleDao() ) } @@ -48,7 +35,7 @@ class FullScheduleFragment: Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { _binding = FragmentFullScheduleBinding.inflate(inflater, container, false) val view = binding.root return view diff --git a/app/src/main/java/com/example/associate/training/busschedule/StopScheduleFragment.kt b/app/src/main/java/com/example/associate/training/busschedule/StopScheduleFragment.kt index a10c12a..97389f0 100644 --- a/app/src/main/java/com/example/associate/training/busschedule/StopScheduleFragment.kt +++ b/app/src/main/java/com/example/associate/training/busschedule/StopScheduleFragment.kt @@ -1,18 +1,3 @@ -/* - * Copyright (C) 2021 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package com.example.associate.training.busschedule import android.os.Bundle @@ -24,6 +9,7 @@ import androidx.fragment.app.activityViewModels import androidx.lifecycle.coroutineScope import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView +import com.example.associate.training.AssociateApplication import com.example.associate.training.busschedule.viewmodels.BusScheduleViewModel import com.example.associate.training.busschedule.viewmodels.BusScheduleViewModelFactory import com.example.associate.training.databinding.FragmentStopScheduleBinding @@ -45,7 +31,7 @@ class StopScheduleFragment: Fragment() { private val viewModel: BusScheduleViewModel by activityViewModels { BusScheduleViewModelFactory( - (activity?.application as BusScheduleApplication).database.scheduleDao() + (activity?.application as AssociateApplication).database.scheduleDao() ) } diff --git a/app/src/main/java/com/example/associate/training/inventory/AddItemFragment.kt b/app/src/main/java/com/example/associate/training/inventory/AddItemFragment.kt index b351298..0b06ded 100644 --- a/app/src/main/java/com/example/associate/training/inventory/AddItemFragment.kt +++ b/app/src/main/java/com/example/associate/training/inventory/AddItemFragment.kt @@ -1,18 +1,3 @@ -/* - * Copyright (C) 2021 The Android Open Source Project. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ package com.example.associate.training.inventory import android.content.Context.INPUT_METHOD_SERVICE @@ -26,7 +11,7 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs -import com.example.associate.training.busschedule.BusScheduleApplication +import com.example.associate.training.AssociateApplication import com.example.associate.training.databinding.FragmentAddItemBinding import com.example.associate.training.inventory.data.Item @@ -39,7 +24,7 @@ class AddItemFragment : Fragment() { // to share the ViewModel across fragments. private val viewModel: InventoryViewModel by activityViewModels { InventoryViewModelFactory( - (activity?.application as BusScheduleApplication).inventoryDatabase + (activity?.application as AssociateApplication).inventoryDatabase .itemDao() ) } diff --git a/app/src/main/java/com/example/associate/training/inventory/ItemDetailFragment.kt b/app/src/main/java/com/example/associate/training/inventory/ItemDetailFragment.kt index 97b0fbb..b6e9270 100644 --- a/app/src/main/java/com/example/associate/training/inventory/ItemDetailFragment.kt +++ b/app/src/main/java/com/example/associate/training/inventory/ItemDetailFragment.kt @@ -1,19 +1,3 @@ -/* - * Copyright (C) 2021 The Android Open Source Project. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.example.associate.training.inventory import android.os.Bundle @@ -24,8 +8,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.navArgs +import com.example.associate.training.AssociateApplication import com.example.associate.training.R -import com.example.associate.training.busschedule.BusScheduleApplication import com.example.associate.training.databinding.FragmentItemDetailBinding import com.example.associate.training.inventory.data.Item import com.example.associate.training.inventory.data.getFormattedPrice @@ -41,7 +25,7 @@ class ItemDetailFragment : Fragment() { private val viewModel: InventoryViewModel by activityViewModels { InventoryViewModelFactory( - (activity?.application as BusScheduleApplication).inventoryDatabase.itemDao() + (activity?.application as AssociateApplication).inventoryDatabase.itemDao() ) } @@ -52,7 +36,7 @@ class ItemDetailFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { _binding = FragmentItemDetailBinding.inflate(inflater, container, false) return binding.root } diff --git a/app/src/main/java/com/example/associate/training/inventory/ItemListFragment.kt b/app/src/main/java/com/example/associate/training/inventory/ItemListFragment.kt index 754cc52..e5952e5 100644 --- a/app/src/main/java/com/example/associate/training/inventory/ItemListFragment.kt +++ b/app/src/main/java/com/example/associate/training/inventory/ItemListFragment.kt @@ -1,19 +1,3 @@ -/* - * Copyright (C) 2021 The Android Open Source Project. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - package com.example.associate.training.inventory import android.os.Bundle @@ -24,8 +8,8 @@ import androidx.fragment.app.Fragment import androidx.fragment.app.activityViewModels import androidx.navigation.fragment.findNavController import androidx.recyclerview.widget.LinearLayoutManager +import com.example.associate.training.AssociateApplication import com.example.associate.training.R -import com.example.associate.training.busschedule.BusScheduleApplication import com.example.associate.training.databinding.FragmentItemListBinding /** @@ -34,7 +18,7 @@ import com.example.associate.training.databinding.FragmentItemListBinding class ItemListFragment : Fragment() { private val viewModel: InventoryViewModel by activityViewModels { InventoryViewModelFactory( - (activity?.application as BusScheduleApplication).inventoryDatabase.itemDao() + (activity?.application as AssociateApplication).inventoryDatabase.itemDao() ) } @@ -45,7 +29,7 @@ class ItemListFragment : Fragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View? { + ): View { _binding = FragmentItemListBinding.inflate(inflater, container, false) return binding.root } From 1d2670ffae032bdfd9ecc47cc8525deff37def87 Mon Sep 17 00:00:00 2001 From: TimChen Date: Sun, 9 Oct 2022 12:56:03 +0800 Subject: [PATCH 04/33] Add the use case of the View Stub --- app/src/main/AndroidManifest.xml | 4 + .../associate/training/MainActivity.kt | 2 + .../associate/training/misc/MiscActivity.kt | 26 +++++++ .../misc/fragment/MiscListFragment.kt | 76 +++++++++++++++++++ .../misc/fragment/ViewStubFragment.kt | 43 +++++++++++ app/src/main/res/layout/activity_misc.xml | 12 +++ .../main/res/layout/fragment_view_stub.xml | 27 +++++++ app/src/main/res/layout/hell_world.xml | 15 ++++ app/src/main/res/layout/hello_world.xml | 15 ++++ 9 files changed, 220 insertions(+) create mode 100644 app/src/main/java/com/example/associate/training/misc/MiscActivity.kt create mode 100644 app/src/main/java/com/example/associate/training/misc/fragment/MiscListFragment.kt create mode 100644 app/src/main/java/com/example/associate/training/misc/fragment/ViewStubFragment.kt create mode 100644 app/src/main/res/layout/activity_misc.xml create mode 100644 app/src/main/res/layout/fragment_view_stub.xml create mode 100644 app/src/main/res/layout/hell_world.xml create mode 100644 app/src/main/res/layout/hello_world.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f3b4f6b..395b7f2 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -82,6 +82,10 @@ android:name=".pic.PicActivity" android:exported="true"/> + + \ No newline at end of file diff --git a/app/src/main/java/com/example/associate/training/MainActivity.kt b/app/src/main/java/com/example/associate/training/MainActivity.kt index 6aca687..e3cbc46 100644 --- a/app/src/main/java/com/example/associate/training/MainActivity.kt +++ b/app/src/main/java/com/example/associate/training/MainActivity.kt @@ -11,6 +11,7 @@ import com.example.associate.training.databinding.ActivityMainBinding import com.example.associate.training.dummy.DummyActivity import com.example.associate.training.inventory.InventoryActivity import com.example.associate.training.lifecycle.LifecycleActivity +import com.example.associate.training.misc.MiscActivity import com.example.associate.training.pic.PicActivity import com.example.associate.training.word.WordActivity import com.example.associate.training.workmanager.WorkManagerActivity @@ -34,6 +35,7 @@ open class MainActivity : AppCompatActivity() { open fun getList(): List { return listOf( + Entry("MiscActivity", MiscActivity::class.java), Entry("CanvasActivity", CanvasActivity::class.java), Entry("ViewsActivity", PicActivity::class.java), Entry("WorkManager", WorkManagerActivity::class.java), diff --git a/app/src/main/java/com/example/associate/training/misc/MiscActivity.kt b/app/src/main/java/com/example/associate/training/misc/MiscActivity.kt new file mode 100644 index 0000000..a86f0a4 --- /dev/null +++ b/app/src/main/java/com/example/associate/training/misc/MiscActivity.kt @@ -0,0 +1,26 @@ +package com.example.associate.training.misc + +import android.os.Bundle +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.add +import androidx.fragment.app.commit +import com.example.associate.training.R +import com.example.associate.training.misc.fragment.MiscListFragment + +class MiscActivity : AppCompatActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + createFragment() + } + + private fun createFragment() { + setContentView(R.layout.activity_misc) + supportFragmentManager.commit { + setReorderingAllowed(true) + add(R.id.canvas_fragment_container) + } + } + +} + diff --git a/app/src/main/java/com/example/associate/training/misc/fragment/MiscListFragment.kt b/app/src/main/java/com/example/associate/training/misc/fragment/MiscListFragment.kt new file mode 100644 index 0000000..2eaff8f --- /dev/null +++ b/app/src/main/java/com/example/associate/training/misc/fragment/MiscListFragment.kt @@ -0,0 +1,76 @@ +package com.example.associate.training.misc.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TextView +import androidx.annotation.Nullable +import androidx.appcompat.app.AppCompatActivity +import androidx.fragment.app.Fragment +import androidx.fragment.app.commit +import androidx.recyclerview.widget.LinearLayoutManager +import androidx.recyclerview.widget.RecyclerView +import com.example.associate.training.R +import com.example.associate.training.databinding.ActivityMainBinding + +class MiscListFragment : Fragment() { + + private lateinit var adapter: MiscListAdapter + private lateinit var binding: ActivityMainBinding + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + setupAdapter() + } + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = ActivityMainBinding.inflate(layoutInflater) + return binding.root + } + + private fun setupAdapter() { + adapter = MiscListAdapter(MiscViewType.values().toList(), activity as AppCompatActivity) + binding.tutorsRecyclerView.layoutManager = LinearLayoutManager(binding.root.context) + binding.tutorsRecyclerView.adapter = adapter + } + +} + +enum class MiscViewType { VIEWSTUB, OTHER} + +class MiscListAdapter(private val entries: List, private val activity: AppCompatActivity) : + RecyclerView.Adapter() { + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + val view = LayoutInflater.from(parent.context) + .inflate(R.layout.card_view_timeline, parent, false) + return DesignViewHolder(view) + } + + override fun onBindViewHolder(@Nullable holder: RecyclerView.ViewHolder, position: Int) { + if (holder is DesignViewHolder) { + val entry = entries[position] + holder.textView.text = entry.name + holder.itemView.setOnClickListener { + activity.supportFragmentManager.commit { + replace(R.id.canvas_fragment_container, ViewStubFragment()) + addToBackStack(null) + } + } + } + + } + + override fun getItemCount(): Int { + return entries.size + } + + class DesignViewHolder(ItemView: View) : RecyclerView.ViewHolder(ItemView) { + val textView: TextView = itemView.findViewById(R.id.textView) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/associate/training/misc/fragment/ViewStubFragment.kt b/app/src/main/java/com/example/associate/training/misc/fragment/ViewStubFragment.kt new file mode 100644 index 0000000..b37c9ea --- /dev/null +++ b/app/src/main/java/com/example/associate/training/misc/fragment/ViewStubFragment.kt @@ -0,0 +1,43 @@ +package com.example.associate.training.misc.fragment + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.associate.training.R +import com.example.associate.training.canvas.CircularAvatarView +import com.example.associate.training.canvas.SaveLayerView +import com.example.associate.training.canvas.SaveRestoreCanvasView +import com.example.associate.training.canvas.XfersModeView +import com.example.associate.training.canvas.view.CanvasViewType +import com.example.associate.training.databinding.ActivityMainBinding +import com.example.associate.training.databinding.FragmentViewStubBinding + +class ViewStubFragment : Fragment() { + private lateinit var binding: FragmentViewStubBinding + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + binding = FragmentViewStubBinding.inflate(layoutInflater) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + binding.apply { + helloWorld.setOnClickListener { + viewStub.layoutResource = R.layout.hello_world + viewStub.inflate() + } + + hellWorld.setOnClickListener { + viewStub.layoutResource = R.layout.hell_world + viewStub.inflate() + } + } + } +} \ No newline at end of file diff --git a/app/src/main/res/layout/activity_misc.xml b/app/src/main/res/layout/activity_misc.xml new file mode 100644 index 0000000..8c15e7d --- /dev/null +++ b/app/src/main/res/layout/activity_misc.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/app/src/main/res/layout/fragment_view_stub.xml b/app/src/main/res/layout/fragment_view_stub.xml new file mode 100644 index 0000000..56529d3 --- /dev/null +++ b/app/src/main/res/layout/fragment_view_stub.xml @@ -0,0 +1,27 @@ + + + + +