Java Android中的片段和ViewPager
我有一个ViewPager,允许用户在5个不同的视图之间滑动,每个“视图”扩展片段 我有自己的适配器,它扩展了FragmentPagerAdapter,并将getItem()实现为 这很好,用户可以在5个不同的视图之间滑动。但问题来了:前4个视图中的每一个都包含用户可以交互的视图,如Button和EditText 然后我希望最后一页(第5页)显示前4页(片段)中所有视图中的所有用户输入值。我该怎么做 我找不到任何方法从前面的片段中读取用户输入值。视图可能不再存在(但如果用户返回,将重新创建)Java Android中的片段和ViewPager,java,android,android-viewpager,fragment,Java,Android,Android Viewpager,Fragment,我有一个ViewPager,允许用户在5个不同的视图之间滑动,每个“视图”扩展片段 我有自己的适配器,它扩展了FragmentPagerAdapter,并将getItem()实现为 这很好,用户可以在5个不同的视图之间滑动。但问题来了:前4个视图中的每一个都包含用户可以交互的视图,如Button和EditText 然后我希望最后一页(第5页)显示前4页(片段)中所有视图中的所有用户输入值。我该怎么做 我找不到任何方法从前面的片段中读取用户输入值。视图可能不再存在(但如果用户返回,将重新创建) 我
我似乎无法得到现有的碎片 2个解决方案浮现在我脑海中 第一个是在调用前4个片段的onpause()方法时保存用户输入数据。您可以将数据保存到首选项,然后从第5个片段中检索它 第二种方法是在刷卡时保留碎片。这样刷卡会更快更干净,每次刷卡时都要重新创建碎片:
yourcustomviewpager.setOffscreenPageLimit(5);
关于setOffscreenPageLimit发件人:
设置在空闲状态下视图层次结构中当前页面两侧应保留的页数。超出此限制的页面将在需要时从适配器重新创建。
这是作为一种优化提供的。如果您事先知道需要支持的页面数量,或者页面上有延迟加载机制,调整此设置可以提高页面动画和交互的平滑度。如果您有少量页面(3-4个)可以同时保持活动状态,则在用户页面来回移动时,新创建的视图子树的布局所花费的时间将更少。
您应该将此限制保持在较低的水平,尤其是在页面布局复杂的情况下。此设置默认为1
我想到了两个解决办法 第一个是在调用前4个片段的onpause()方法时保存用户输入数据。您可以将数据保存到首选项,然后从第5个片段中检索它 第二种方法是在刷卡时保留碎片。这样刷卡会更快更干净,每次刷卡时都要重新创建碎片:
yourcustomviewpager.setOffscreenPageLimit(5);
关于setOffscreenPageLimit发件人:
设置在空闲状态下视图层次结构中当前页面两侧应保留的页数。超出此限制的页面将在需要时从适配器重新创建。
这是作为一种优化提供的。如果您事先知道需要支持的页面数量,或者页面上有延迟加载机制,调整此设置可以提高页面动画和交互的平滑度。如果您有少量页面(3-4个)可以同时保持活动状态,则在用户页面来回移动时,新创建的视图子树的布局所花费的时间将更少。
您应该将此限制保持在较低的水平,尤其是在页面布局复杂的情况下。此设置默认为1
我会考虑使用一个自定义对象来保持每个片段的数据填充。比如:
public class FillerData implements Parcelable {
private String page0$data0;
private String page0$data1;
private String page0$data2;
// getters and setters if you wish
// implement Parcelable interface as this object will be managed by host activity
}
您只有一个这样的对象由父活动管理,父活动将实现一个用于公开此对象的接口:
public static interface FillerDataExposer {
public FillerData exposeFiller();
}
public class MyFragmentHostActivity extends FragmentActivity implements FillerDataExposer {
private static final String FILLER_KEY = "FILLER_KEY";
private FillerData myFillerData;
protected void onCreate(Bundle savedInstance) {
.......
if(savedInstance != null) {
myFillerData = (FillerData) savedInstance.getParcelable(FILLER_KEY);
} else {
myFillerData = new FillerData();
}
}
protected void onSaveInstanceState(Bundle savedInstance) {
super.onSaveInstanceState();
savedInstance.putExtra(FILLER_KEY, myFillerData);
}
public FillerData exposeFiller() {
return this.myFillerData;
}
}
现在,您的每个片段都可以通过父活动访问该集中式数据填充对象。为了减少代码的重量,您的所有片段都可以从提供对FillerDataExposer
实现(实际上是父活动)的访问的基本片段类扩展:
只应记录填充数据的片段可能如下所示:
public class Page1Fragment extends AbstractFillerFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = // inflate XML resource ...
yourEditText = (EditText) view.findViewById(...);
// other relevant code ....
}
public void onViewCreated(View view, Bundle savedInstanceState) {
yourEditText.setText(dataExposer.exposeFiller.setPageX$DataY());
// some code for EditText.addTextChangedListener(new TextWatcher() could look like:
yourEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
dataExposer.exposeFiller().setPage1$Data0(s.toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
}
public class FinalFragment extends AbstractFillerFragment {
public void collectAllData() {
DataFiller allDataCollectedObject = dataExposer.exposeFiller();
// by calling get...() you should have access to collected data.
}
}
而需要访问所有存储数据的片段可能如下所示:
public class Page1Fragment extends AbstractFillerFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = // inflate XML resource ...
yourEditText = (EditText) view.findViewById(...);
// other relevant code ....
}
public void onViewCreated(View view, Bundle savedInstanceState) {
yourEditText.setText(dataExposer.exposeFiller.setPageX$DataY());
// some code for EditText.addTextChangedListener(new TextWatcher() could look like:
yourEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
dataExposer.exposeFiller().setPage1$Data0(s.toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
}
public class FinalFragment extends AbstractFillerFragment {
public void collectAllData() {
DataFiller allDataCollectedObject = dataExposer.exposeFiller();
// by calling get...() you should have access to collected data.
}
}
这只是个草图,但你会明白的。这样做的目的是在活动重新启动时管理活动中的单个对象,并通过接口使其可访问,这样您就可以尊重活动模式的片段
<>希望有意义…我会考虑使用一个自定义对象来保持每个片段的数据填充。比如:
public class FillerData implements Parcelable {
private String page0$data0;
private String page0$data1;
private String page0$data2;
// getters and setters if you wish
// implement Parcelable interface as this object will be managed by host activity
}
您只有一个这样的对象由父活动管理,父活动将实现一个用于公开此对象的接口:
public static interface FillerDataExposer {
public FillerData exposeFiller();
}
public class MyFragmentHostActivity extends FragmentActivity implements FillerDataExposer {
private static final String FILLER_KEY = "FILLER_KEY";
private FillerData myFillerData;
protected void onCreate(Bundle savedInstance) {
.......
if(savedInstance != null) {
myFillerData = (FillerData) savedInstance.getParcelable(FILLER_KEY);
} else {
myFillerData = new FillerData();
}
}
protected void onSaveInstanceState(Bundle savedInstance) {
super.onSaveInstanceState();
savedInstance.putExtra(FILLER_KEY, myFillerData);
}
public FillerData exposeFiller() {
return this.myFillerData;
}
}
现在,您的每个片段都可以通过父活动访问该集中式数据填充对象。为了减少代码的重量,您的所有片段都可以从提供对FillerDataExposer
实现(实际上是父活动)的访问的基本片段类扩展:
只应记录填充数据的片段可能如下所示:
public class Page1Fragment extends AbstractFillerFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = // inflate XML resource ...
yourEditText = (EditText) view.findViewById(...);
// other relevant code ....
}
public void onViewCreated(View view, Bundle savedInstanceState) {
yourEditText.setText(dataExposer.exposeFiller.setPageX$DataY());
// some code for EditText.addTextChangedListener(new TextWatcher() could look like:
yourEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
dataExposer.exposeFiller().setPage1$Data0(s.toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
}
public class FinalFragment extends AbstractFillerFragment {
public void collectAllData() {
DataFiller allDataCollectedObject = dataExposer.exposeFiller();
// by calling get...() you should have access to collected data.
}
}
而需要访问所有存储数据的片段可能如下所示:
public class Page1Fragment extends AbstractFillerFragment {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = // inflate XML resource ...
yourEditText = (EditText) view.findViewById(...);
// other relevant code ....
}
public void onViewCreated(View view, Bundle savedInstanceState) {
yourEditText.setText(dataExposer.exposeFiller.setPageX$DataY());
// some code for EditText.addTextChangedListener(new TextWatcher() could look like:
yourEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
dataExposer.exposeFiller().setPage1$Data0(s.toString());
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
}
public class FinalFragment extends AbstractFillerFragment {
public void collectAllData() {
DataFiller allDataCollectedObject = dataExposer.exposeFiller();
// by calling get...() you should have access to collected data.
}
}
这只是个草图,但你会明白的。这样做的目的是在活动重新启动时管理活动中的单个对象,并通过接口使其可访问,这样您就可以尊重活动模式的片段
希望它有意义……onpause技巧不起作用,因为在查看第4页(最后一页)时,第3页没有调用onpause。你说得对。因此,您可以在每次更改输入时保存输入(您应该为您的文本视图设置侦听器)。我真正需要的是一个fragmentNotVisibleAnymore()方法。我想我会尝试使用setOnPageChangeListener,它可以在每个片段中调用一个方法来收集所有数据。第二个方法只需一行代码,不需要将数据保存到首选项,也可以使滑动更加平滑。不管怎样,这是你的决定。按您认为最好的方式执行:)几乎正确,但第二种方法需要多4行代码,因为它还需要我缓存在m中创建的对象