1

さて、私は周りを見回しましたが、これは間違っているのではないかと思います。私は選択科目として大学で C++ のクラスを受講しており、いじくり回すのが好きですが、まだ Java を学んでいます。

そのため、ListAdapter を使用して、ユーザーが選択できるさまざまなフラグメントのリストを配置しています。ユーザーが選択したフラグメントは、ListAdapter があった場所に配置されます。配列のみが必要で、大したことはありません。

/**
 * 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 という単純な get/set クラスを介してこれを実行し、フラグメントがアタッチされたときにそれを ListAdapter に送信します。

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

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

}

ここまでは順調ですね。onListItemClick リスナーをプログラムしようとすると、問題が発生します。クラス情報から実際のオブジェクトを作成する方法が見つからないようです。私は周りを見回して、 .getClass().newInstance() 関数が new とほぼ同じであるはずだったので、これを試しました。

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());
}

これを行うと、コンパイラで Illegal Access Exception がスローされます。C ++でも同様のことが受け入れられることを知っています。多分クラスポインタ?しかし、それは Java では完全に間違った方法かもしれません。おそらくタイプセーフではありませんか?

私の他の唯一の考えは、

Class<? extends Fragment> fragmentClass

配列からジェネリックを取得し、switch ステートメント (おそらくタイトル ID から) を使用してフラグメント トランザクションをハード コーディングしますが、それは少し洗練されていないように見えます。新しいアクティビティを起動したい場合は問題なく動作します。ジェネリック クラスを次のようにインテントに渡すだけです。

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

しかし、フラグメントはこれを受け入れません。

4

1 に答える 1

1

ドキュメントによると:

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

したがって、リフレクションを使用してフラグメントをインスタンス化する場合は、可能なすべてのクラスで引数なしのコンストラクター<? extends Fragment>を提供する必要があります。public

于 2013-07-02T16:08:26.003 に答える