2013-07-02 4 views
1

Хорошо, поэтому я немного осмотрелся, и я думаю, что, возможно, я ошибусь. Я учил занятия в колледже для C++ как факультативы, и мне нравится возиться, но я все еще изучаю Java.Создание нового конкретного объекта из класса generic

Итак, я использую ListAdapter для размещения списка различных фрагментов, которые пользователь может выбрать, а затем выбранный фрагмент находится там, где был ListAdapter. Для этого нужны только массивы, не biggie.

/** 
* An array of POJOs used to hold the info about the fragments we'll be 
* swapping between This should be inserted into an array adapter of some 
* sort before being passed onto ListAdapter 
*/ 
private static final FragmentDetails[] FRAGMENT_DETAILS = { 
     new FragmentDetails(R.string.action_extraInfo, 
       R.string.extraInfo_description, 
       ExtraInfoFragment.class), 
     new FragmentDetails(R.string.action_largeTach, 
       R.string.largeTach_description, 
       LargeTachFragment.class), 
       ... 
      }; 
/** 
* @author PyleC1 
* 
*   A POJO that holds a class object and its resource info 
*/ 
public static class FragmentDetails { 
    private final Class<? extends Fragment> fragmentClass; 
    private int titleId; 
    private int descriptionId; 
/** 
    * @param titleId 
    *   The resource ID of the string for the title 
    * @param descriptionId 
    *   The resource ID of the string for the description 
    * @param fragmentClass 
    *   The fragment's class associated with this list position 
    */ 
    FragmentDetails(int titleId, int descriptionId, 
      Class<? extends Fragment> fragmentClass) { 
      super(); 
     this.titleId = titleId; 
     this.descriptionId = descriptionId; 
     this.fragmentClass = fragmentClass; 
    } 

    ... 
} 

Во всяком случае, я запускаю это через простой получить/установить класс под названием CustomArrayAdapter и отправить его к ListAdapter когда прикреплен фрагмент.

public void onAttach(Activity activity) { 
    super.onAttach(activity); 

    ListAdapter listAdapter = new CustomArrayAdapter(getActivity(), 
     FRAGMENT_DETAILS); 
    setListAdapter(listAdapter); 

}

До сих пор так хорошо. Проблема возникает, когда я пытаюсь запрограммировать прослушиватель onListItemClick. Кажется, я не могу найти способ создания реального объекта из информации о классе. Я огляделся и нашел функцию .getClass(). Функция newInstance() должна была быть примерно похожа на новую, поэтому я попробовал это.

public void onListItemClick(ListView l, View v, int position, long id) { 
    FragmentDetails details = (FragmentDetails) getListAdapter().getItem(position); 

     FragmentManager fragmentManager = ... 
     FragmentTransaction fragmentTransaction = ... 

     fragmentTransaction.add(R.id.fragment_container, 
           details.fragmentClass.newInstance()); 
} 

Выполнение этого в компиляторе делает исключение незаконного доступа. Я знаю, что что-то подобное было приемлемым в C++. Может быть, указатель на класс? Но это может быть полным неправильным способом в Java. Возможно, нет типов?

Моя единственная другая мысль, чтобы удалить

Class<? extends Fragment> fragmentClass 

родовые из массива и просто использовать переключатель заявление (от заголовка идентификатора может быть) на жесткий код транзакцию фрагмента, хотя это кажется немного безвкусным. Он отлично работает, если вы хотите, чтобы запустить новые Активности, вы можете просто передать общий класс намерению, как это:

Class<? extends Foo> bar = someFooClass.getClass(); 
new Intent(this, bar); 

Но фрагменты не принимают это.

ответ

1

Согласно documentation:

IllegalAccessException - if the class or its nullary constructor is not accessible. 

Так что, если вы хотите создать экземпляр фрагмента с помощью отражения, всех возможных классов <? extends Fragment> необходимости обеспечить конструктор public не-аргументов.

+1

Сладкое спасибо. Я не мог найти ответ, и я знал, что это просто. Мне также пришлось добавить в блок catch try и тип объекта. 'Object foo; try {foo = details.fragmentClass.newInstance(); } catch ... ' Тогда я мог бы вызвать:' fragmentTransaction.add (R.id.fragment_container, (Fragment) foo); 'Без проблем – DownrangeFuture

+0

Поскольку' newInstance() 'является общим, должно быть возможно назначить 'details.fragmentClass.newInstance();' непосредственно к переменной типа 'Fragment', если ваш' fragmentClass' по-прежнему параметризуется символом ' '. –

+0

Просто, чтобы проверить это, и это работает, как вы сказали. Моя настоящая работа мешала на некоторое время. лол. Спасибо за помощь. Я принял ваш ответ, надеюсь, что мне не нужно ничего делать. Я добавил в закладки эту страницу оракула. Официальные java-документы должны быть отличным ресурсом. Хотел бы я знать о них раньше. Документация в eclipse ужасно и предполагает, что вы знаете java очень хорошо, и андроидные документы не лучше. – DownrangeFuture

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