Sunday, 24 July 2022

How to use the new ComponentActivity with ViewBinding and the other old AppCompatActivity components

According to this question, I tried to update my deprecated menus codes like setHasOptionsMenu , onCreateOptionsMenu and onOptionsItemSelected in my fragments and all app, but I should replace AppCompatActivity to ComponentActivity(R.layout.activity_example) but after doing this I see there's some problem, first I confused about how to use ViewBinding with it when I should remove setContentView(binding.root) from activity second the method setSupportActionBar(binding.appBarMain.toolbar) is not found, and I couldn't use the navigation components like supportFragmentManager and setupActionBarWithNavController the third thing I couldn't"t declare this
val menuHost: MenuHost = requireActivity() in onCreateView in fragment I see it's Required: MenuHost but Found: FragmentActivity

enter image description here

menu updates

here's my MainActivity code before edits

@AndroidEntryPoint
class MainActivity : AppCompatActivity() {


    private lateinit var appBarConfiguration: AppBarConfiguration
    private lateinit var binding: ActivityMainBinding
    private lateinit var navController: NavController
    private lateinit var postViewModel: PostViewModel
    private lateinit var navGraph: NavGraph


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        postViewModel = ViewModelProvider(this)[PostViewModel::class.java]
        postViewModel.getCurrentDestination()

        setSupportActionBar(binding.appBarMain.toolbar)

        val drawerLayout: DrawerLayout = binding.drawerLayout
        

        val navHostFragment =
            supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment?

        if (navHostFragment != null) {
            navController = navHostFragment.navController
        }
        navGraph = navController.navInflater.inflate(R.navigation.mobile_navigation)


        // Passing each menu ID as a set of Ids because each
        // menu should be considered as top level destinations.
        appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.nav_home, R.id.nav_accessory,
                R.id.nav_arcade, R.id.nav_fashion,
                R.id.nav_food, R.id.nav_heath,
                R.id.nav_lifestyle, R.id.nav_sports, R.id.nav_favorites, R.id.about
            ), drawerLayout
        )
//        setupActionBarWithNavController(navController, appBarConfiguration)
//        navView.setupWithNavController(navController)

        setupActionBarWithNavController(this, navController, appBarConfiguration)
        setupWithNavController(binding.navView, navController)



        
//        determineAdvertisingInfo()
    }


    override fun onSupportNavigateUp(): Boolean {
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }

}

and this the implementation of menus in fragments

  override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {

        _binding = FragmentHomeBinding.inflate(inflater, container, false)


         setHasOptionsMenu(true)
         return binding.root
    }

....................................................................................

  override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
        inflater.inflate(R.menu.main, menu)
        super.onCreateOptionsMenu(menu, inflater)
        val searchManager =
            requireContext().getSystemService(Context.SEARCH_SERVICE) as SearchManager
        val searchView = menu.findItem(R.id.app_bar_search).actionView as SearchView
        searchView.setSearchableInfo(searchManager.getSearchableInfo(requireActivity().componentName))
        searchView.queryHint = resources.getString(R.string.searchForPosts)

        searchView.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
            override fun onQueryTextSubmit(keyword: String): Boolean {
                if (keyword.isEmpty()) {
                    Snackbar.make(
                        requireView(),
                        "please enter keyword to search",
                        Snackbar.LENGTH_SHORT
                    ).show()
                }
//                itemArrayList.clear()
                if (Utils.hasInternetConnection(requireContext())) {
                    postViewModel.getItemsBySearch(keyword)
                    postViewModel.searchedPostsResponse.observe(viewLifecycleOwner) { response ->

                        when (response) {
                            is NetworkResult.Success -> {
                                hideShimmerEffect()
                                itemArrayList.clear()
                                binding.progressBar.visibility = View.GONE
                                response.data?.let {
                                    itemArrayList.addAll(it.items)
                                }
                                adapter.notifyDataSetChanged()

                            }

                            is NetworkResult.Error -> {
                                hideShimmerEffect()
                                //                    loadDataFromCache()
                                Toast.makeText(
                                    requireContext(),
                                    response.toString(),
                                    Toast.LENGTH_LONG
                                ).show()

                            }

                            is NetworkResult.Loading -> {
                                if (postViewModel.recyclerViewLayout.value == "titleLayout" ||
                                    postViewModel.recyclerViewLayout.value == "gridLayout"
                                ) {
                                    hideShimmerEffect()
                                } else {
                                    showShimmerEffect()
                                }
                            }
                        }
                    }
                } else {
                    postViewModel.getItemsBySearchInDB(keyword)
                    postViewModel.postsBySearchInDB.observe(viewLifecycleOwner) { items ->
                        if (items.isNotEmpty()) {
                            hideShimmerEffect()
                            binding.progressBar.visibility = View.GONE
                            itemArrayList.clear()
                            itemArrayList.addAll(items)
                            adapter.notifyDataSetChanged()
                        }
                    }
                }
                return false

            }


            override fun onQueryTextChange(newText: String): Boolean {
                return false
            }
        })
        searchView.setOnCloseListener {
            if (Utils.hasInternetConnection(requireContext())) {
                Log.d(TAG, "setOnCloseListener: called")
                itemArrayList.clear()
                requestApiData()
            } else {
                noInternetConnectionLayout()
            }
            false
        }


        postViewModel.searchError.observe(viewLifecycleOwner) { searchError ->
            if (searchError) {
                Toast.makeText(
                    requireContext(),
                    "There's no posts with this keyword", Toast.LENGTH_LONG
                ).show()
            }
        }

    }



   override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if (item.itemId == R.id.change_layout) {
            changeAndSaveLayout()
            return true
        }
        return super.onOptionsItemSelected(item)
    }


