【问题标题】:ViewPager setCurrentItem(position) not working after orientation changeViewPager setCurrentItem(position)在方向更改后不起作用
【发布时间】:2017-10-18 07:20:22
【问题描述】:

我遇到了一个我似乎无法解决的问题,我需要一些帮助。

我的应用由一个包含片段的活动组成。用户点击建议后,将调用活动的 onSuggestionClicked(String cardId) 方法,并将活动的内容替换为新的 PagerFragment_new

 @Override
public void onSuggestionClicked(String cardId) {

    Log.d("activity","ID:\t" + cardId);


    PagerFragment_new pagerFragment = PagerFragment_new.getInstance(
            Injection.provideMtgDatabase(getApplicationContext()),
            activityPresenter.getAllCardExpansionIds(cardId),
            this);
    ActivityUtils.replaceFragment(getSupportFragmentManager(), pagerFragment, R.id.MTGRecallActivity_container);
}

PagerFragment_new 包含一个 ViewPager 来显示 CardInfoFragment_new

public class PagerFragment_new extends MtgRecallFragment_new implements PagerFragmentContract.View {

private View fragmentView;
private ViewPager viewPager;
private PagerFragmentContract.Presenter presenter;
private ScreenSlidePageAdapter_new adapter;
private MtgDatabase database;
private String[] printingsIds;
private ScreenSlidePageAdapter_new.ActivePresenterListener listener;

public PagerFragment_new() {
    //Required empty constructor
}

public static PagerFragment_new getInstance(MtgDatabase database, String[] printingsIds, ScreenSlidePageAdapter_new.ActivePresenterListener listener) {
    PagerFragment_new instance = new PagerFragment_new();
    instance.setDatabase(database);
    instance.setPrintingsIds(printingsIds);
    instance.listener = listener;
    return instance;
}

//other stuff

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    setRetainInstance(true);
    super.onCreate(savedInstanceState);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    setHasOptionsMenu(true);
    fragmentView = inflater.inflate(R.layout.fragment_pager, container, false);
    viewPager = (ViewPager) fragmentView.findViewById(R.id.PAGERFRAG_VIEWPAGER);
    adapter = new ScreenSlidePageAdapter_new(getChildFragmentManager(), printingsIds, database, viewPager);
    adapter.setListener(listener);
    viewPager.setAdapter(adapter);
    viewPager.setOffscreenPageLimit(1);
    return fragmentView;
}

@Override
public void setPresenter(PagerFragmentContract.Presenter presenter) {
    this.presenter = presenter;
}
}

管理ViewPager元素的适配器是ScreenSlidePageAdapter_new,它负责实例化CardInfoFragments。

public class ScreenSlidePageAdapter_new extends FragmentStatePagerAdapter {

private String[] printingsIds;
private String firstItemId;
private MtgDatabase database;
public ActivePresenterListener activity;
private ViewPager viewPager;

public ScreenSlidePageAdapter_new(FragmentManager fm, String[] printingsIds, MtgDatabase database, ViewPager viewPager) {
    super(fm);
    this.printingsIds =printingsIds;
    this.database = database;
    this.firstItemId = printingsIds[0];
    this.viewPager = viewPager;
}

@Override
public Fragment getItem(int position) {
    //todo create a bundle with cardId
    Bundle bundle = new Bundle();
    bundle.putString("CardID", printingsIds[position]);
    bundle.putString("FirstItemId", firstItemId);
    CardInfoFragment_new cardInfoFragment_new = CardInfoFragment_new.getInstance(viewPager);
    cardInfoFragment_new.setArguments(bundle);
    CardInfoPresenter cardInfoPresenter = new CardInfoPresenter(cardInfoFragment_new, database);
    activity.setActivePresenter(cardInfoPresenter);
    return cardInfoFragment_new;
}

@Override
public void destroyItem(ViewGroup container, int position, Object object) {
    super.destroyItem(container, position, object);

}

public void setListener(ActivePresenterListener listener) {
    this.activity = listener;
}
@Override
public int getCount() {
    return printingsIds.length;
}

public interface ActivePresenterListener {

    void setActivePresenter(BasePresenter presenter);
}}

最后是 CardInfoFragment 的代码:

