我如何通过具有到目的地的safeArgs的一对一关系pojo(ROOM实现)传递List <>

问题描述 投票:0回答:1

此答案很有帮助,但似乎仍然缺少某些内容。

https://stackoverflow.com/a/56477713/11214643

问题是,设置参数的'action'方法告诉我,我的List与Navigation.xml中定义的类型不同,如果我尝试将xml参数写为List,它只是因此,safeArgs不支持该类型(如果它是RecyclerViewAdapters管理的最常见的类型,则很奇怪),我还尝试将List <>转换为ArrayList <>,什么也没有。

enter image description here

我的代码:

<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_;
}
java android list android-room android-navigation
1个回答
0
投票

所以我终于有了一个解决方案,它看起来像这样:

enter image description here

但是它不如那条线那么简单。对于List<ProductQuantity> productQuantities,要能够将其自身转换为Array [](不是ArrayList,它们是不相同的),Pojo(在这种情况下为ProductQuantity.class)必须实现一个Parcelable。像这样:

enter image description here

一旦实现,只需按alt + Enter即可实现所有必要的方法。

但是,还不是全部。

在用于关系查询的ROOM Pojo中实现方法的问题是它不会编译,因此接下来要做的是在由Parcelable实现创建的每个方法之上使用@Ignore接口。

最后,您会注意到它仍然无法编译,并且由于某种原因,即使您忽略了Parcelable所需的构造函数,也必须为ROOM创建一个EMPTY构造函数,以便能够进行编译(即使构造函数没有在成为包裹之前是必需的)

代码:

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];
        }
    };

    @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);

最后一个需要注意的技巧是List类的.toArray()方法如何不包括List本身的行数或项目数,这就是为什么手动放置项目数最重要的原因在代码中,在这种情况下使用的是adapter.getItemCount()方法,但是如果直接使用List <>,则只需使用List的.size()方法即可。在这种情况下,应为productQuantities.size()

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.