2

Eclipse で生成されたマスター ディテール フローには、拡張するクラスにいくつかのコールバック マジックがありListFragmentます。Android と Java 初心者が一度にすべてを行うと、それがどのように見えるかという理由で、マジックと呼びます :)

以下のコードを考えると、誰かが私のためにいくつかの質問に答えることができます:

  1. onAttachのメソッドは何ListFragmentをしmCallbacks = (Callbacks) activityますか?
  2. のメソッド、実装が必要なメソッド、またはで呼び出さonItemSelectedれるメソッドはどれですか?onListItemClickListFragmentonItemSelectedFragmentActivity
  3. これらのonItemSelectedメソッドはすべてidof 型を取りますString( DummyContent idis であるためString)。に変更DummyContent idした場合long、どのonItemSelectedメソッドを変更する必要がありますか? 1つを変更しようとしましたFragmentActivityが、これは@Override許可されていないため、:(

ありがとうございました

public class RecordingListFragment extends ListFragment {

    private static final String STATE_ACTIVATED_POSITION = "activated_position";

    private Callbacks mCallbacks = sDummyCallbacks;
    private int mActivatedPosition = ListView.INVALID_POSITION;

    public interface Callbacks {

        public void onItemSelected(String id);
    }

    private static Callbacks sDummyCallbacks = new Callbacks() {
        @Override
        // NEEDS IMPLEMENTATION - i guess????
        public void onItemSelected(String id) {
        }
    };

...

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (!(activity instanceof Callbacks)) {
            throw new IllegalStateException("Activity must implement fragment's callbacks.");
        }

        mCallbacks = (Callbacks) activity;
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mCallbacks = sDummyCallbacks;
    }

    @Override
    public void onListItemClick(ListView listView, View view, int position, long id) {
        super.onListItemClick(listView, view, position, id);
        mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
    }

...

}

そして、もう1つのファイル...

public class RecordingListActivity extends FragmentActivity
        implements RecordingListFragment.Callbacks {

    private boolean mTwoPane;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_recording_list);
        getActionBar().setDisplayHomeAsUpEnabled(true);

        if (findViewById(R.id.recording_detail_container) != null) {
            mTwoPane = true;
            ((RecordingListFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.recording_list))
                    .setActivateOnItemClick(true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case android.R.id.home:
                NavUtils.navigateUpFromSameTask(this);
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onItemSelected(String id) {
        if (mTwoPane) {
            Bundle arguments = new Bundle();
            arguments.putString(RecordingDetailFragment.ARG_ITEM_ID, id);
            RecordingDetailFragment fragment = new RecordingDetailFragment();
            fragment.setArguments(arguments);
            getSupportFragmentManager().beginTransaction()
                    .replace(R.id.recording_detail_container, fragment)
                    .commit();

        } else {
            Intent detailIntent = new Intent(this, RecordingDetailActivity.class);
            detailIntent.putExtra(RecordingDetailFragment.ARG_ITEM_ID, id);
            startActivity(detailIntent);
        }
    }
}
4

1 に答える 1

4

ListFragment の onAttach メソッドは mCallbacks = (Callbacks) アクティビティで何をしますか?

onAttachコールバックでは、/ Activity(FragmentActivity接続Fragment/使用される) がそのFragmentインスタンスに (アクティビティパラメータを介して) 渡されます。その行は、それActivityCallbacksインターフェースにキャストして、後で で使用できるようにしますFragment(以下を参照)。そのインターフェイスを実装するActivity 必要があります。そうしないと、前の状態が原因でコードが失敗しifます。基本的に、onAttachメソッドのコードは次のように述べています

ListFragment の onListItemClick メソッドで呼び出される onItemSelected メソッド、実装が必要なメソッド、または FragmentActivity の onItemSelected メソッドはどれですか?

非常に生の説明では:型オブジェクト(インターフェースを実装するクラスを意味する)へRecordingListFragmentの参照(mCallbacksフィールド)を保持します。最初に、コードはこの参照にデフォルト/空の参照 ( sDummyCallbacks ) を割り当てますが、これは何もしません (したがって、そのonItemSelectedが空であるため、 の実装を提供する必要はありません)。場合によっては可能です (たとえば、フィールドに何かを割り当てずに呼び出す場合)。メソッドが実行されると、これが存在する場所への参照がにキャストされ、CallbacksCallbacksCallabacksCallbackssDummyCallbacksNullPointerExceptionmCallbacksonItemSelectedonAttachActivityFragmentCallbaksmCallbacks分野。これが発生した後、のメソッドを呼び出すとmCallbacks.onItemSelected()、メソッドが呼び出され、メソッドのコードが実行されます。後でが呼び出された場合、 は再び を指します。これが発生した後、呼び出しは何もしません。FragmentActivityonItemSelectedonDetachmCallbackssDummyCallbacksmCallbacks.onItemSelected()

上記のインターフェイス システムは、特定の実装RecordingListFragmentに結び付けられないため、コード内でより再利用可能なコンポーネントになるため、重要です。Activityユーザーがフラグメントのリスト内の項目をクリックするとonItemSelectedmCallbacks参照に対して を呼び出してonItemSelected、そのオブジェクト (この場合はアクティビティ) からメソッドを実行します。あなたのフラグメントは、インターフェイスの実装方法を知らず、気にもしません。たとえば、3 つのアクティビティがあり、それぞれがRecordingListFragmentフラグメントを使用しているとします。RecordingListFragmentクラスを使用する 3 つのアクティビティで動作させるには、クラスをどのように変更する必要がありますか?

これらの onItemSelected メソッドはすべて String 型の ID を取ります (DummyContent ID が String であるため)。DummyContent id を long に変更した場合、どの onItemSelected メソッドを変更する必要がありますか? FragmentActivity のものを変更しようとしましたが、これには @Override があるため、許可されませんでした:(

インターフェイスを変更します。

public interface Callbacks {

        public void onItemSelected(long id);
}

Java ファイルを保存すると、Eclipse は、このインターフェースが実装された場所に文句を言います (スーパークラス メソッドをオーバーライドする必要があります)。の場合sDummyCallbacks:

private static Callbacks sDummyCallbacks = new Callbacks() {
    @Override
    // NEEDS IMPLEMENTATION - i guess???? <- it doesn't need no implementation
    // it's purpose is to do nothing
    public void onItemSelected(long id) {
    }
};

また、インターフェースもFragmentActivity実装しているCallbacksため、それも変更する必要があります。

public class RecordingListActivity extends FragmentActivity
        implements RecordingListFragment.Callbacks {

    @Override
    public void onItemSelected(long id) {
        if (mTwoPane) {
    // ...

最後mCallbacksに、フラグメントで を使用します。

@Override
public void onListItemClick(ListView listView, View view, int position, long id) {     
    mCallbacks.onItemSelected(id);
}

時間をかけて Java 言語について少し勉強することをお勧めします。そうすれば、Android コード + Java の方法ではなく、Android コードを理解できるようになります。

于 2012-11-26T07:54:48.297 に答える