Jetpack 实战系列(二) | 写Java版的sunflower 分析Java版本

最近在研究Jetpack,这是我看见的一个比较好的系列文,这里分享给大家,希望对大家的学习和工作有所帮助。
原文地址:https://www.jianshu.com/p/9c94b41f4810

架构图

使用safe args插件传递参数

在project的build.gradle 中引入safe arges 插件

 classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$navigationVersion"

然后需要引用这个插件。在app的build.gradle中添加依赖。
如果需要java添加这个:

id 'androidx.navigation.safeargs'

纯kotlin的,添加这个:

id 'androidx.navigation.safeargs.kotlin'

build完成后,去nav_graph导航图的源代码中添加argument标签,也可以选中需要添加的页面在

也可以在代码里面添加,我比较喜欢代码添加

nav_graph.xml 中的---->标签

<fragment
        android:id="@+id/plantListFragment"
        android:name="top.zcwfeng.sunflower_java.PlantListFragment"
        android:label="@string/plant_list_title"
        tools:layout="@layout/fragment_plant_list">
        <action
            android:id="@+id/action_plantListFragment_to_planDetail"
            app:destination="@id/planDetail" />
        <argument
            android:name="plantId"
            app:argType="string" />
    </fragment>

build一下项目,进入Android模式下查看app文件夹,可以看见系统自动生成了两个文件。

参数的传递和使用

注意版本问题。可能不同版本生成的代码调用不一样
生成不带有参数构造方法,再设置ID

private View.OnClickListener createOnClickListener(String plantId) {
        Log.e("zcwfeng", "fix GardenPlantingAdapter click");
        GardenFragmentDirections.ActionGardenFragmentToPlantDetailFragment direction = GardenFragmentDirections.actionGardenFragmentToPlantDetailFragment();
        direction.setPlantId(plantId);
        return v -> Navigation.findNavController(v).navigate(direction);
    }

Entity 和 room 数据库

数据模型和表
Domain 层
Plant 植物 的表实体

/**
 * 这个是 植物 的表实体
 * 数据表 plants == Plant实体类
 * (plants表:存储了所有植物的信息)
 *  这里数据的获取并不是来源于网络,而是来自于事先已经创建好了的assets目录下的json数组(plants.json),
 *  并在数据库创建时,通过WorkManger发送这个请求,把所有Plant的信息insert到plants表中
 */
@Entity(tableName = "plants")
public final class Plant {
    private static final int DEFAULT_WATERING_INTERVAL = 7;
    @NonNull
    @PrimaryKey
    @ColumnInfo(name = "id")
    private final String plantId;
    @NonNull
    private final String imageUrl;
    @NonNull
    private final String name;

    @NonNull
    private final String description; // 描述详情,很长很长的文字信息
    // 植物应该多久浇水一次,以天为单位
    // how often the plant should be watered, in days
    private final int wateringInterval;
    private final int growZoneNumber;

    public Plant(@NonNull String plantId, @NonNull String imageUrl, @NonNull String name,
                 @NonNull String description, int wateringInterval, int growZoneNumber) {
        this.plantId = plantId;
        this.imageUrl = imageUrl;
        this.name = name;
        this.description = description;
        this.wateringInterval = wateringInterval;
        this.growZoneNumber = growZoneNumber;
    }


    public boolean shouldBeWatered(Calendar since, Calendar lastWateringDate) {
        lastWateringDate.add(Calendar.DAY_OF_YEAR, wateringInterval);
        return since.compareTo(lastWateringDate) > 0;
    }

省略setter and getter...

    @Override
    public boolean equals(Object o) {
//        if (this == o) return true;
        if (!(o instanceof Plant)) return false;
        Plant plant = (Plant) o;
        return plantId.equals(plant.plantId);
    }

    @Override
    public int hashCode() {
        return Objects.hash(plantId);
    }

    @NonNull
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

GardenPlating 实体表

@Entity(tableName = "garden_plantings",
        foreignKeys = {@ForeignKey(entity = Plant.class,
                parentColumns = {"id"},
                childColumns = {"plant_id"})},
        indices = {@Index("plant_id")})
public class GardenPlanting {
    @ColumnInfo(name = "plant_id")
    private final String plantId;


    @ColumnInfo(name = "plant_date")
    private final Calendar plantDate;

    @ColumnInfo(name = "last_watering_date")
    private final Calendar lastWateringDate;

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id")
    private long gardenPlantingId = 0L;

    public GardenPlanting(String plantId, Calendar plantDate, Calendar lastWateringDate) {
        this.plantId = plantId;
        this.plantDate = plantDate == null ? Calendar.getInstance() : plantDate;
        this.lastWateringDate = lastWateringDate == null ? Calendar.getInstance() : lastWateringDate;
    }
   setter and getter ......
  }

PlantAndGardenPlantings 关系

public class PlantAndGardenPlantings {
    @Embedded
    private Plant plant;

    @Relation(parentColumn = "id", entityColumn = "plant_id")
    private List<GardenPlanting> gardenPlantings;

    public PlantAndGardenPlantings() {
        this.gardenPlantings = new ArrayList<>();
    }

   setter getter....
}

‘Dao 层’
PlantDao ,GardenPlatingDao

‘Repository 层’
GardenPlantingRepository ,PlantRepository

‘ViewModel 层’

第一版简版,有ModelFactory 生成对应ViewModel,优化可以提取公共ViewModelFactory。

暂时未加入DI和网络数据,用的本地数据。

具体参考 分支 修复bug,无DI版本java第一版1.0 》》sunflower_java_nodi_1.0

最后

Android学习是一条漫长的道路,我们要学习的东西不仅仅只有表面的 技术,还要深入底层,弄明白下面的 原理,只有这样,我们才能够提高自己的竞争力,在当今这个竞争激烈的世界里立足。

我把自己这段时间整理的Android最重要最热门的学习方向资料放在了我们2000人的技术交流圈共享文件夹中(点击此处可加入),里面还有不同方向的自学编程路线、面试题集合/面经、及系列技术文章等。

群资源共享(文件密码找管理雨墨),欢迎大家一起学习和探讨。

猜你喜欢

转载自blog.csdn.net/m0_46962786/article/details/114458181
今日推荐