2016-01-26 2 views
2

У меня есть код, который я хочу обобщить.Метод реализации с 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. Что я делаю неправильно?

+0

Получаете ли вы какие-либо ошибки компиляции или исключения во время выполнения? Выполняет ли программа то, что вы хотите? –

+0

@ Эрик Г. Хагстром. Спасибо за ваш ответ . Действительно, я получил ошибку компиляции при создании SynthesisFragmentAdapter: «неизвестный класс f1, неизвестный класс f2»). Я думаю, что у меня что-то не хватает, но я не знаю почему. – ulquiorra

ответ

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; 
    } 
} 
+0

@ ErickG.Hagstrom обновленный код – gio

+1

Там ya go! Поместите тип args на метод 'init()' тоже! Хорошо, я думаю, у вас здесь победитель. –

+0

@gio Он отлично работает. Я никогда не видел такого объявления метода. Я бы никогда не нашел его без твоей помощи. Я не знаю, как поблагодарить вас. Ты спас мне много хлопот. Большое спасибо ! – ulquiorra

1

Проблема заключается в том, что система не знает тип f1 и f2 во время компиляции, что, когда он проверяет аргументы типа. Аргументы типа стираются во время выполнения, поэтому не могут быть проверены на основе любых аргументов метода.

Как насчет изменения вашего объявления SynthesisFragmentAdapter? Вам действительно нужна нотация extends в параметрах типа? Может быть, все, что вам действительно нужно:

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

Это просто не выглядит, как вы на самом деле нужно дженерики здесь.

+0

Большое спасибо! Первоначально я хотел обойтись без дженериков, потому что у меня были проблемы с ними, но это было обязательным в моих правилах спецификации :( – ulquiorra

Смежные вопросы