在两个选项卡之间共享ViewPager

8

Tab View Pager

我已经尝试了许多不同的方法来共享ViewPager,但都失败了。请问有什么建议吗?

TabLayout topTabLayout = (TabLayout) findViewById(R.id.topTabLayout);
topTabLayout.addTab(topTabLayout.newTab().setText("Tab 1"));
topTabLayout.addTab(topTabLayout.newTab().setText("Tab 2"));
topTabLayout.addTab(topTabLayout.newTab().setText("Tab 3"));

TabLayout bottomTabLayout =(TabLayout)findViewById(R.id.bottomTabLayout);
bottomTabLayout.addTab(bottomTabLayout.newTab().setText("Tab 4"));
bottomTabLayout.addTab(bottomTabLayout.newTab().setText("Tab 5"));
bottomTabLayout.addTab(bottomTabLayout.newTab().setText("Tab 6"));

1
请问您能否展示一下您 onPageChangeListener() 的代码片段? - Collins Abitekaniza
2
我不理解你问题中“share”这个词的含义,你想要实现什么?你的ViewPager中是否有6个选项卡,其中选项卡1、2、3在顶部,其余在底部或者其他布局方式?如果你能详细说明,我或许可以提供帮助。 - PirateApp
我有两个选项卡,一个在上面,一个在下面。ViewPager 应该包含所有页面链接。由于对我来说很奇怪,所以不能调用两次 setupWithViewPager(viewPager); 我尝试了其他方法,如触摸监听器或选择,但都不起作用。 - Hafizan Aziz
1
我还在尝试弄清楚的最后一段代码是在http://pastebin.com/UmEn2sxN。 - Hafizan Aziz
ViewPager是采用MVC设计模式的(V)iew部分。(C)ontroller和(M)odel是适配器,例如FragmentPagerAdapter。我认为思考过程是共享适配器和数据,而不是ViewPager。如果您想在不同的选项卡之间共享数据,可以通过将相同的适配器(setAdapter()方法)设置为不同的ViewPager来实现。在这种情况下,您需要设计一个“线程安全”的适配器。由于您已经准备好应对这样的挑战,因此我相信您会处理好这些问题。祝编码愉快! - Devendra Vaja
显示剩余4条评论
2个回答

0

以下是代码,按照以下步骤执行:

1)为活动创建布局:

    <RelativeLayout android:id="@+id/job_layout"
                    xmlns:android="http://schemas.android.com/apk/res/android"
                    xmlns:materialdesign="http://schemas.android.com/apk/res-auto"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    >

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="56dp"/>



            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@id/toolbar">


            <com.xlsys.generic.view.SlidingTabLayout
                android:id="@+id/sliding_tabs1"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" />

            <android.support.v4.view.ViewPager
                android:id="@+id/pager1"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_below="@+id/sliding_tabs1"
                />

    </RelativeLayout>

    </RelativeLayout>







2) Create two fragment for two tab if three Tab then create three fragment:

Fragment 1) 



 import android.os.Bundle;
    import android.support.v4.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import com.xlsys.generic.activities.R;


    public class JobCalender extends Fragment {



        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {

            View mView = inflater.inflate(R.layout.inspection, container, false);
          return mView;
        }

    }





3) Create xml file for above fragment 

3) Same way create another fragment and xml file  for another tab.

