在 viewpager 上滑动时,选项卡选择器无法在上一个选项卡上单击
Tab selector not working on previous tab click when swipe on viewpager
我遵循 this 示例..
我遇到一个问题,当我在 ViewPager
上滑动时会出现相应的 fragment
,但是当我从左向右或从右向左滑动时 和 select 上一个选项卡 选项卡指示器出现在新的 select 选项卡上,但相应的 fragment
未出现在 ViewPager
上。
请帮助我,我哪里错了?
这是我使用的并且工作正常。
适配器:
public class SCFragmentPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
private Context mContext;
private FragmentManager mFragmentManager;
public SCFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.mFragmentManager = fm;
this.mContext = context;
}
@Override
public int getCount() {
return mFragments.size();
}
// Return the correct Fragment based on index
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
// Return the tab title to SlidingTabLayout
return mFragmentTitles.get(position);
}
public Fragment getActiveFragment(ViewPager container, int position) {
String name = makeFragmentName(container.getId(), position);
return mFragmentManager.findFragmentByTag(name);
}
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
}
Activity:
public class SCWelcomeActivity extends AppCompatActivity implements
SCWelcomeFragment.OnFragmentInteractionListener,
SCSyncFragment.OnFragmentInteractionListener,
SCRegisterFragment.OnFragmentInteractionListener,
SCConfirmationFragment.OnFragmentInteractionListener {
private static final String TAG = SCWelcomeActivity.class.getSimpleName();
private ViewPager viewPager = null;
private TabLayout tabLayout = null;
private Toolbar toolbar = null;
private SCFragmentPagerAdapter adapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scwelcome);
// Layout manager that allows the user to flip through the pages
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Initialize the Sliding Tab Layout
tabLayout = (TabLayout) findViewById(R.id.tablayout);
// Connect the viewPager with the sliding tab layout
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public void onFragmentInteraction(Uri uri) {
}
private void setupViewPager(ViewPager viewPager) {
adapter = new SCFragmentPagerAdapter(getSupportFragmentManager(), SCWelcomeActivity.this);
adapter.addFragment(SCWelcomeFragment.newInstance(), getString(R.string.title_tab1));
adapter.addFragment(SCSyncFragment.newInstance(), getString(R.string.title_tab2));
adapter.addFragment(SCRegisterFragment.newInstance(), getString(R.string.title_tab3));
adapter.addFragment(SCConfirmationFragment.newInstance(), getString(R.string.title_tab4));
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(4);
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
片段示例:
public class SCWelcomeFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public static SCWelcomeFragment newInstance() {
SCWelcomeFragment fragment = new SCWelcomeFragment();
return fragment;
}
public SCWelcomeFragment() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_scwelcome, container, false);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
布局:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="130dp"
android:fitsSystemWindows="true"
android:gravity="bottom"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:layout_gravity="center"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
请像我一样尝试实现适配器。请密切注意,在我的 Adapter 中,所有实例都保存在
private final List<Fragment> mFragments = new ArrayList<>();
在你的情况下,你总是返回一个新实例。这就是设置 setOffscreenPageLimit(4) 的原因。到 4 所以它们也保存在内存中。
我有更短的变体来修复这个错误(android 支持设计库 v.23.0.0):
...
//initialize views
mViewPager.setAdapter(pagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.clearOnPageChangeListeners();
mViewPager.addOnPageChangeListener(new WorkaroundTabLayoutOnPageChangeListener(mTabLayout));
...
和class解决方法TabLayoutOnPageChangeListener:
public class WorkaroundTabLayoutOnPageChangeListener extends TabLayout.TabLayoutOnPageChangeListener {
private final WeakReference<TabLayout> mTabLayoutRef;
public WorkaroundTabLayoutOnPageChangeListener(TabLayout tabLayout) {
super(tabLayout);
this.mTabLayoutRef = new WeakReference<>(tabLayout);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null) {
final TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
}
}
}
}
这是支持库 23.0.0 中的错误,但已在 23.0.1 中解决。首先更新您的 支持库使用额外部分的 SDK 管理器。
并在应用 gradle 文件中写入以下行。
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
供大家参考
https://developer.android.com/topic/libraries/support-library/revisions.html
并阅读 Android 支持库修订版 23.0.1 部分 设计支持库的更改
在您的 activity 中,按 ID 找到视图后,您应该 "config" 您的 ViewPager 和 TabLayout。一些必要的功能可能是:ViewPager 的“addOnPageChangeListener”和 TabLayout 的“setOnTabSelectedListener”,如下所示:
public class MainActivity extends AppCompatActivity {
private final int numOfPages = 4; //viewpager has 4 pages
private final String[] pageTitle = {"Food", "Movie", "Shopping", "Travel"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
for (int i = 0; i < numOfPages; i++) {
tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i]));
}
//set gravity for tab bar
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), numOfPages);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
}
private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
return new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
}
我有一个关于此的教程 post,而且效果很好!没有像你这样的错误。
希望它有所帮助:
http://www.devexchanges.info/2015/08/android-material-design-viewpager-with.html
您使用的支持库版本是 23.0.0 吗?有一个问题 https://code.google.com/p/android/issues/detail?id=183123 看起来与您的相似。如果确实如此,请将您的支持库版本更新为 23.0.1。此问题已修复。
None 以上答案对我有用截至 2016 结束 bug 仍然存在于设计支持库 24+.
我可以通过将选项卡布局包装在
中来解决这个问题
协调器布局
我遵循 this 示例..
我遇到一个问题,当我在 ViewPager
上滑动时会出现相应的 fragment
,但是当我从左向右或从右向左滑动时 和 select 上一个选项卡 选项卡指示器出现在新的 select 选项卡上,但相应的 fragment
未出现在 ViewPager
上。
请帮助我,我哪里错了?
这是我使用的并且工作正常。
适配器:
public class SCFragmentPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragments = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
private Context mContext;
private FragmentManager mFragmentManager;
public SCFragmentPagerAdapter(FragmentManager fm, Context context) {
super(fm);
this.mFragmentManager = fm;
this.mContext = context;
}
@Override
public int getCount() {
return mFragments.size();
}
// Return the correct Fragment based on index
@Override
public Fragment getItem(int position) {
return mFragments.get(position);
}
public void addFragment(Fragment fragment, String title) {
mFragments.add(fragment);
mFragmentTitles.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
// Return the tab title to SlidingTabLayout
return mFragmentTitles.get(position);
}
public Fragment getActiveFragment(ViewPager container, int position) {
String name = makeFragmentName(container.getId(), position);
return mFragmentManager.findFragmentByTag(name);
}
private static String makeFragmentName(int viewId, int index) {
return "android:switcher:" + viewId + ":" + index;
}
}
Activity:
public class SCWelcomeActivity extends AppCompatActivity implements
SCWelcomeFragment.OnFragmentInteractionListener,
SCSyncFragment.OnFragmentInteractionListener,
SCRegisterFragment.OnFragmentInteractionListener,
SCConfirmationFragment.OnFragmentInteractionListener {
private static final String TAG = SCWelcomeActivity.class.getSimpleName();
private ViewPager viewPager = null;
private TabLayout tabLayout = null;
private Toolbar toolbar = null;
private SCFragmentPagerAdapter adapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_scwelcome);
// Layout manager that allows the user to flip through the pages
viewPager = (ViewPager) findViewById(R.id.viewpager);
setupViewPager(viewPager);
// Initialize the Sliding Tab Layout
tabLayout = (TabLayout) findViewById(R.id.tablayout);
// Connect the viewPager with the sliding tab layout
tabLayout.setupWithViewPager(viewPager);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public void onFragmentInteraction(Uri uri) {
}
private void setupViewPager(ViewPager viewPager) {
adapter = new SCFragmentPagerAdapter(getSupportFragmentManager(), SCWelcomeActivity.this);
adapter.addFragment(SCWelcomeFragment.newInstance(), getString(R.string.title_tab1));
adapter.addFragment(SCSyncFragment.newInstance(), getString(R.string.title_tab2));
adapter.addFragment(SCRegisterFragment.newInstance(), getString(R.string.title_tab3));
adapter.addFragment(SCConfirmationFragment.newInstance(), getString(R.string.title_tab4));
viewPager.setAdapter(adapter);
viewPager.setOffscreenPageLimit(4);
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
片段示例:
public class SCWelcomeFragment extends Fragment {
private OnFragmentInteractionListener mListener;
public static SCWelcomeFragment newInstance() {
SCWelcomeFragment fragment = new SCWelcomeFragment();
return fragment;
}
public SCWelcomeFragment() {
super();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_scwelcome, container, false);
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
try {
mListener = (OnFragmentInteractionListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnFragmentInteractionListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
}
布局:
<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/coordinator"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v4.view.ViewPager
android:id="@+id/viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<android.support.design.widget.AppBarLayout
android:id="@+id/appbar"
android:layout_width="match_parent"
android:layout_height="130dp"
android:fitsSystemWindows="true"
android:gravity="bottom"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
app:layout_collapseMode="pin"
android:layout_gravity="center"
android:theme="@style/ThemeOverlay.AppCompat.Dark"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="@+id/tablayout"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</android.support.design.widget.AppBarLayout>
</android.support.design.widget.CoordinatorLayout>
请像我一样尝试实现适配器。请密切注意,在我的 Adapter 中,所有实例都保存在
private final List<Fragment> mFragments = new ArrayList<>();
在你的情况下,你总是返回一个新实例。这就是设置 setOffscreenPageLimit(4) 的原因。到 4 所以它们也保存在内存中。
我有更短的变体来修复这个错误(android 支持设计库 v.23.0.0):
...
//initialize views
mViewPager.setAdapter(pagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
mViewPager.clearOnPageChangeListeners();
mViewPager.addOnPageChangeListener(new WorkaroundTabLayoutOnPageChangeListener(mTabLayout));
...
和class解决方法TabLayoutOnPageChangeListener:
public class WorkaroundTabLayoutOnPageChangeListener extends TabLayout.TabLayoutOnPageChangeListener {
private final WeakReference<TabLayout> mTabLayoutRef;
public WorkaroundTabLayoutOnPageChangeListener(TabLayout tabLayout) {
super(tabLayout);
this.mTabLayoutRef = new WeakReference<>(tabLayout);
}
@Override
public void onPageSelected(int position) {
super.onPageSelected(position);
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null) {
final TabLayout.Tab tab = tabLayout.getTabAt(position);
if (tab != null) {
tab.select();
}
}
}
}
这是支持库 23.0.0 中的错误,但已在 23.0.1 中解决。首先更新您的 支持库使用额外部分的 SDK 管理器。 并在应用 gradle 文件中写入以下行。
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:design:23.0.1'
供大家参考
https://developer.android.com/topic/libraries/support-library/revisions.html 并阅读 Android 支持库修订版 23.0.1 部分 设计支持库的更改
在您的 activity 中,按 ID 找到视图后,您应该 "config" 您的 ViewPager 和 TabLayout。一些必要的功能可能是:ViewPager 的“addOnPageChangeListener”和 TabLayout 的“setOnTabSelectedListener”,如下所示:
public class MainActivity extends AppCompatActivity {
private final int numOfPages = 4; //viewpager has 4 pages
private final String[] pageTitle = {"Food", "Movie", "Shopping", "Travel"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
for (int i = 0; i < numOfPages; i++) {
tabLayout.addTab(tabLayout.newTab().setText(pageTitle[i]));
}
//set gravity for tab bar
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
final PagerAdapter adapter = new PagerAdapter
(getSupportFragmentManager(), numOfPages);
viewPager.setAdapter(adapter);
viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
tabLayout.setOnTabSelectedListener(onTabSelectedListener(viewPager));
}
private TabLayout.OnTabSelectedListener onTabSelectedListener(final ViewPager pager) {
return new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
pager.setCurrentItem(tab.getPosition());
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
}
};
}
我有一个关于此的教程 post,而且效果很好!没有像你这样的错误。 希望它有所帮助: http://www.devexchanges.info/2015/08/android-material-design-viewpager-with.html
您使用的支持库版本是 23.0.0 吗?有一个问题 https://code.google.com/p/android/issues/detail?id=183123 看起来与您的相似。如果确实如此,请将您的支持库版本更新为 23.0.1。此问题已修复。
None 以上答案对我有用截至 2016 结束 bug 仍然存在于设计支持库 24+.
我可以通过将选项卡布局包装在
中来解决这个问题
协调器布局