方向更改后ViewPager setCurrentItem(position)不起作用

时间:2017-05-18 12:55:52

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

我正面临一个似乎无法解决的问题,我想要一些帮助。

我的应用程序由包含片段的活动组成。在用户点击建议后,调用活动的方法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被解雇
  • 此问题question1 question2

如果我使用

android:configChanges="orientation|screenSize"
清单中的

即使在配置更改后也能正常工作,但我不想使用此选项,因为不鼓励使用此选项。 提前致谢!

1 个答案:

答案 0 :(得分:0)

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

当你定义android:configChanges =&#34; keyboardHidden | orientation&#34;在您的AndroidManifest中,您正在告诉Android:&#34;当拔出键盘或手机旋转时,请不要执行默认重置;我想自己处理这件事。是的,我知道我在做什么&#34;。

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