1

私のアクティビティでは、ユーザーがアイテムをクリックすると、フラグメントをロードしてバックスタックに追加しています。これはうまく機能し、バックスタックはうまくロードされます。

残念ながら、デバイスを回転させると、アクティビティが空白になります。SOとGoogleで可能な限りすべてを試しました。

ユーザーがクリックするとフラグメントを置き換え、背面をナビとして処理するだけで、ナビゲーションを自分で管理してみました。これは正常に動作しますが、スタックが 1 より大きい場合、ナビゲーション ドロワーを変更して戻る矢印を表示するようにコーディングした自動機能が失われます。

スタック全体を削除し、デバイスを回転させたときにユーザーがクリックする順序で個々のフラグメントを追加しようとしました。これはうまくいきません。取り外しと交換がうまくいかないようです。

fragmentManager.findbytag を使用してフラグメントを追加しようとしましたが、「フラグメントが既に追加されました」という不正な状態例外がスローされます。SOでトランジションを削除する解決策を見つけました。一度動作して停止しました。理由はわかりません。

トーストを入れて、バックスタックのカウントが変更されるたびに表示されるようにしましたが、スタックは追加後も正しいカウントを示しているが、ページはまだ空白であることに気付きました。アクティビティを終了して前のアクティビティに戻るには、2 つのバックプレスが必要です。

フラグメントで onCreateView が呼び出されているかどうかを確認するブレークポイントを配置しました。はい、電話が回転するたびに呼び出されます。

基本的に、あきらめたので、私のコードは次のようになります。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        mPosition = 1;

        super.onCreate(savedInstanceState);

        if(savedInstanceState != null) {
            mLastArtistFragmentTag = savedInstanceState.getString(SAVE_FRAGMENT_LAST_ARTIST);
            mLastAlbumFragmentTag = savedInstanceState.getString(SAVE_FRAGMENT_LAST_ALBUM);
            mLastSongFragmentTag = savedInstanceState.getString(SAVE_FRAGMENT_LAST_SONG);

            mLastFragmentType = savedInstanceState.getInt(SAVE_FRAGMENT_LAST_TYPE);
        }

        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Load();
            }
        }, 100);
    }

    void Load() {

        findViewById(R.id.loading).setVisibility(View.GONE);

        ViewStub stub = (ViewStub) findViewById(R.id.container_stub);
        stub.setLayoutResource(R.layout.activity_music);
        stub.inflate();




    if(mLastArtistFragmentTag == null) {
        getSupportFragmentManager().beginTransaction()
                .replace(R.id.base_container, new Artists(), FRAGMENT_TAG_BASE)


                   .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
                    .commit();
        }
            else {
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.base_container, new Artists(), FRAGMENT_TAG_BASE)
                    //.add(R.id.base_container, Albums.newInstance(mLastArtistFragmentTag), mLastArtistFragmentTag)
//.add(R.id.base_container, getSupportFragmentManager().findFragmentByTag(mLastArtistFragmentTag), mLastArtistFragmentTag)
                    //.addToBackStack(mLastArtistFragmentTag)
                .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN)
                .commit();
        }

    }

@Override
    public void onSaveInstanceState(Bundle instanceState) {
        super.onSaveInstanceState(instanceState);

        if(mLastFragmentType != -1) {
            instanceState.putString(SAVE_FRAGMENT_LAST_ARTIST, mLastArtistFragmentTag);
            instanceState.putString(SAVE_FRAGMENT_LAST_ALBUM, mLastAlbumFragmentTag);
            instanceState.putString(SAVE_FRAGMENT_LAST_SONG, mLastSongFragmentTag);

            instanceState.putInt(SAVE_FRAGMENT_LAST_TYPE, mLastFragmentType);
        }

    }

フラグメントコードはこんな感じ

    @Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    super.onCreateView(inflater, container, savedInstanceState);

    final ListView listView = (ListView) inflater.inflate(R.layout.fragment_albums, container, false);
    listView.addHeaderView(inflater.inflate(R.layout.header_artist_info, null));

    try {
        String uri2 = "http://someurl";
        NetworkRequest.FetchJSON(Request.Method.GET, uri2, new Response.Listener<JSONObject>() {
            @Override
            public void onResponse(JSONObject response) {
                try {
                    JSONArray songs = response.getJSONArray("songs");
                    //HashMap<String, Song> recentSongs = new HashMap<String, Song>();
                    ArrayList<Song> latest = new ArrayList<Song>();

                    for (int i = 0; i < songs.length(); i++) {
                        Song s = new Song(songs.getJSONObject(i));
                        latest.add(s);
                    }

                    AlbumListAdapter pgiAdapter = new AlbumListAdapter(getActivity(), latest);
                    SwingBottomInAnimationAdapter swingBottomInAnimationAdapter = new SwingBottomInAnimationAdapter(pgiAdapter);

                    swingBottomInAnimationAdapter.setAbsListView(listView);
                    listView.setAdapter(swingBottomInAnimationAdapter);

                } catch (JSONException ex) {
                    Toast.makeText(getActivity(), ex.getMessage(), Toast.LENGTH_LONG).show();
                }
            }
        });
    } catch (Exception ex) {
        Toast.makeText(getActivity(), ex.getMessage(), Toast.LENGTH_LONG).show();
    }

    return listView;
}

質問する前に、はい、Load メソッドを onCreate メソッド内に移動しました。それでもうまくいきませんでした。

私は本当にここで立ち往生しており、あなたの助けが必要です. 私を助けてください。ありがとう。

4

2 に答える 2

5

アクティビティを再作成する方法によっては、フラグメントの状態の変更を手動で処理する必要がある場合があります。最悪の場合、フラグメントをデタッチしてから再度アタッチして、ビューを強制的に再作成する必要がある場合があります。

public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
  transaction.detach(activeFrag).attach(activeFrag).commit();
}

AndroidManifest.xml に正しいフックを設定します

android:configChanges="orientation|screenSize"
于 2014-06-26T11:01:07.787 に答える
1

@MLProgrammer-CiM のおかげで、この問題の修正が見つかりました。

if(mLastArtistFragmentTag == null) {
    getSupportFragmentManager().beginTransaction()
            .replace(R.id.base_container, new Artists(), FRAGMENT_TAG_BASE)
            .setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE)
            .commit();
} else {
    FragmentTransaction ft = getSupportFragmentManager().beginTransaction();

    Fragment base = getSupportFragmentManager().findFragmentByTag(FRAGMENT_TAG_BASE);
    Fragment art = getSupportFragmentManager().findFragmentByTag(mLastArtistFragmentTag);

    ft.detach(base).attach(base).detach(art).attach(art).commit();
}

バックスタック内のすべてのアイテムに対してこれを行う必要があると思います。少なくともそれが機能することを嬉しく思います。ついに!

于 2014-06-25T15:30:31.197 に答える