Android сохраняет выбранный элемент из фрагмента списка при изменении экрана (пейзаж)

Я новичок в Fragments и играю с ним. В основном я хочу макет мастер/деталь. Моя главная панель — это список песен, а детали — текст каждой песни.

Итак, вот что у меня есть:

MainActivity.class:

public class MainActivity extends FragmentActivity implements TitlesFragment.OnItemSelectListener{

// Whether or not we are in dual-pane mode
boolean mIsDualPane = false;

int mArtIndex = 0;

TitlesFragment mTitleFragment;
DescriptionFragment descriptionFragment;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    mTitleFragment = (TitlesFragment) getSupportFragmentManager().findFragmentById(
            R.id.titlesFragment);

    descriptionFragment = 
            (DescriptionFragment) getSupportFragmentManager().findFragmentById(R.id.descriptionFragment);

    View descriptionView = findViewById(R.id.descriptionFragment);
    mIsDualPane = descriptionView != null && descriptionView.getVisibility() == View.VISIBLE;

    Log.e("", "" + mIsDualPane);


    mTitleFragment.setSelection(0);
    if(mIsDualPane) {
        String description = Songs.lyrics[mArtIndex].toString();
        descriptionFragment.setDescriptionIntoFragment(description);
    }
    restoreSelection(savedInstanceState);

}

@Override
protected void onStart() {
    super.onStart();

}

/*
 * Implements the interface declared into TitlesFragment class
 * If the screen is in portrait mode launch a second activity instead of 
 * showing the text into the second fragment (as the second fragment is not visible)
 */
@Override
public void onItemSelect(int index) {
    String description = Songs.lyrics[index].toString();
    if(descriptionFragment != null && descriptionFragment.isInLayout())
    {
        descriptionFragment.setDescriptionIntoFragment(description);
    }
    else
    {
        Intent intent = new Intent(this, DescriptionActivity.class);
        intent.putExtra("lyrics", description);
        startActivity(intent);
    }
}

/** Restore category/article selection from saved state. */
void restoreSelection(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        if (mIsDualPane) {

            int artIndex = savedInstanceState.getInt("artIndex", 0);
            String description = Songs.lyrics[artIndex].toString();
            mTitleFragment.setSelection(artIndex);
            descriptionFragment.setDescriptionIntoFragment(description);
        }
    }
}

@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
    restoreSelection(savedInstanceState);
}

/** Save instance state. Saves current category/article index. */
@Override
protected void onSaveInstanceState(Bundle outState) {
    outState.putInt("artIndex", mArtIndex);
    super.onSaveInstanceState(outState);
}

TitlesFragment.class:

public class TitlesFragment extends ListFragment {

private OnItemSelectListener itemSelectListener;

//public interface used to communicate with activities
public interface OnItemSelectListener
{
    public void onItemSelect(int index);
}

//Check if the parent activity has implemented the public interface
//if not, throw an exception
@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    try
    {
        itemSelectListener = (OnItemSelectListener) activity;
    }
    catch(ClassCastException e)
    {
        throw new ClassCastException(activity.toString() + " must implement OnItemSelectListener");
    }
}


//launch the method described into the interface when the user click on an item
@Override
public void onListItemClick(ListView l, View v, int position, long id) {
    itemSelectListener.onItemSelect(position);
}


@SuppressLint("InlinedApi")
@Override
public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    int layout = 0;
    /*
     * Pick a different layout for the list item based on the sdk version,
     * as the simple_list_item_activated_1 is not compatible on devices
     * running sdk < 11 and could throw a fatal exception
     */
    if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.HONEYCOMB)
    {
        layout = android.R.layout.simple_list_item_1;
    }
        else layout = android.R.layout.simple_list_item_activated_1;
    ArrayAdapter<String> adapter = new ArrayAdapter<String>(getActivity(), layout, Songs.titles);
    setListAdapter(adapter);
    getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
    adapter.notifyDataSetChanged();
}

DescriptionActivity.class:

public class DescriptionActivity extends FragmentActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
    {
        finish();
        return;
    }
    else setContentView(R.layout.activity_description);

    Bundle extras = getIntent().getExtras();

    if(extras != null)
    {
        String lyrics = extras.getString("lyrics");
        DescriptionFragment descriptionFragment = 
                (DescriptionFragment) getSupportFragmentManager().findFragmentById(R.id.descriptionFragment);
        if(descriptionFragment != null && descriptionFragment.isInLayout())
        {
            descriptionFragment.setDescriptionIntoFragment(lyrics);
        }
    }
}

Проблема в том, что когда я выбрал 3-й элемент из списка в портретном режиме и перешел в альбомный режим, детализация неверна, он выбрал первую (0) деталь. Что не так с моим кодом? Любые идеи? Буду рад вашей помощи. Спасибо.


person Community    schedule 04.11.2014    source источник
comment
Когда ориентация изменилась на альбомную, есть ли какой-либо процесс (например, загрузка или сохранение чего-либо), который вы хотели бы выполнить? Если их нет, то, думаю, у меня есть для вас хороший ответ.   -  person Harry    schedule 04.11.2014
comment
Да, я сохраняю индекс   -  person    schedule 04.11.2014


Ответы (2)


Я не понял, где у вас функция setDescriptionIntoFragment? Почему вы не сохранили и не восстановили во фрагменте с onSaveInstanceState и restoreSelection?

Я думаю, что ваша позиция равна 0, потому что, когда вы вызываете setSelection, у вас нет данных в адаптере вашего фрагмента, и представления не создаются.

person QArea    schedule 04.11.2014

Если все, что вам нужно, это изменить ориентацию экрана на альбомную, просто откройте файл manifest.xml, найдите активность, ориентацию которой вы хотите изменить, добавьте android:configChanges именно так:

<activity
        android:name=".MyActivity"
        android:configChanges="orientation|keyboardHidden|screenSize" >
</activity>
person Harry    schedule 04.11.2014
comment
Поток «основной / детальный» заключается в правильной обработке как пейзажной, так и портретной ориентации, поэтому ваш ответ полностью упускает из виду суть. - person corsair992; 04.11.2014