片段间交互慢刷新
Interaction between fragments slow refresh
在我的屏幕上,我有 2 个容器 - 左侧用于视图寻呼机中的 3 个片段,右侧用于单个片段。从右边开始,我增加了一些临时变量,并通过界面将这个变量传递给片段。我在视图寻呼机中切换片段,一切似乎都正常。但是,有两个问题。
首先,当我启动我的应用程序并尝试在视图寻呼机的第三个片段中实现临时变量时,存在 NPE。当然应该是,因为此时第三个片段还没有初始化(查看寻呼机只初始化实际片段和他两侧的片段,以便能够在片段之间滑动)。如何在开始时初始化第三个片段?我想我可以将数据暂时存储在第二个片段中,当第二个片段初始化时我可以将数据传递给第三个片段,但这似乎不是一个好的解决方案。
第二个问题是当我通过在其上滑动来初始化所有片段并且我返回到第三个的第一个片段视图已经消失(但它已被初始化)。当我实现临时变量并滑到第三个片段时,我可以看到这个变量,但在 +- 一秒后。有人可以向我解释为什么吗?没有这些知识,我无法解决这个问题:/
这是我的一些代码:
public class ThirdFragment extends Fragment {
View thisView;
TextView tempTextView;
String iterator;
public AchievFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
iterator = "Start";
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
thisView = inflater.inflate(R.layout.fragment_third, container, false);
tempTextView= (TextView) thisView.findViewById(R.id.tempTextView);
tempTextView.setText(iterator);
return thisView;
}
public void getVariable(String text) {
iterator = text;
tempTextView.setText(iterator);
}
这是第三个片段class。一开始我将迭代器(它是这个临时变量)初始化为全局变量以避免在初始化片段后出现npe。在 onCreateView 中,我将 TextView 的视图设置为此变量的值。应该可以正常工作,但是这个 +-1 秒的偏移让我很难过。
我认为这个代码示例应该足够了,其余的我想是标准的,但如果有人真的感兴趣,我会跳过其余部分。
我真的希望你能理解我刚刚写的东西。
这是主要(托管)activity代码:
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener {
ViewPager mViewPager;
FragmentPageAdapter ft;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.pager_container);
ft = new FragmentPageAdapter(getSupportFragmentManager());
mViewPager.setAdapter(ft);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
RightFragment gameFragment = new RightFragment();
ft.replace(R.id.rightFragment_container, rightFragment,"RightFragment");
ft.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public void OnUpdateFirst(String text) {
FirstFragment firstFragment = (FirstFragment) ft.instantiateItem(mViewPager,0);
firstFragment.getVariable(text);
}
@Override
public void OnUpdateSecond(String text) {
SecondFragment secondFragment = (SecondFragment) ft.instantiateItem(mViewPager,1);
secondFragment.getVariable(text);
}
@Override
public void OnUpdateThird(String text) {
ThirdFragment thirdFragment = (ThirdFragment) ft.instantiateItem(mViewPager,2);
thirdFragment.getVariable(text);
}
}
片段页面适配器代码:
public class FragmentPageAdapter extends FragmentPagerAdapter {
public FragmentPageAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
switch (arg0)
{
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
default:
break;
}
return null;
}
@Override
public int getCount() {
return 3;
}
在我初始化它之前尝试在第三个片段上实现变量时的预期(在我启动应用程序后的示例中)
06-14 16:47:25.621 27246-27246/com.package.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.package.app.ThirdFragment.getVariable(ThirdFragment.java:37)
at com.package.app.MainActivity.OnUpdateThird(MainActivity.java:59)
at com.package.app.RightFragment.onClick(RightFragment.java:57)
at android.view.View.performClick(View.java:4101)
at android.view.View$PerformClick.run(View.java:17082)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4940)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
at dalvik.system.NativeStart.main(Native Method)
关于您的第一个问题,您可以在初始化 ViewPager 后立即调用 setOffscreenPageLimit(2)
方法。默认情况下,它设置为 1,这意味着适配器创建一个当前屏幕上的页面和下一个屏幕上的页面。
在我的屏幕上,我有 2 个容器 - 左侧用于视图寻呼机中的 3 个片段,右侧用于单个片段。从右边开始,我增加了一些临时变量,并通过界面将这个变量传递给片段。我在视图寻呼机中切换片段,一切似乎都正常。但是,有两个问题。
首先,当我启动我的应用程序并尝试在视图寻呼机的第三个片段中实现临时变量时,存在 NPE。当然应该是,因为此时第三个片段还没有初始化(查看寻呼机只初始化实际片段和他两侧的片段,以便能够在片段之间滑动)。如何在开始时初始化第三个片段?我想我可以将数据暂时存储在第二个片段中,当第二个片段初始化时我可以将数据传递给第三个片段,但这似乎不是一个好的解决方案。
第二个问题是当我通过在其上滑动来初始化所有片段并且我返回到第三个的第一个片段视图已经消失(但它已被初始化)。当我实现临时变量并滑到第三个片段时,我可以看到这个变量,但在 +- 一秒后。有人可以向我解释为什么吗?没有这些知识,我无法解决这个问题:/
这是我的一些代码:
public class ThirdFragment extends Fragment {
View thisView;
TextView tempTextView;
String iterator;
public AchievFragment() {
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
iterator = "Start";
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
thisView = inflater.inflate(R.layout.fragment_third, container, false);
tempTextView= (TextView) thisView.findViewById(R.id.tempTextView);
tempTextView.setText(iterator);
return thisView;
}
public void getVariable(String text) {
iterator = text;
tempTextView.setText(iterator);
}
这是第三个片段class。一开始我将迭代器(它是这个临时变量)初始化为全局变量以避免在初始化片段后出现npe。在 onCreateView 中,我将 TextView 的视图设置为此变量的值。应该可以正常工作,但是这个 +-1 秒的偏移让我很难过。
我认为这个代码示例应该足够了,其余的我想是标准的,但如果有人真的感兴趣,我会跳过其余部分。
我真的希望你能理解我刚刚写的东西。
这是主要(托管)activity代码:
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener {
ViewPager mViewPager;
FragmentPageAdapter ft;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mViewPager = (ViewPager) findViewById(R.id.pager_container);
ft = new FragmentPageAdapter(getSupportFragmentManager());
mViewPager.setAdapter(ft);
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
RightFragment gameFragment = new RightFragment();
ft.replace(R.id.rightFragment_container, rightFragment,"RightFragment");
ft.commit();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@Override
public void OnUpdateFirst(String text) {
FirstFragment firstFragment = (FirstFragment) ft.instantiateItem(mViewPager,0);
firstFragment.getVariable(text);
}
@Override
public void OnUpdateSecond(String text) {
SecondFragment secondFragment = (SecondFragment) ft.instantiateItem(mViewPager,1);
secondFragment.getVariable(text);
}
@Override
public void OnUpdateThird(String text) {
ThirdFragment thirdFragment = (ThirdFragment) ft.instantiateItem(mViewPager,2);
thirdFragment.getVariable(text);
}
}
片段页面适配器代码:
public class FragmentPageAdapter extends FragmentPagerAdapter {
public FragmentPageAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int arg0) {
switch (arg0)
{
case 0:
return new FirstFragment();
case 1:
return new SecondFragment();
case 2:
return new ThirdFragment();
default:
break;
}
return null;
}
@Override
public int getCount() {
return 3;
}
在我初始化它之前尝试在第三个片段上实现变量时的预期(在我启动应用程序后的示例中)
06-14 16:47:25.621 27246-27246/com.package.app E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.NullPointerException
at com.package.app.ThirdFragment.getVariable(ThirdFragment.java:37)
at com.package.app.MainActivity.OnUpdateThird(MainActivity.java:59)
at com.package.app.RightFragment.onClick(RightFragment.java:57)
at android.view.View.performClick(View.java:4101)
at android.view.View$PerformClick.run(View.java:17082)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4940)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:798)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:565)
at dalvik.system.NativeStart.main(Native Method)
关于您的第一个问题,您可以在初始化 ViewPager 后立即调用 setOffscreenPageLimit(2)
方法。默认情况下,它设置为 1,这意味着适配器创建一个当前屏幕上的页面和下一个屏幕上的页面。