泛型实现方法

时间:2016-01-26 18:49:21

标签: java android generics

我有一些我想要概括的代码。

我有一个通用类

public class SynthesisFragmentAdapter<A extends Fragment & IBaseFragment, B extends Fragment & IBaseFragment> extends FragmentPagerAdapter {

    private Context context;

    private Class<A> synthesisFragmentClass1;

    private Class<B> synthesisFragmentClass2;

    public SynthesisFragmentAdapter(FragmentManager fm, Context context, 
                                          Class<A> synthesisFragmentClass1, 
                                          Class<B> synthesisFragmentClass2) {
        super(fm);
        this.context = context;
        this.synthesisFragmentClass1 = synthesisFragmentClass1;
        this.synthesisFragmentClass2= synthesisFragmentClass2;
    }

}

当我需要动态地向SynthesisFragmentAdapter实例添加片段时,我想调用此类。我试过这个

// dynamically add same kind of fragment to adapter
    protected void init(Class a, Class b , Fragment f1 , Fragment f2) {

            TabLayout tab = (TabLayout) findViewById(R.id.tab);

            ViewPager pager = (ViewPager) findViewById(R.id.pager);

            SynthesisFragmentAdapter<f1 , f2> fragmentAdapter = new SynthesisFragmentAdapter<f1, f2>(getSupportFragmentManager(), this , a , b);
            pager.setAdapter(fragmentAdapter);
            tab.setupWithViewPager(pager);
        }

但我不认为这是正确的,因为我使用的片段除了扩展IBaseFragment之外还实现了一个接口(Fragment)。 我做错了什么?

2 个答案:

答案 0 :(得分:2)

参见方法init的声明及其用法。

更新的代码:

public class MainActivity extends AppCompatActivity {

protected <A extends Fragment & IBaseFragment, B extends Fragment & IBaseFragment> void init(Class<A> classA, Class<B> classB) {
    TabLayout tab = (TabLayout) findViewById(R.id.tab);
    ViewPager pager = (ViewPager) findViewById(R.id.pager);
    SynthesisFragmentAdapter<A, B> fragmentAdapter = new SynthesisFragmentAdapter<>(getSupportFragmentManager(), this, classA, classB);
    pager.setAdapter(fragmentAdapter);
    tab.setupWithViewPager(pager);
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    init(FragmentA.class, FragmentB.class);
}

interface IBaseFragment {
}


public static class FragmentA extends Fragment implements IBaseFragment {
}


public static class FragmentB extends Fragment implements IBaseFragment {

}

public class SynthesisFragmentAdapter<A extends Fragment & IBaseFragment, B extends Fragment & IBaseFragment> extends FragmentPagerAdapter {


    private Context context;

    private Class<A> synthesisFragmentClass1;

    private Class<B> synthesisFragmentClass2;

    public SynthesisFragmentAdapter(FragmentManager fm, Context context,
                                    Class<A> synthesisFragmentClass1,
                                    Class<B> synthesisFragmentClass2) {
        super(fm);
        this.context = context;
        this.synthesisFragmentClass1 = synthesisFragmentClass1;
        this.synthesisFragmentClass2 = synthesisFragmentClass2;
    }

    @Override
    public int getCount() {
        return 0;
    }

    @Override
    public Fragment getItem(int position) {
        return null;
    }
}

答案 1 :(得分:1)

问题是系统在编译时并不真正知道f1f2的类型,即检查类型参数时。类型参数在运行时被擦除,因此无法根据这些方法参数进行检查。

如何更改SynthesisFragmentAdapter的声明?你真的需要在类型参数中使用extends表示法吗?也许你真正需要的只是:

public class SynthesisFragmentAdapter extends FragmentPagerAdapter {
    // ...
    private Class<? extends Fragment> synthesisFragmentClass1;
    private Class<? extends Fragment> synthesisFragmentClass2;
    // etc.

在这里看起来你真的不需要泛型。