Jetpack 实战目录:
Jetpack 实战Java(一)写Java版的sunflower 分析Java版本
Hilt入门思想,DI框架撇一眼
架构图
使用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 中的
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 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