我的 Activity 使用 TabLayout + ViewPager。
此处的选项卡和页面数量是动态的,具体取决于从服务器获取的数据。
崩溃是通过 Crashlytics 报告的,我无法复制它。
我的 Activity 代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
boolean isAppRestarting = PrefUtils.getBoolean("app_restarting", false);
if (isAppRestarting) {
super.onCreate(null);
this.savedInstanceState = null;
} else {
super.onCreate(savedInstanceState);
this.savedInstanceState = savedInstanceState;
}
initSlidingTabs();
fetchSomeData(); // see onDataFetched() below
}
private void initSlidingTabs() {
List<FragmentWithTitle> sdsTabs = new ArrayList<>();
Logger.i("There is saved instance state");
ArrayList<String> titles = savedInstanceState.getStringArrayList(TAB_TITLES);
if (titles != null) {
for (int i = 0; i < titles.size(); i++) {
if (getFragment(i) != null) {
sdsTabs.add(new FragmentWithTitle(getFragment(i), titles.get(i)));
}
}
}
mTabsAdapter = new MyTabsAdapter(getSupportFragmentManager(), sdsTabs);
mViewPager = (ViewPager) findViewById(R.id.layoutViewPagerSlidingTabs);
mViewPager.setAdapter(mTabsAdapter);
mViewPager.setOffscreenPageLimit(2);
mSlidingTabs = (TabLayout) findViewById(R.id.tabs);
mSlidingTabs.setupWithViewPager(mViewPager);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (mTabsAdapter != null) {
outState.putStringArrayList(TAB_TITLES, mTabsAdapter.getTitles());
}
}
private Fragment getFragment(int position) {
return savedInstanceState == null ? mTabsAdapter.getItem(position) : getSupportFragmentManager()
.findFragmentByTag(getFragmentTag(position));
}
private String getFragmentTag(int position) {
return "android:switcher:" + R.id.layoutViewPagerSlidingTabs + ":" + position;
}
/**
Callback of fetchData() in onCreate()
*/
private void onDataFetched(List<AbcObject> abcObjects) {
if (savedInstanceState == null) {
if (abcObjects != null) {
for (AbcObject abcObject : abcObjects) {
mTabsAdapter.addTab(new FragmentWithTitle(AbcFragment.newInstance(), abcObject.getTitle()));
}
}
} else {
Logger.d("There is saved instance state");
ArrayList<String> titles = savedInstanceState.getStringArrayList(TAB_TITLES);
if (titles != null) {
for (int i = 0; i < titles.size(); i++) {
mTabsAdapter.addTab(new FragmentWithTitle(getFragment(i), titles.get(i)));
}
}
}
mTabsAdapter.notifyDataSetChanged();
}
MyTabsAdapter:
public class MyTabsAdapter extends FragmentPagerAdapter {
private List<FragmentWithTitle> mTabs = new ArrayList<>();
public MyTabsAdapter(FragmentManager fm, List<FragmentWithTitle> sdsTabs) {
super(fm);
this.mTabs = sdsTabs;
}
@Override
public Fragment getItem(int position) {
return mTabs.get(position).getFragment();
}
@Override
public CharSequence getPageTitle(int position) {
return mTabs.get(position).getTitle();
}
@Override
public int getCount() {
return this.mTabs.size();
}
public int getItemPosition(Object object) {
return POSITION_NONE;
}
/**
* Prevent java.lang.IllegalStateException Fragment no longer exists for key android:target_state: index 5
*
* @return
*/
@Override
public Parcelable saveState() {
return null;
}
public ArrayList<String> getTitles() {
ArrayList<String> titles = new ArrayList<>();
for (int i = 0; i < mTabs.size(); i++) {
titles.add((String) mTabs.get(i).getTitle());
}
return titles;
}
public void addTab(FragmentWithTitle fragmentWithTitle) {
mTabs.add(fragmentWithTitle);
}
}
完整的堆栈跟踪:
Fatal Exception: java.lang.IllegalStateException: Can't change tag of fragment ShopFrag{4dbb6e90 #0 id=0x7f1200dd android:switcher:2131886301:0}: was android:switcher:2131886301:0 now android:switcher:2131886301:9
at android.support.v4.app.BackStackRecord.doAddOp(BackStackRecord.java:444)
at android.support.v4.app.BackStackRecord.add(BackStackRecord.java:426)
at android.support.v4.app.FragmentPagerAdapter.instantiateItem(FragmentPagerAdapter.java:103)
at android.support.v4.view.ViewPager.addNewItem(ViewPager.java:1038)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1252)
at android.support.v4.view.ViewPager.populate(ViewPager.java:1120)
at android.support.v4.view.ViewPager.onMeasure(ViewPager.java:1646)
at android.view.View.measure(View.java:17396)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:17396)
at android.support.v4.widget.DrawerLayout.onMeasure(DrawerLayout.java:1081)
at android.view.View.measure(View.java:17396)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.support.v7.widget.ContentFrameLayout.onMeasure(ContentFrameLayout.java:139)
at android.view.View.measure(View.java:17396)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:17396)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at android.view.View.measure(View.java:17396)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365)
at android.widget.LinearLayout.measureChildBeforeLayout(LinearLayout.java:1410)
at android.widget.LinearLayout.measureVertical(LinearLayout.java:695)
at android.widget.LinearLayout.onMeasure(LinearLayout.java:588)
at android.view.View.measure(View.java:17396)
at android.view.ViewGroup.measureChildWithMargins(ViewGroup.java:5365)
at android.widget.FrameLayout.onMeasure(FrameLayout.java:310)
at com.android.internal.policy.impl.PhoneWindow$DecorView.onMeasure(PhoneWindow.java:2505)
at android.view.View.measure(View.java:17396)
at android.view.ViewRootImpl.performMeasure(ViewRootImpl.java:2175)
at android.view.ViewRootImpl.measureHierarchy(ViewRootImpl.java:1316)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1513)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1200)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:6401)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:803)
at android.view.Choreographer.doCallbacks(Choreographer.java:603)
at android.view.Choreographer.doFrame(Choreographer.java:573)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:789)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:157)
at android.app.ActivityThread.main(ActivityThread.java:5335)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1265)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1081)
at dalvik.system.NativeStart.main(NativeStart.java)
FragmentWithTitle:
public class FragmentWithTitle {
public FragmentWithTitle(Fragment mFragment, CharSequence mTitle) {
this.fragment = mFragment;
this.title = mTitle;
}
public Fragment getFragment() {
return fragment;
}
public void setFragment(Fragment fragment) {
this.fragment = fragment;
}
public CharSequence getTitle() {
return title;
}
public void setTitle(CharSequence title) {
this.title = title;
}
private Fragment fragment;
private CharSequence title;
}
最佳答案
FragmentPagerAdapter 已经为您缓存了 Fragments。每个 fragment 都被分配一个标签,然后 FragmentPagerAdapter 尝试调用 findFragmentByTag。如果 findFragmentByTag 的结果是 null,它只会调用 getItem()。
您可能会收到此错误,因为您将相同的 fragment 实例添加到列表中。您应该为每个页面创建一个新实例。
示例表单文档:
//...
public static class MyAdapter extends FragmentPagerAdapter {
public MyAdapter(FragmentManager fm) {
super(fm);
}
@Override
public int getCount() {
return NUM_ITEMS;
}
@Override
public Fragment getItem(int position) {
return ArrayListFragment.newInstance(position);// IMPORTANT
}
}
//..
关于android - 非法状态异常 : Can't change tag of fragment was android:switcher now android:switcher,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41974251/
我需要在客户计算机上运行Ruby应用程序。通常需要几天才能完成(复制大备份文件)。问题是如果启用sleep,它会中断应用程序。否则,计算机将持续运行数周,直到我下次访问为止。有什么方法可以防止执行期间休眠并让Windows在执行后休眠吗?欢迎任何疯狂的想法;-) 最佳答案 Here建议使用SetThreadExecutionStateWinAPI函数,使应用程序能够通知系统它正在使用中,从而防止系统在应用程序运行时进入休眠状态或关闭显示。像这样的东西:require'Win32API'ES_AWAYMODE_REQUIRED=0x0
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="
关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion在首页我有:汽车:VolvoSaabMercedesAudistatic_pages_spec.rb中的测试代码:it"shouldhavetherightselect"dovisithome_pathit{shouldhave_select('cars',:options=>['volvo','saab','mercedes','audi'])}end响应是rspec./spec/request
当我的预订模型通过rake任务在状态机上转换时,我试图找出如何跳过对ActiveRecord对象的特定实例的验证。我想在reservation.close时跳过所有验证!叫做。希望调用reservation.close!(:validate=>false)之类的东西。仅供引用,我们正在使用https://github.com/pluginaweek/state_machine用于状态机。这是我的预订模型的示例。classReservation["requested","negotiating","approved"])}state_machine:initial=>'requested