在 ViewPager 内设计一个 HorizontalScrollView 或使用片段:
Posted
技术标签:
【中文标题】在 ViewPager 内设计一个 HorizontalScrollView 或使用片段:【英文标题】:Design a HorizontalScrollView inside of ViewPager or use fragments: 【发布时间】:2013-03-13 10:30:38 【问题描述】:我需要设计以下屏幕,我需要你的建议:
说明:
标题是静态的/固定的,我不需要对它做任何事情。
黄色:这是有趣的部分,我需要设计一个类似ViewPager
的屏幕,它能够左右滚动最多 4 个屏幕。
红色:我需要在每个屏幕中添加一个表格/网格,如果它不适合屏幕大小,它也可以滚动。
绿色:可以使用屏幕底部的绿色按钮或滚动ViewPager
来完成页面切换。
问题是:这种行为可以使用ViewPager
实现还是我应该使用Fragments
?如果 Fragment 是要走的路,那么我将如何使用滑动手势实现页面切换?如果是ViewPager
,那么如何添加内部滚动以及如何使用底部的按钮进行控制?
任何帮助将不胜感激,谢谢。
【问题讨论】:
如果这些表格/网格需要在 X 轴上滚动(填充整个宽度),那么我不知道您如何实现这一点,因为您将无法决定应该使用哪个小部件允许滚动。如果表格/网格只能垂直滚动而不是使用ViewPager
。
实际上我偶然发现了以下链接:***.com/questions/6920137/… 并且人们在那里说有可能,我从未尝试过,所以我打开了这个问题来看看人们的意见,也许知道什么方法会更好。
【参考方案1】:
我认为这应该通过 不可滑动 ViewPager
来解决。视图寻呼机和底层Fragment
s 不可能响应滑动手势。在ViewPager
中覆盖以禁用滑动的方法是:
onTouchEvent()
- 返回false
。
onInterceptTouchEvent()
- 返回false
。
请参阅this SO question 了解有关如何实现此目的的更多信息。
接下来,您希望在每个寻呼机持有人中使用Fragment
s。所以我们正在构建以下布局:
在父活动中,FragmentPagerAdapter
被实例化,并且您的标签添加了标签:
活动变化
@Override
protected void onCreate(final Bundle saveInstanceState)
final FragmentPagerAdapter myTabAdapter = new MyFragmentPagerAdapter(
<Your ViewPager View>, <Your activity context, this>);
myTabAdapter.addTab(getActionBar().newTab(), "YOUR TAG", "Your Title");
// etc...
所以这给了我们上图的框架。一个托管活动,包含 ViewPager
和基础选项卡。接下来是将Fragment
s(包含您的表格)放入每个相应的选项卡中。这是由FragmentPagerAdapter
实现处理的:
片段适配器(活动的内部类):
private class MyFragmentPagerAdapter extends FragmentPagerAdapter implements
ActionBar.TabListener, ViewPager.OnPageChangeListener
/**
* Constructs a pager adapter to back a @link ViewPager.
*
* @param pager
* The @link ViewPager widget.
* @param activityContext
* The context the widget is being added under.
*/
public SpotMenuFragmentPagerAdapter(final ViewPager pager,
final Context activityContext)
super(getFragmentManager());
pager.setAdapter(this);
this.context = activityContext;
/**
* Adds a tab to the hosting activity action bar.
*
* @param newTab
* The tab to add.
* @param tag
* The tab tag for id purposes.
* @param label
* The label of the tab displayed to the user.
*/
public void addTab(final ActionBar.Tab newTab, final String tag,
final String label)
newTab.setTag(tag);
newTab.setText(label);
newTab.setTabListener(this);
getSupportActionBar().addTab(newTab);
/**
* This is where you do the work of building the correct fragment based
* on the tab currently selected.
*
* @see FragmentPagerAdapter#getItem(int)
*/
@Override
public Fragment getItem(final int position)
final Tab tab = getActionBar().getTabAt(position);
if ("MY TAG".equals(tab.getTag().toString())
// instantiate the fragment (table) for "MY TAG"
else
// instantiate something else...
/**
* One fragment per tab.
*
* @see android.support.v4.view.PagerAdapter#getCount()
*/
@Override
public int getCount()
return getSupportActionBar().getTabCount();
/**
* @see ViewPager.OnPageChangeListener#onPageScrollStateChanged(int)
*/
@Override
public void onPageScrollStateChanged(final int arg0)
// No-op.
/**
* @see ViewPager.OnPageChangeListener#onPageScrolled(int, float, int)
*/
@Override
public void onPageScrolled(final int arg0, final float arg1,
final int arg2)
// No-op.
/**
* @see ViewPager.OnPageChangeListener#onPageSelected(int)
*/
@Override
public void onPageSelected(final int position)
getSupportActionBar().setSelectedNavigationItem(position);
/**
* @see TabListener#onTabSelected(app.ActionBar.Tab,
* app.FragmentTransaction)
*/
@Override
public void onTabSelected(final Tab tab, final FragmentTransaction ft)
viewPager.setCurrentItem(tab.getPosition());
/**
* @see TabListener#onTabUnselected(ActionBar.Tab,
* app.FragmentTransaction)
*/
@Override
public void onTabUnselected(final Tab tab, final FragmentTransaction ft)
// No-op.
/**
* @see TabListener#onTabReselected(ActionBar.Tab,app.FragmentTransaction)
*/
@Override
public void onTabReselected(final Tab tab, final FragmentTransaction ft)
// No-op.
因此,希望到此为止,我们有一个托管“不可滑动”视图寻呼机的活动,以及一个以标题下方的标签栏形式(或取决于屏幕大小)切换标签的机制。从这一点来看,我相信您可以自定义以用一些导航箭头替换标签栏。
注意:其中很多内容都是凭记忆写的,但希望我已经传达了我将如何处理的要点。
更新
针对更新后的问题:您可以将选项卡设置为任何旧视图。相应地设置TabSpec。抱歉,我自己没有使用过。
【讨论】:
其实你说的刷卡问题有解决办法,看这个帖子:***.com/questions/6920137/…,我还没查。但是如果我使用 ViewPager,并且我没有操作栏,如何将我的页面切换按钮放置在屏幕底部并自定义它们? @EmilAdz - 这是non-action bar example “FragmentStatePagerAdapter”和“FragmentPagerAdapter”有什么区别? 嘿 Emil- 我可以在这里重复文档,但解释很容易理解。FragmentStatePagerAdapter
在考虑许多页面时对内存更友好,但代价是片段初始化速度较慢(因为只有状态 - 而不是整个组件 - 保存在内存中)
所以对于我的情况(最多 4 个片段)使用 FragmentPagerAdapter 会更好(从性能角度)?【参考方案2】:
您必须使用 HorizontalScrollView ,它将包含一个 LinearLayout 并且 Linear 将包含您的各个元素
XML 会看到类似这样的内容
<HorizontalScrollView
android:id="@+id/horizontal_scroll_parent"
android:layout_
android:layout_
android:scrollbars="horizontal"
android:scrollbarStyle="outsideInset">
<LinearLayout android:id="@+id/content_scroll"
android:layout_
android:layout_
android:orientation="horizontal"
android:gravity="center_vertical" />
</HorizontalScrollView>
【讨论】:
那是错误的方式。使用 Fragments 而不是需要 1 秒加载的重载布局。以上是关于在 ViewPager 内设计一个 HorizontalScrollView 或使用片段:的主要内容,如果未能解决你的问题,请参考以下文章