build.gradle dependencies

dependencies {

    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.4.2'

    implementation ('com.google.android.material:material:1.6.1') {
        exclude(group: 'androidx.recyclerview',  module: 'recyclerview')
        exclude(group: 'androidx.recyclerview',  module: 'recyclerview-selection')
    }
    implementation "androidx.recyclerview:recyclerview:1.2.1"
    // For control over item selection of both touch and mouse driven selection
    implementation "androidx.recyclerview:recyclerview-selection:1.1.0"

    implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.5.0'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.0'
    implementation 'androidx.navigation:navigation-fragment-ktx:2.5.0'
    implementation 'androidx.navigation:navigation-ui-ktx:2.5.0'
    testImplementation 'junit:junit:4.13.2'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    //Retrofit
    implementation 'com.squareup.retrofit2:retrofit:2.9.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.9.0'

//    //Moshi
//    implementation("com.squareup.moshi:moshi:1.13.0")
//    implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
//    kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"

    implementation 'com.github.bumptech.glide:glide:4.12.0'
    implementation 'org.jsoup:jsoup:1.14.1'
    implementation 'com.squareup.picasso:picasso:2.71828'
    implementation 'org.apache.commons:commons-lang3:3.8.1'
    implementation 'org.ocpsoft.prettytime:prettytime:4.0.1.Final'
    implementation "androidx.browser:browser:1.4.0"

    implementation 'androidx.multidex:multidex:2.0.1'
    configurations {
        all*.exclude group: 'com.google.guava', module: 'listenablefuture'
    }

    //Room
    implementation "androidx.room:room-runtime:2.4.2"
    kapt "androidx.room:room-compiler:2.4.2"
    implementation "androidx.room:room-ktx:2.4.2"
    androidTestImplementation "androidx.room:room-testing:2.4.2"




    //Dagger - Hilt
    implementation 'com.google.dagger:hilt-android:2.42'
    kapt 'com.google.dagger:hilt-android-compiler:2.42'


    //SDP & SSP
    implementation 'com.intuit.sdp:sdp-android:1.0.6'
    implementation 'com.intuit.ssp:ssp-android:1.0.6'

    // Shimmer
    implementation 'com.facebook.shimmer:shimmer:0.5.0'

    //firebase & analytics
    implementation platform('com.google.firebase:firebase-bom:28.4.0')
    implementation 'com.google.firebase:firebase-analytics'

    //crashlytics
    implementation 'com.google.firebase:firebase-crashlytics'
    implementation 'com.google.firebase:firebase-analytics'

    // DataStore
    implementation 'androidx.datastore:datastore-preferences:1.0.0'
    implementation("androidx.datastore:datastore-preferences-rxjava3:1.0.0")

    //admob
    implementation 'com.google.android.gms:play-services-ads:21.1.0'
    implementation platform('com.google.firebase:firebase-bom:30.2.0')

    implementation project(':nativetemplates')

    implementation("androidx.ads:ads-identifier:1.0.0-alpha04")

    // Used for the calls to addCallback() in the snippets on this page.
    implementation("com.google.guava:guava:28.0-android")

    implementation 'com.google.firebase:firebase-analytics'
    implementation("androidx.activity:activity-ktx:1.5.0")


}


from How to use the new ComponentActivity with ViewBinding and the other old AppCompatActivity components

No comments:

Post a Comment