4) Create Activity :




 import android.os.Bundle;
    import android.support.v4.app.FragmentStatePagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.support.v4.app.FragmentManager;
    import android.support.v4.app.Fragment;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.View;
    import com.xlsys.generic.fragments.Inspection_Fragment;
    import com.xlsys.generic.fragments.NC_Fragments;
    import com.xlsys.generic.view.SlidingTabLayout;
    import android.support.design.widget.TabLayout;
    import android.widget.LinearLayout;
    import android.widget.TextView;


    public class AddLocationActivity extends AppCompatActivity {


        private String mPagerItem[]={"Calender","Tab2"};

        private Toolbar toolbar;
        private SlidingTabLayout mSlidingTabLayout;
        ViewPager pager;

        public String jobId,mTaskType,taskCreatedDate;

        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.addlocation);


            getWidgets();
            setWidgets();
            setWidgetsListener();

        }



        private void getWidgets() 

            pager = (ViewPager) findViewById(R.id.pager1);
            mSlidingTabLayout = (SlidingTabLayout)findViewById(R.id.sliding_tabs1);
        }

        private void setWidgets()
        {

            pager.setAdapter(new MyPagerAdapter(getSupportFragmentManager()));
            mSlidingTabLayout.setViewPager(pager);


        }



        private class MyPagerAdapter extends FragmentStatePagerAdapter {

            int mNumOfTabs;
            public MyPagerAdapter(FragmentManager fm) {
                super(fm);
            }

            @Override
            public CharSequence getPageTitle(int position) {
                return mPagerItem[position];
            }

            public Fragment getItem(int pos) {
                switch(pos) {
                    case 0:
                        JobCalender JobCalender_fragment=new JobCalender();
                        return JobCalender_fragment;
                    case 1:
                        NC_Fragments mNC_Fragments=new NC_Fragments();
                        return mNC_Fragments;

                    default:
                       JobCalender JobCalender_fragment=new JobCalender();
                        return JobCalender_fragment;

                }
            }
            public int getCount() {
                return mPagerItem.length;
            }
        }



    }

