Android Fragments Android中片段的参数化构造函数

8ljdwjyq  于 2022-11-24  发布在  Android
关注(0)|答案(6)|浏览(170)

下面是一个简单的例子:

public PlaceDialogFragment(Place place, DisplayMetrics dm){
        super();
        this.mPlace = place;
        this.mMetrics = dm;
    }

我也试过这个:-

public static final DialogFragment newInstance(Place place, DisplayMetrics dm)
{
    DialogFragment fragment = new DialogFragment();
    Bundle bundle = new Bundle(2);
    bundle.putParcelable("Place", place);
    bundle.putLong("Metrics", dm);
    fragment.setArguments(bundle);
    return fragment ;
}

但是bundle.putLong("Metrics", dm)行上有错误
这里Place是实现Parceable接口的类
但我得到一个错误说:-

Avoid non-default constructors in fragments: use a default constructor plus Fragment#setArguments(Bundle) instead

有什么建议可以解决这个问题吗?

5us2dqdw

5us2dqdw1#

你应该使用默认的构造函数并将参数作为bundle来传递,因为当系统恢复你的片段状态时,它会调用默认的构造函数并恢复bundle。如果你从bundle中获取参数,那么你就可以正确地恢复状态。
如果使用当前方法,则在重新创建片段时,在自定义构造函数中执行的所有操作都将丢失。
有关示例,请参见this answer

kzmpq1sx

kzmpq1sx2#

请改用setArguments,在处理片段时,在bundle中传递构造函数参数,然后使用getArguments()在片段中使用它们
How to use setArguments() and getArguments() methods in Fragments?
What's the point of setArguments?
http://developer.android.com/reference/android/app/Fragment.html
您补充道:

bundle.putLong("Metrics", dm);

这样做:

bundle.putFloat("Metrics_density", dm.density);

请参阅DisplatMetrics文档并单独添加参数,或者将DisplayMetrics对象作为静态对象添加到应用程序内存中,并在任何位置使用它。
DisplayMetrics不是Long对象,甚至不可打包,请改为在包中添加相关的DisplayMetrics字段。

public static final PlaceDialogFragment newInstance(Place place, DisplayMetrics dm)
{
    PlaceDialogFragment fragment = new DialogFragment();
    Bundle bundle = new Bundle(2);
    bundle.putParcelable("Place", place);
    bundle.putFloat("Metrics_density", dm.density);
    //bundle.putFloat("Metrics_other", dm.<other fields>);
    fragment.setArguments(bundle);
    return fragment ;
}

注意:不要使用带参数的公共构造函数。

yr9zkbsy

yr9zkbsy3#

错误信息是正确的!
避免对Fragment/Activity使用参数化构造函数。
你可以通过进入Lint设置并排除规则+添加一个默认构造函数来进行“快速修复”。但是快速修复不是办法。这会导致问题。考虑一下这个例子,你只是旋转屏幕,然后当你调用Activity的super.onCreate(savedState)时,你的片段被破坏并重新创建,这将调用默认构造函数=〉这会导致NullPointerException
因此,尊重Android Lint,使用setArguments()来传递Place的示例。
可以通过在片段内调用getArguments()来获取参数

ngynwnxp

ngynwnxp4#

理想情况下,一个片段只需要使用它的参数来重建它自己。参数化的构造函数不能很好地完成这个任务,因为在设备方向改变的情况下参数会丢失(尽管你可以通过调用setRetainInstance来缓解这个问题)。
使用静态方法而不是构造函数来创建片段。
例如:

public static MyFragment newInstance() {
    MyFragment f = new FragStateList_();
    Bundle args = new Bundle();
    args.putInt("someInt", someInt);
    args.putString("someString", someString);
    f.setArguments(args);
    return f;
}

然后,您应该包含一个默认构造函数,以便系统在需要时重新创建片段。
在您更新的问题中,您尝试将DisplayMetrics对象作为Long对象放入bundle中。这些类型不兼容。请不要传入DisplayMetrics。相反,请在您的片段中尝试此操作以获取DisplayMetrics对象。

DisplayMetrics metrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
kkbh8khc

kkbh8khc5#

理想情况下,一个片段只需要使用它的参数来重建它自己。参数化的构造函数并不能很好地完成这个任务,因为在设备方向改变的情况下参数会丢失(尽管你可以通过调用setRetainInstance来缓解这个问题)。

a1o7rhls

a1o7rhls6#

就像Kuffs写的那样,正确的方法是使用一个静态方法调用一个(默认)构造函数,在初始化之后,它会添加你的自定义值。你可以在这个方法中放置参数,例如:

public static PlaceDialogFragment newInstance(Place place, DisplayMetrics dm) {
    PlaceDialogFragment f = new PlaceDialogFragment(); //alternatively new Fragment()
    f.mPlace = place;
    f.mMetrics = dm;
    return f;
}

然后从Activity中调用它,如下所示:

PlaceDialogFragment pdf = PlaceDialogFragment.newInstance(param1, param2);

相关问题