如何将具有一对一关系 pojo(ROOM 实现)和 safeArgs 的 List<> 传递到目的地
How Do I pass a List<> with a one to one relation pojo (ROOM implementation) with safeArgs to the destination
这个回答帮了大忙,但好像还缺什么。
问题是设置参数的 'action' 方法告诉我我的列表与 navigation.xml 中定义的列表类型不同,如果我尝试编写xml 作为 List 的参数,碰巧 safeArgs 不支持该类型(如果它是由 RecyclerViewAdapters 管理的最常见类型,那就很奇怪了),我还尝试将我的 List<> 转换为 ArrayList<> 但什么也没有。
我的代码:
<fragment
android:id="@+id/product_list_fragment"
android:name="com.example.myapp.ui.ProductListFragment"
android:label="@string/product_list_title"
tools:layout="@layout/fragment_product_list">
<argument
android:name="quote"
app:argType="integer"
android:defaultValue="0"
/>
<argument
android:name="productList"
app:argType="com.example.myapp.data.pojos_entities.ProductQuantity[]"
/>
</fragment>
public class ProductQuantity {
@Embedded
public Quantity mQuantity_;
@Relation(
parentColumn = "child_product_id",
entityColumn = "product_id"
)
public Product mProduct_;
}
所以我终于想出了一个解决方案,它看起来像这样:
但它并不像那一行那么简单。
对于 List<ProductQuantity> productQuantities
,为了能够将其自身转换为 Parcelable Array[](不是 Array[] 或 ArrayList,它们不相同),Pojo(在本例中为 ProductQuantity.class
)必须实现一个 Parcelable。像这样:
实施后,只需按 alt + Enter 即可实施所有必要的方法。
但是,这还不是全部。
在用于关系查询的 ROOM Pojo 中实现方法的问题在于它不会编译,因此您接下来需要做的是在 Parcelable 实现创建的每个方法之上使用 @Ignore 接口.
最后你会注意到它仍然没有编译,并且出于某种原因,即使你忽略了 Parcelable 所需的构造函数,你也必须为 ROOM 创建一个 EMPTY 构造函数才能编译(即使在成为 Parcelable 之前不需要构造函数)
代码:
public class ProductQuantity implements Parcelable {
@Embedded
public Quantity mQuantity_;
@Relation(
parentColumn = "child_product_id",
entityColumn = "product_id"
)
public Product mProduct_;
public ProductQuantity() {
/*Empty constructor required by ROOM*/
}
@Ignore
protected ProductQuantity(Parcel in) {
}
@Ignore
public static final Creator<ProductQuantity> CREATOR = new Creator<ProductQuantity>() {
@Override
public ProductQuantity createFromParcel(Parcel in) {
return new ProductQuantity(in);
}
@Override
public ProductQuantity[] newArray(int size) {
return new ProductQuantity[size];
}
};
/*This methods don't need to be ignored for some reason*/
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
}
}
转换加导航:
List<ProductQuantity> productQuantities = adapter.getCurrentList();
ProductQuantity[] productQuantitiesArray = productQuantities
.toArray(new ProductQuantity[adapter.getItemCount()]);
ProductsAndQuantitiesFragmentDirections.ActionProductsAndQuantitiesByQuoteFragmentToProductListFragment direction;
Log.d(TAG, "onClick: quoteId is: " + quoteId);
direction = ProductsAndQuantitiesFragmentDirections
.actionProductsAndQuantitiesByQuoteFragmentToProductListFragment(productQuantitiesArray).setQuote(quoteId);
Navigation.findNavController(view).navigate(direction);
最后一个要注意的提示是列表 class 的 .toArray()
方法如何不包括列表本身的行数或项目数,这就是为什么它是最重要的在代码中手动放置项目数量的重要性,在本例中使用了 adapter.getItemCount()
方法,但如果您直接使用 List<>,只需使用 List 的 .size() 方法。在这种特殊情况下将是 productQuantities.size()
这个回答帮了大忙,但好像还缺什么。
问题是设置参数的 'action' 方法告诉我我的列表与 navigation.xml 中定义的列表类型不同,如果我尝试编写xml 作为 List 的参数,碰巧 safeArgs 不支持该类型(如果它是由 RecyclerViewAdapters 管理的最常见类型,那就很奇怪了),我还尝试将我的 List<> 转换为 ArrayList<> 但什么也没有。
我的代码:
<fragment
android:id="@+id/product_list_fragment"
android:name="com.example.myapp.ui.ProductListFragment"
android:label="@string/product_list_title"
tools:layout="@layout/fragment_product_list">
<argument
android:name="quote"
app:argType="integer"
android:defaultValue="0"
/>
<argument
android:name="productList"
app:argType="com.example.myapp.data.pojos_entities.ProductQuantity[]"
/>
</fragment>
public class ProductQuantity {
@Embedded
public Quantity mQuantity_;
@Relation(
parentColumn = "child_product_id",
entityColumn = "product_id"
)
public Product mProduct_;
}
所以我终于想出了一个解决方案,它看起来像这样:
但它并不像那一行那么简单。
对于 List<ProductQuantity> productQuantities
,为了能够将其自身转换为 Parcelable Array[](不是 Array[] 或 ArrayList,它们不相同),Pojo(在本例中为 ProductQuantity.class
)必须实现一个 Parcelable。像这样:
实施后,只需按 alt + Enter 即可实施所有必要的方法。
但是,这还不是全部。
在用于关系查询的 ROOM Pojo 中实现方法的问题在于它不会编译,因此您接下来需要做的是在 Parcelable 实现创建的每个方法之上使用 @Ignore 接口.
最后你会注意到它仍然没有编译,并且出于某种原因,即使你忽略了 Parcelable 所需的构造函数,你也必须为 ROOM 创建一个 EMPTY 构造函数才能编译(即使在成为 Parcelable 之前不需要构造函数)
代码:
public class ProductQuantity implements Parcelable {
@Embedded
public Quantity mQuantity_;
@Relation(
parentColumn = "child_product_id",
entityColumn = "product_id"
)
public Product mProduct_;
public ProductQuantity() {
/*Empty constructor required by ROOM*/
}
@Ignore
protected ProductQuantity(Parcel in) {
}
@Ignore
public static final Creator<ProductQuantity> CREATOR = new Creator<ProductQuantity>() {
@Override
public ProductQuantity createFromParcel(Parcel in) {
return new ProductQuantity(in);
}
@Override
public ProductQuantity[] newArray(int size) {
return new ProductQuantity[size];
}
};
/*This methods don't need to be ignored for some reason*/
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
}
}
转换加导航:
List<ProductQuantity> productQuantities = adapter.getCurrentList();
ProductQuantity[] productQuantitiesArray = productQuantities
.toArray(new ProductQuantity[adapter.getItemCount()]);
ProductsAndQuantitiesFragmentDirections.ActionProductsAndQuantitiesByQuoteFragmentToProductListFragment direction;
Log.d(TAG, "onClick: quoteId is: " + quoteId);
direction = ProductsAndQuantitiesFragmentDirections
.actionProductsAndQuantitiesByQuoteFragmentToProductListFragment(productQuantitiesArray).setQuote(quoteId);
Navigation.findNavController(view).navigate(direction);
最后一个要注意的提示是列表 class 的 .toArray()
方法如何不包括列表本身的行数或项目数,这就是为什么它是最重要的在代码中手动放置项目数量的重要性,在本例中使用了 adapter.getItemCount()
方法,但如果您直接使用 List<>,只需使用 List 的 .size() 方法。在这种特殊情况下将是 productQuantities.size()