添加片段的通用方法,如何实现

Universal method for adding fragment, how to implement it

提问人:Stanly T 提问时间:8/29/2018 最后编辑:Stanly T 更新时间:9/9/2018 访问量:127

问:

我正在尝试创建用于片段添加的方法,我将能够多次使用,但我遇到了一些错误。 这是我的方法:

// global variable
fragManager = getSupportFragmentManager();
private <T> void findFragmentByTagAndAdd(String fragmentTag, Class<?> cls, T t){
    Fragment fragm = fragManager.findFragmentByTag(fragmentTag);
    if (fragm == null) {
        fragm = cls.newInstance(t);
        fragManager.beginTransaction()
                .add(R.id.host_fragment_container, fragm)
                .commit();
    } 
}

其中 是一些数据(例如某个模型类),必须传递给 fragment 的 newInstance 方法的 setArgumentsT t

我得到下一个错误:

    cannot be applied to given types;
                    fragm = cls.newInstance(t);
                               ^   required: no arguments   
found: T#1   reason: actual and formal argument lists differ in length
android-fragments

评论

0赞 Benoit 8/29/2018
参数是什么?是片段构造函数参数吗?T t
0赞 Stanly T 8/29/2018
T t 是一些数据(例如某个模型类),必须传递给 fragment 的 newInstance 方法的 setArguments。它将在 newInstance 方法中传递给 bundle
1赞 Benoit 8/29/2018
但是在您调用而不是 的样本中,您应该检查 Farhan Rahman Arnob 解决方案。Class.newInstance()Fragment.newInstance()
0赞 Stanly T 8/29/2018
是的,你是对的,我必须施放它,但这无济于事。我已经找到了决定

答:

0赞 Prashanth Verma 8/29/2018 #1

试试这个:

private void findFragmentByTagAndAdd(Fragment fragment, T t){
    FragmentManager fragmentManager = getSupportFragmentManager();
    FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
    if(fragment != null){
        fragment.setArguments(t)
        fragmentTransaction.add(R.id.fragment_container, fragment);
        fragmentTransaction.commit();
      }
}

您可以通过 setArguments() 传递数据

另请参阅此链接:https://developer.android.com/guide/components/fragments

评论

0赞 Stanly T 8/29/2018
谢谢,但这不是我需要的。您正在提出带有混凝土碎片的具体示例。但是我需要创建可以添加参数中提供的任何片段的方法。我的 fragManager 它是我已经定义的 fragmentManager
2赞 Benoit 8/29/2018 #2

替换以下内容:

fragm = cls.newInstance(t);

像这样:

Constructor constructor = cls.getConstructor(t.getClass());
fragm = (Fragment) constructor.newInstance(t);

评论

0赞 Stanly T 8/29/2018
在这种情况下,我收到一个错误:“错误:不兼容的类型:对象无法转换为 Fragment fragm = constructor.newInstance(t);”
1赞 Farhan Rahman Arnob 8/29/2018 #3

查看 findFragmentByTagAndAdd 方法的参数类 cls,不使用它,这对您来说很容易。

这样做:

像这样添加界面。

interface IYourDesireClass<T>{
   T newInstance();
}

将其实现到所需的类中。

class YourDesireClass implements IYourDesireClass<YourDesireClass>

像这样的重构方法

private <T extends IYourDesireClass> void findFragmentByTagAndAdd(String fragmentTag, T t){
    Fragment fragm = fragManager.findFragmentByTag(fragmentTag);
    if (fragm == null) {
        fragm = t.newInstance();
        fragManager.beginTransaction()
                .add(R.id.host_fragment_container, fragm)
                .commit();
    } 
}

还有一件事,尽量避免反思。反射对性能有负面影响。

0赞 Stanly T 8/29/2018 #4

多亏了 Benoit 的回答,我的方法终于开始工作了,它看起来像这样:

    private <T> void findFragmentByTagAndAdd(String fragmentTag, Class<?> cls, T data){ 
    Fragment fragm = fragManager.findFragmentByTag(fragmentTag);
    if (fragm == null) {
        try{
            Constructor constructor = cls.getConstructor(data.getClass());
            fragm = (Fragment) constructor.newInstance(data);
        } catch (Exception e) {
        }
        fragManager.beginTransaction()
                .add(R.id.host_fragment_container, fragm, fragmentTag)
                .commit();
    }
}

然后我就叫它:

findFragmentByTagAndAdd(DogsListFragment.DOGS_TAG, DogsListFragment.class, (Owner)owner);

感谢所有参与我问题的人,伙计们!

如果您使用多窗格 UI,并且必须在主机活动中多次添加/替换片段,则此方法将很有用