android中片段的参数化构造函数

时间:2014-01-08 08:33:40

标签: android android-fragments

我在片段中有以下构造函数: -

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

有任何建议如何解决这个问题?

5 个答案:

答案 0 :(得分:1)

使用setArguments代替,在处理片段时,在bundle中传递构造函数params,然后使用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对象,甚至不是parcelable,而是在bundle中添加相关的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 ;
}

注意:不要将公共构造函数与参数一起使用。

答案 1 :(得分:1)

你应该使用默认构造函数并将参数作为bundle传递的原因是因为当系统恢复你的片段状态时,它会调用默认构造函数并恢复bundle。如果从捆绑中获取参数,则可以正确恢复状态。

使用您当前的方法,在重新创建片段时,您在自定义构造函数中执行的所有操作都将丢失。

有关示例,请参阅this answer

答案 2 :(得分:1)

理想情况下,片段需要仅使用其参数重建自身。参数化构造函数对此不起作用,因为在(例如)设备方向更改的情况下参数会丢失(尽管您可以通过调用setRetainInstance来缓解这一点。)

使用静态方法而不是构造函数来创建片段。

e.g。

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放入捆绑包中。类型不兼容。不要传递DisplayMetrics。相反,请在您的片段中尝试获取DisplayMetrics对象。

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

答案 3 :(得分:1)

错误信息是对的!

避免将参数化构造函数用于Fragment / Activity ..

您可以通过进入Lint设置并排除规则+添加默认构造函数来执行“快速修复”。但快速解决方法并非如此。这将导致问题。 考虑这种情况,只需旋转屏幕,然后当您调用活动的super.onCreate(savedState)时,您的片段就会被销毁并重新创建,这将调用默认构造函数=&gt;这导致NullPointerException

尊重Android Lint,利用setArguments()传递Place的实例。如果Place是您的模型类,请将其设为Parcelable

您可以通过调用片段中的getArguments()来获取参数

答案 4 :(得分:-1)

就像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);