2

Ich habe eine Activity, die eine TabLayout enthält, die mit einer ViewPager verknüpft ist. Die ViewPager enthält drei Fragmente, und jedes Fragment hat eine RecyclerView enthält eine Liste von Artikeln. Wenn Sie auf einen Listeneintrag klicken, wird ein neuer Activity mit dem vollständigen Artikeltext gestartet. Nachdem ich die neue Activity starte, dann drücke die Zurück-Taste, um zur ersten Activity zurückzukehren, sie beginnt mit der ersten ausgewählten Registerkarte.Aktivität mit TabLayout Speicherstatus nach neuer Aktivität Start

Ich möchte in der Lage sein, eine neue Activity von jeder Registerkarte zu starten, dann, wenn die Zurück-Taste gedrückt wird, geht es zurück zur vorherigen Aktivität mit der gleichen Registerkarte ausgewählt. Und vorzugsweise den Zustand innerhalb der RecyclerView beibehalten (d. H. Wie weit nach unten gescrollt wird). Wie kann ich das erreichen?

Ich habe versucht, onSaveInstanceState zu verwenden, um die viewPager.getCurrentItem() zu speichern. Es funktionierte für, wenn das Gerät gedreht wurde, aber der gespeicherte Instanzzustand scheint nicht aufgerufen zu werden, nachdem ein neuer Activity gestartet wurde.


Das Tabbed Activity:

public class ArticleActivity extends BaseActivity { 

    @Bind(R.id.toolbar) Toolbar mToolbar; 
    @Bind(R.id.content) ViewPager mViewPager; 
    @Bind(R.id.tabs) TabLayout mTabLayout; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_article); 
     ButterKnife.bind(this); 
     setupActionBar(); 

     FragmentPagerAdapter adapter = new BaseFragmentPagerAdapter(this, getSupportFragmentManager(), 
       NewsFragment.newInstance(); 
       EventsFragment.newInstance(); 
       BulletinFragment.newInstance(); 
     ); 

     mViewPager.setAdapter(adapter); 
     mTabLayout.setupWithViewPager(mViewPager); 
    } 

    private void setupActionBar() { 
     setSupportActionBar(mToolbar); 

     ActionBar actionBar = getSupportActionBar(); 
     if(actionBar != null) { 
      actionBar.setDisplayShowTitleEnabled(true); 
      actionBar.setDisplayHomeAsUpEnabled(true); 
     } 
    } 
} 

Und eines der in der ViewPager enthaltenen Fragmente:

public class NewsFragment extends BaseFragment implements 
     Observer<DataResponse<NewsArticle>> { 

    @BindDimen(R.dimen.divider_padding_start) float mDividerPadding; 

    @Bind(R.id.recycler) RecyclerView mRecyclerView; 
    @Bind(R.id.progress) RecyclerView mProgressBar; 
    @Bind(R.id.refresh_layout) SwipeRefreshLayout mRefreshLayout; 

    @Inject RestService mRestService; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View view = inflater.inflate(R.layout.fragment_recycler_refresh, container, false); 
     ButterKnife.bind(this, view); 

     mRefreshLayout.setColorSchemeColors(
       ThemeUtil.getColorAttribute(getContext(), R.attr.colorAccent)); 
     mRefreshLayout.setProgressBackgroundColorSchemeColor(
       ThemeUtil.getColorAttribute(getContext(), R.attr.colorPrimary)); 
     mRefreshLayout.setOnRefreshListener(this::getArticles); 

     mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext())); 
     mRecyclerView.addItemDecoration(new DividerDecoration(getContext(), mDividerPadding)); 

     getArticles(); 

     return view; 
    } 


    @Override 
    public CharSequence getTitle(Context context) { 
     return context.getString(R.string.title_fragment_news); 
    } 

    @Override 
    publiv void onCompleted() { 
     mRefreshLayout.setRefreshing(false); 
    } 

    @Override 
    public void onError(Throwable exception) { 
     Timber.d(exception, "Failed to retrieve articles"); 
    } 

    @Override 
    public void onNext(DataResponse<NewsArticle> response) { 
     mProgressBar.setVisibility(View.GONE); 

     ArticleAdapter adapter = new ArticleAdapter(getContext(), response.data()); 
     adapter.setOnItemClickListener(this::onItemClick); 
     mRecyclerView.swapAdapter(adapter, false); 
    } 

    private void getArticles() { 
     mRestService.getNews().subscribeOn(Schedulers.newThread()) 
       .observeOn(AndroidSchedulers.mainThread()).subscribe(this); 
    } 

    public void onItemClick(Article article) { 
     Intent intent = new Intent(getActivity(), ArticleDetailActivity.class); 
     intent.putExtra("article", article); 
     startActivity(intent); 
    } 
} 

Ich war neugierig, so dass ich es gerade getestet. Die Activity wird nicht wirklich zerstört, wenn ich die neue Activity starte. Es wird nur zerstört (dann neu erstellt), nachdem ich die Zurück-Taste gedrückt habe. Ich verstehe nicht, warum es das tun würde, wenn die Activity nicht zerstört werden muss, wenn eine neue startet, warum sollte sie zerstört werden, wenn sie einfach in den Vordergrund tritt?

Ich habe eine andere Aktivität (meine SettingsActivity), die kein Elternteil hat Activity, und ruft nur finish(), wenn die Zurück-Taste gedrückt wird. Wenn ich dieses Activity von meinem ArticleActivity starte, wird das ArticleActivity nie zerstört und speichert seinen Zustand tadellos.

+0

Geben Sie Ihren Code ein! – Sourabh

+0

'aber der gespeicherte Instanzstatus scheint nicht aufgerufen zu werden, nachdem eine neue Aktivität gestartet wurde 'verwenden Sie stattdessen die Speichereinstellung. –

+0

@Sourabh Mit Code aktualisiert. – Bryan

Antwort

3

ich meine Antwort hier: ActionBar 'up' button destroys parent activity, 'back' does not

Und hier: How can I return to a parent activity correctly?

Die Eltern (ArticleActivity) wurde nach der Zurück Taste immer zerstört in dem Kind gedrückt wurde Activity da, dass das Verhalten der ist "Standard" Startmodus. Ich setze android:launchMode="singleTop" für die ArticleActivity in das Manifest, was mir das gewünschte Startverhalten gibt. Wenn jetzt Zurück in dem Kind Activity gedrückt wird, wird das übergeordnete Element nicht neu erstellt.