5) 添加 SlidingTabLayout 类:

 your.package.name ;    
    import android.content.Context;
    import android.graphics.Point;
    import android.graphics.Typeface;
    import android.os.Build;
    import android.support.v4.view.PagerAdapter;
    import android.support.v4.view.ViewPager;
    import android.util.AttributeSet;
    import android.util.TypedValue;
    import android.view.Display;
    import android.view.Gravity;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.WindowManager;
    import android.widget.HorizontalScrollView;
    import android.widget.TextView;

    /**
     * To be used with ViewPager to provide a tab indicator component which give constant feedback as to
     * the user's scroll progress.
     * <p>
     * To use the component, simply add it to your view hierarchy. Then in your
     * {@link android.app.Activity} or {@link android.support.v4.app.Fragment} call
     * {@link #setViewPager(ViewPager)} providing it the ViewPager this layout is being used for.
     * <p>
     * The colors can be customized in two ways. The first and simplest is to provide an array of colors
     * via {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)}. The
     * alternative is via the {@link TabColorizer} interface which provides you complete control over
     * which color is used for any individual position.
     * <p>
     * The views used as tabs can be customized by calling {@link #setCustomTabView(int, int)},
     * providing the layout ID of your custom layout.
     */
    public class SlidingTabLayout extends HorizontalScrollView {

        /**
         * Allows complete control over the colors drawn in the tab layout. Set with
         * {@link #setCustomTabColorizer(TabColorizer)}.
         */
        public interface TabColorizer {

            /**
             * @return return the color of the indicator used when {@code position} is selected.
             */
            int getIndicatorColor(int position);

            /**
             * @return return the color of the divider drawn to the right of {@code position}.
             */
            int getDividerColor(int position);

        }

        private static final int TITLE_OFFSET_DIPS = 24;
        private static final int TAB_VIEW_PADDING_DIPS = 16;
        private static final int TAB_VIEW_TEXT_SIZE_SP = 12;

        private int mTitleOffset;

        private int mTabViewLayoutId;
        private int mTabViewTextViewId;

        private ViewPager mViewPager;
        private ViewPager.OnPageChangeListener mViewPagerPageChangeListener;

        private final SlidingTabStrip mTabStrip;

        public SlidingTabLayout(Context context) {
            this(context, null);
        }

        public SlidingTabLayout(Context context, AttributeSet attrs) {
            this(context, attrs, 0);
        }

        public SlidingTabLayout(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);

            // Disable the Scroll Bar
            setHorizontalScrollBarEnabled(false);
            // Make sure that the Tab Strips fills this View
            setFillViewport(true);

            mTitleOffset = (int) (TITLE_OFFSET_DIPS * getResources().getDisplayMetrics().density);

            mTabStrip = new SlidingTabStrip(context);
            addView(mTabStrip, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
        }

        /**
         * Set the custom {@link TabColorizer} to be used.
         *
         * If you only require simple custmisation then you can use
         * {@link #setSelectedIndicatorColors(int...)} and {@link #setDividerColors(int...)} to achieve
         * similar effects.
         */
        public void setCustomTabColorizer(TabColorizer tabColorizer) {
            mTabStrip.setCustomTabColorizer(tabColorizer);
        }

        /**
         * Sets the colors to be used for indicating the selected tab. These colors are treated as a
         * circular array. Providing one color will mean that all tabs are indicated with the same color.
         */
        public void setSelectedIndicatorColors(int... colors) {
            mTabStrip.setSelectedIndicatorColors(colors);
        }

        /**
         * Sets the colors to be used for tab dividers. These colors are treated as a circular array.
         * Providing one color will mean that all tabs are indicated with the same color.
         */
        public void setDividerColors(int... colors) {
            mTabStrip.setDividerColors(colors);
        }

        /**
         * Set the {@link ViewPager.OnPageChangeListener}. When using {@link SlidingTabLayout} you are
         * required to set any {@link ViewPager.OnPageChangeListener} through this method. This is so
         * that the layout can update it's scroll position correctly.
         *
         * @see ViewPager#setOnPageChangeListener(ViewPager.OnPageChangeListener)
         */
        public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
            mViewPagerPageChangeListener = listener;
        }

        /**
         * Set the custom layout to be inflated for the tab views.
         *
         * @param layoutResId Layout id to be inflated
         * @param textViewId id of the {@link TextView} in the inflated view
         */
        public void setCustomTabView(int layoutResId, int textViewId) {
            mTabViewLayoutId = layoutResId;
            mTabViewTextViewId = textViewId;
        }

        /**
         * Sets the associated view pager. Note that the assumption here is that the pager content
         * (number of tabs and tab titles) does not change after this call has been made.
         */
        public void setViewPager(ViewPager viewPager) {
            mTabStrip.removeAllViews();

            mViewPager = viewPager;
            if (viewPager != null) {
                viewPager.setOnPageChangeListener(new InternalViewPagerListener());
                populateTabStrip();
            }
        }

        /**
         * Create a default view to be used for tabs. This is called if a custom tab view is not set via
         * {@link #setCustomTabView(int, int)}.
         */
        protected TextView createDefaultTabView(Context context) {
            TextView textView = new TextView(context);
            textView.setGravity(Gravity.CENTER);
            textView.setGravity(Gravity.CENTER);
            WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
            Display display = wm.getDefaultDisplay();
            Point size = new Point();
            display.getSize(size);
            textView.setWidth(size.x /2);

            textView.setTextSize(TypedValue.COMPLEX_UNIT_SP, TAB_VIEW_TEXT_SIZE_SP);
            textView.setTypeface(Typeface.DEFAULT_BOLD);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
                // If we're running on Honeycomb or newer, then we can use the Theme's
                // selectableItemBackground to ensure that the View has a pressed state
                TypedValue outValue = new TypedValue();
                getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground,
                        outValue, true);
                textView.setBackgroundResource(outValue.resourceId);
            }

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                // If we're running on ICS or newer, enable all-caps to match the Action Bar tab style
                textView.setAllCaps(true);
            }

            int padding = (int) (TAB_VIEW_PADDING_DIPS * getResources().getDisplayMetrics().density);
            textView.setPadding(padding, padding, padding, padding);

            return textView;
        }

        private void populateTabStrip() {
            final PagerAdapter adapter = mViewPager.getAdapter();
            final OnClickListener tabClickListener = new TabClickListener();

            for (int i = 0; i < adapter.getCount(); i++) {
                View tabView = null;
                TextView tabTitleView = null;

                if (mTabViewLayoutId != 0) {
                    // If there is a custom tab view layout id set, try and inflate it
                    tabView = LayoutInflater.from(getContext()).inflate(mTabViewLayoutId, mTabStrip,
                            false);
                    tabTitleView = (TextView) tabView.findViewById(mTabViewTextViewId);
                }

                if (tabView == null) {
                    tabView = createDefaultTabView(getContext());
                }

                if (tabTitleView == null && TextView.class.isInstance(tabView)) {
                    tabTitleView = (TextView) tabView;
                }

                tabTitleView.setText(adapter.getPageTitle(i));
                tabView.setOnClickListener(tabClickListener);

                mTabStrip.addView(tabView);
            }
        }

        @Override
        protected void onAttachedToWindow() {
            super.onAttachedToWindow();

            if (mViewPager != null) {
                scrollToTab(mViewPager.getCurrentItem(), 0);
            }
        }

        private void scrollToTab(int tabIndex, int positionOffset) {
            final int tabStripChildCount = mTabStrip.getChildCount();
            if (tabStripChildCount == 0 || tabIndex < 0 || tabIndex >= tabStripChildCount) {
                return;
            }

            View selectedChild = mTabStrip.getChildAt(tabIndex);
            if (selectedChild != null) {
                int targetScrollX = selectedChild.getLeft() + positionOffset;

                if (tabIndex > 0 || positionOffset > 0) {
                    // If we're not at the first child and are mid-scroll, make sure we obey the offset
                    targetScrollX -= mTitleOffset;
                }

                scrollTo(targetScrollX, 0);
            }
        }

        private class InternalViewPagerListener implements ViewPager.OnPageChangeListener {
            private int mScrollState;

            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
                int tabStripChildCount = mTabStrip.getChildCount();
                if ((tabStripChildCount == 0) || (position < 0) || (position >= tabStripChildCount)) {
                    return;
                }

                mTabStrip.onViewPagerPageChanged(position, positionOffset);

                View selectedTitle = mTabStrip.getChildAt(position);
                int extraOffset = (selectedTitle != null)
                        ? (int) (positionOffset * selectedTitle.getWidth())
                        : 0;
                scrollToTab(position, extraOffset);

                if (mViewPagerPageChangeListener != null) {
                    mViewPagerPageChangeListener.onPageScrolled(position, positionOffset,
                            positionOffsetPixels);
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {
                mScrollState = state;

                if (mViewPagerPageChangeListener != null) {
                    mViewPagerPageChangeListener.onPageScrollStateChanged(state);
                }
            }

            @Override
            public void onPageSelected(int position) {
                if (mScrollState == ViewPager.SCROLL_STATE_IDLE) {
                    mTabStrip.onViewPagerPageChanged(position, 0f);
                    scrollToTab(position, 0);
                }

                if (mViewPagerPageChangeListener != null) {
                    mViewPagerPageChangeListener.onPageSelected(position);
                }
            }

        }

        private class TabClickListener implements OnClickListener {
            @Override
            public void onClick(View v) {
                for (int i = 0; i < mTabStrip.getChildCount(); i++) {
                    if (v == mTabStrip.getChildAt(i)) {
                        mViewPager.setCurrentItem(i);
                        return;
                    }
                }
            }
        }

    }

0

首先,这违反了Google材料指南。您可以在这里阅读相关内容。

最近我有一个自定义TabLayout设计工作,我已经阅读了所有的TabLayout代码。 这是使用Design Support库不可能实现的。

反射是一种选择,但会让你做很多工作,并且最终并不能完全满足您的需求,因为它并没有专门为此设计Design Support库。

如果您仍想要这样做,应考虑创建自定义TabLayout


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接