zoukankan      html  css  js  c++  java
  • Sunflower(向日葵)源码分析

    简介:

    Sunflower项目是google发布的kotlin项目,里面主要介绍google 最新的一些工具,使开发者可以快速构建自己的APP项目,具体源码:https://github.com/googlesamples/android-sunflower

    在自己安装编译的时候,建议把包名(com.google.samples.apps.sunflower)改动下,因为com.google.xx安装后提示需要安装google的插件

    一、主要技术

    1、MVVM 利用databinding,viewModel,liveData实现MVVM架构,

    2、利用navigation框架做导航,APP只有一个Activity,其余的都是Fragment

    二、具体说明

    1、界面实现

    主Activity:GardenActivity 加载了一个布局

    <layout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">
    
            <fragment
                android:id="@+id/nav_host"
                android:name="androidx.navigation.fragment.NavHostFragment"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                app:defaultNavHost="true"
                app:navGraph="@navigation/nav_garden"/>
    
        </FrameLayout>
    
    </layout>

    有个<layout/>来封装其实没啥用,因为没有使用Binding的内容,可以去掉

    这里用到Navigation,我们来看看nav_garden

    //使用navigation来包装,加载两个fragment app:startDestination设置主界面
    <navigation xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        app:startDestination="@+id/view_pager_fragment">
    
    //主fragment <fragment android:id="@+id/view_pager_fragment" android:name="com.gl.samples.apps.sunflower.HomeViewPagerFragment" tools:layout="@layout/fragment_view_pager"> <action android:id="@+id/action_view_pager_fragment_to_plant_detail_fragment" app:destination="@id/plant_detail_fragment" app:enterAnim="@anim/slide_in_right" app:exitAnim="@anim/slide_out_left" app:popEnterAnim="@anim/slide_in_left" app:popExitAnim="@anim/slide_out_right" /> </fragment> //详情页 <fragment android:id="@+id/plant_detail_fragment" android:name="com.gl.samples.apps.sunflower.PlantDetailFragment" android:label="@string/plant_details_title" tools:layout="@layout/fragment_plant_detail"> <argument android:name="plantId" app:argType="string" /> </fragment> </navigation>
    这个也不难,HomeViewPagerFragment主界面,PlantDetailFragment植物详情页,具体内容可以去了解下Navigation

       HomeViewPagerFragment 主要是一个viewPager,包含两个Fragment :GardenFragment和 PlantListFragment

    class SunflowerPagerAdapter(fragment: Fragment) : FragmentStateAdapter(fragment) {
    
        /**
         * Mapping of the ViewPager page indexes to their respective Fragments
         */
        private val tabFragmentsCreators: Map<Int, () -> Fragment> = mapOf(
            MY_GARDEN_PAGE_INDEX to { GardenFragment() },
            PLANT_LIST_PAGE_INDEX to { PlantListFragment() }
        )
    
        override fun getItemCount() = tabFragmentsCreators.size
    
        override fun createFragment(position: Int): Fragment {
            return tabFragmentsCreators[position]?.invoke() ?: throw IndexOutOfBoundsException()
        }
    }

    viewPager适配器SunflowerPagerAdapter中定义一个map,在创建Fragment的时候通过反射来执行构建Fragment的方法。

    这里要注意viewPager和我们以前使用的viewPager并不是一个东西,而是在androidx.viewpager2.widget里面的新的类,主要通过RecyclerView来实现,适配器当然

    也是继承RecyclerView.Adapter实现的,具体实现请查看源码,具体不细说。

    GardenFragment和 PlantListFragment里面就比较简单,运用DataBinding来把数据绑定到View上,实现数据变化view改变,ViewModel来处理和管理数据,并进行数据通信。

    这个里面涉及到的内容比较复杂,可以查看我另一个源码,比较简单的介绍DataBinding和ViewModel的用法,传送门

    2、数据加载

    这个应用可以说是一个离线应用(数据离线,图片加载不是),主要的数据都是存储在plants.json,于是需要把内容都加载出来:

    class SeedDatabaseWorker(
        context: Context,
        workerParams: WorkerParameters
    ) : CoroutineWorker(context, workerParams) {
        override suspend fun doWork(): Result = coroutineScope {
            try {
                applicationContext.assets.open(PLANT_DATA_FILENAME).use { inputStream ->
                    JsonReader(inputStream.reader()).use { jsonReader ->
                        val plantType = object : TypeToken<List<Plant>>() {}.type
                        val plantList: List<Plant> = Gson().fromJson(jsonReader, plantType)
    
                        val database = AppDatabase.getInstance(applicationContext)
                        database.plantDao().insertAll(plantList)
    
                        Result.success()
                    }
                }
            } catch (ex: Exception) {
                Log.e(TAG, "Error seeding database", ex)
                Result.failure()
            }
        }

    主要在SeedDatabaseWorker类中,主要使用的是WorkManager这个框架来实现异步加载,加载后把数据存入room数据库,便于后续使用。

    CoroutineWorker是Worker的子类,一般在使用Kotlin开发的时候使用来和协程配合开发,

    看这部分代码可以先去学习下WorkManager,WorkManger介绍视频:介绍视频(美丽的小姐姐不会让你失望的)

    当然room数据库也有小哥哥的视频:介绍视频

    总结:

    Sunflower这个应用主要的技术包括:DataBinding、ViewModel、LiveData、Navigation、WorkManager和Room,

    当然还有一些简单的Android的知识和协程的内容,把这个应用过一遍,对自己也很有帮助。

  • 相关阅读:
    Rotation issue in XCode 4.5 and iOS 6.0
    Core Data on iOS 5 Tutorial: How To Work with Relations and Predicates
    How To Synchronize Core Data with a Web Service – Part 2
    Unit Testing in Xcode 4 – use OCUnit and SenTest instead of GHUnit
    Migrate old project to ARC
    Core Data on iOS 5 Tutorial: Getting Started
    How To Draw Graphs with Core Plot, Part 2
    How To Use NSOperations and NSOperationQueues
    How To Save Your App Data With NSCoding and NSFileManager
    What's New in iOS
  • 原文地址:https://www.cnblogs.com/doubleyoujs/p/11576227.html
Copyright © 2011-2022 走看看