2013-07-30 35 views
1

我有一个ViewPager允许用户在5个不同视图之间滑动,其中每个“视图”都会扩展片段。Android中的片段和ViewPager

我有我自己的)适配器延伸FragmentPagerAdapter和实施的getItem(如

@Override public Fragment getItem(int position) { 
    switch(position) { 
     case 0: 
      return new TextDescriptionFragment(); 
     // Handle the 4 other cases the same way 
    } 
} 

这工作正常,用户可以在5个不同的视图之间滑动。但是问题在于:前4个视图中的每一个都包含用户可以与之交互的诸如Button和EditText之类的视图。

然后我希望最后一页(页码5)显示来自前4页(片段)的所有视图的所有用户输入值。我怎么做?

我找不到任何方法从前面的片段读取用户输入值。视图可能不再存在(但如果用户返回,则会被重新创建)。

而我似乎无法得到现有的片段。

+0

但我无法得到4个第一页的片段。他们甚至可能不存在。 – MTilsted

回答

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; 
    } 
} 

现在,您的每一个片段都将有通过父级活动访问该集中式数据填充对象。

public abstract class AbstractFillerFragment extends Fragment { 
    protected FillerDataExposer dataExposer; 

    public void onAttach(Activity act) { 
     super.onAttach(act); 
     // make sure no ClassCastExceptions 
     this.dataExposer = (FillerDataExposer) act; 
    } 
} 

片段应该只记录填充可能看起来像数据:为了减少代码的重量,所有的碎片可能会从基片段类,它提供给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. 
    } 
} 

这只是一个草图,但你会得到的图片。这个想法是让活动中的单个对象在整个活动重新启动时进行管理,并使其可以通过接口进行访问,因此您可以将片段视为活动模式。

希望它是有道理的......

+0

问题是,像onpause一样,onSaveInstanceState(Bundle savedInstance)不会被所有片段调用,当我查看最后一个片段时。 – MTilsted

+0

你不需要关心暂停。无论您做什么,数据都可随时随地使用。 – gunar

+0

要添加的一件事:对于每个片段,您需要为DataFiller中已有的数据设置edittext或其他视图。这可以在onViewCreated中完成。 – gunar

0

2种解决方案出现在我的脑海。

第一个是当您的第一个4片段的onpause()方法被调用时保存用户输入数据。您可以将数据保存到首选项,然后从第5个片段中检索它。

第二种方法是坚持你的片段,而swiping.This方式刷卡会更快,更清洁,他们希望重新创建每次刷卡情况:

yourcustomviewpager.setOffscreenPageLimit(5); 

关于setOffscreenPageLimit从the android doc

设置应保留在处于空闲状态的视图层次结构中当前页面任一侧的页数。超出此限制的页面将在需要时从适配器重新创建。 这是作为优化提供的。如果您事先知道您需要支持的页面数量或者在您的页面上放置了延迟加载机制,那么调整此设置可以在分页动画和交互的感知平滑度方面带来好处。如果您有一小部分页面(3-4)可以一次保持活动状态,那么随着用户来回翻页,新创建的视图子树的布局花费的时间会更少。 您应该保持低限,特别是如果您的页面布局复杂。此设置默认为1.

+0

由于在查看第4页(最后一页)时没有为第3页调用onpause,所以不能使用这个技巧。 – MTilsted

+0

你说得对。所以你可以在每次输入改变时保存输入(你应该为你的文字视图设置监听器)。 –

+0

Dam,这是很多代码。而我真正需要的是一个fragmentNotVisibleAnymore()方法。我想我会尝试使用setOnPageChangeListener,然后可以调用每个片段中的方法来收集所有数据。 – MTilsted