public class CardInfoFragment_new extends MtgRecallFragment_new
    implements CardInfoContract.View,
    CardPrintingsAdapter.OnItemClickListener {

private ViewPager viewPager;

public CardInfoContract.Presenter presenter;
private View fragmentView;
private MTGCard mtgCard;
RecyclerView printingsRecyclerView;

CardPrintingsAdapter cardPrintingsAdapter;


private String firstItemId; //the first id 




public CardInfoFragment_new() {
    //required empty constructor
}

private void setViewPager(ViewPager viewPager) {
    this.viewPager = viewPager;
}

public static CardInfoFragment_new getInstance(ViewPager viewPager) {
    CardInfoFragment_new cardInfoFragment_new = new CardInfoFragment_new();
    cardInfoFragment_new.setViewPager(viewPager);
    return cardInfoFragment_new;
}

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    setRetainInstance(true);
    presenter.start();
    String cardId = getArguments().getString("CardID");
    firstItemId = getArguments().getString("FirstItemId");
    mtgCard = presenter.getCardData(cardId);
    super.onCreate(savedInstanceState);
}

@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    fragmentView = inflater.inflate(R.layout.fragment_card_info_new, container, false);
    setUpCardInfoView(fragmentView);
    return fragmentView;
}

public void setUpCardInfoView(final View view){
//others view set-up action omitted



    cardprintingsContainer =  (LinearLayout) view.findViewById(R.id.CARDINFO_printingsContainer);
    printingsRecyclerView = (RecyclerView)fragmentView.findViewById(R.id.CARDINFO_printings_recyclerView);
    final List<String> printings = presenter.getCardPrintings(firstItemId, mtgCard.getName());
    if (printings.size() < 40) {
        setupPrintings(printings,printingsRecyclerView);
    }
    else {
        LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);

        LinearLayout printingsRow = new LinearLayout(getContext());
        printingsRow = (LinearLayout)inflater.inflate(R.layout.card_info_printings_row,printingsRow,true);
        printingsRow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                setupPrintings(printings, printingsRecyclerView);
            }
        });
        ImageView printingssetImage = (ImageView)printingsRow.findViewById(R.id.CARDINFO_printingsRow_setImage);

        printingssetImage.setVisibility(View.INVISIBLE);
        TextView printingssetName = (TextView)printingsRow.findViewById(R.id.CARDINFO_printingsRow_setName);

        printingssetName.setText("Click to see all the "+printings.size()+ " versions");
        cardprintingsContainer.addView(printingsRow);
    }
}

public void setupPrintings(List<String> printings, RecyclerView recyclerView) {
    cardPrintingsAdapter =
            new CardPrintingsAdapter(getContext(), printings);
    cardPrintingsAdapter.setOnItemClickListener(this);
    UnscrollableLayoutManager layoutManager = new UnscrollableLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false);
    recyclerView.setAdapter(cardPrintingsAdapter);
    recyclerView.setLayoutManager(layoutManager);
}

@Override
public void onItemClick(View itemView, int position) {
    int i = viewPager.getAdapter().getCount();

    viewPager.setCurrentItem(position);
}



@Override
public void onDestroy() {
    presenter = null;
    mtgCard = null;
    super.onDestroy();
}}

当用户点击 RecyclerView 项目时,会调用 CardInfoFragment 的 onItemClick(View itemView, int position) 方法并将 viewpager 设置为当前位置。一切如预期。

问题

当方向改变时,片段能够保持它们的状态,但是 viewPager.setCurrentItem(position) 什么都不做,我无法改变显示的片段。

我已经检查过了:

  • ViewPager 实例和适配器实例对应于传递给 Fragments 的那些
  • onItemClick 被触发
  • 这个问题question1question2

如果我使用

android:configChanges="orientation|screenSize"

在清单中它即使在配置更改后也能工作,但我不想使用这个选项,因为不鼓励。 提前致谢!

【问题讨论】:

    标签: java android android-viewpager onclicklistener android-configchanges


    【解决方案1】:

    默认情况下,当 Android 上发生某些关键配置更改(常见示例是方向更改)时,Android 会完全重启正在运行的 Activity 以帮助其适应此类更改。

    当您在 AndroidManifest 中定义 android:configChanges="keyboardHidden|orientation" 时,您是在告诉 Android:“请不要在拔出键盘或旋转手机时进行默认重置;我要处理这是我自己。是的,我知道我在做什么”。

    所以使用 configChanges。 如果您不知道如何使用它,不鼓励使用它。但是对于这样的情况,我建议你使用它。如果没有,仍然会重新创建活动。这只需要时间和资源,我不明白你为什么希望这样。

    【讨论】:

    • 我明白你的意思:有时最好保留状态并且不要在重新创建所有内容时浪费资源,但在我的情况下,留下资源考虑我无法弄清楚为什么事情不是' t 按预期工作。
    猜你喜欢
    • 2013-10-19
    • 2017-01-15
    • 1970-01-01
    • 2015-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多