Xamarin Android TabLayout将片段添加到ViewPager而不是布局

时间:2016-05-27 10:11:03

标签: c# android android-fragments android-viewpager xamarin.android

我是Android开发的新手,并决定在xamarin android中创建一个tabLayout。我把它全部搞定了,但唯一的问题是;我的ViewPager显示的是xml Layouts而不是片段。

我现在无法使用布局内的按钮做任何事情,我已尝试使用适配器等不同的东西,但似乎无法使其正常工作。

TabLayout是自定义的,包含LinearLayout和Horizo​​ntalScrollView。

我的MainActivity添加了整个tabLayout:

 public class MainActivity : Activity
{

    protected override void OnCreate(Bundle bundle)
    {
        base.OnCreate(bundle);

        // Api getapi = new Api();
        // getapi.GetApi();

        // Set our view from the "main" layout resource
        SetContentView(Resource.Layout.Main);           

        FragmentTransaction transaction = FragmentManager.BeginTransaction();
        SlidingTabsFragment fragment = new SlidingTabsFragment();
        transaction.Replace(Resource.Id.sample_content_fragment, fragment);

        transaction.Commit();

    }



}

我的片段与适配器和ViewPager(只是夸大布局丑陋的atm):

    public class SlidingTabsFragment : Fragment
{
    private SlidingTabScrollView mSlidingTabScrollView;
    private ViewPager mViewPager;

    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        var view = inflater.Inflate(Resource.Layout.fragment_sample, container, false);

        return view;
    }

    public override void OnViewCreated(View view, Bundle savedInstanceState)
    {
        mSlidingTabScrollView = view.FindViewById<SlidingTabScrollView>(Resource.Id.sliding_tabs);
        mViewPager = view.FindViewById<ViewPager>(Resource.Id.viewpager);
        mViewPager.Adapter = new SamplePagerAdapter();

        mSlidingTabScrollView.ViewPager = mViewPager;
    }

    public class SamplePagerAdapter : PagerAdapter
    {
        List<string> items = new List<string>();

        public SamplePagerAdapter()
            : base()
        {
            items.Add("Home");
            items.Add("Surfboard kopen");
            items.Add("Surfboard customize");
            items.Add("Nieuwsbrief");
            items.Add("Contact");
            items.Add("FAQ");
        }

        public override int Count
        {
            get { return items.Count; }
        }

        public override bool IsViewFromObject(View view, Java.Lang.Object obj)
        {
            return view == obj;
        }

        public override Java.Lang.Object InstantiateItem(ViewGroup container, int position)
        {
            if (position == 4)
            {
                View view = LayoutInflater.From(container.Context).Inflate(Resource.Layout.Contact, container, false);
                container.AddView(view);

                return view;
            }

            if (position == 0)
            {
                View view = LayoutInflater.From(container.Context).Inflate(Resource.Layout.Home, container, false);
                container.AddView(view);

                return view;
            }

        }

        public string GetHeaderTitle(int position)
        {
            return items[position];
        }

        public override void DestroyItem(ViewGroup container, int position, Java.Lang.Object obj)
        {
            container.RemoveView((View)obj);
        }
    }
}

Main.axml:

<?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#E2E2E2"
        android:id="@+id/sample_main_layout">
        <FrameLayout
            android:id="@+id/sample_content_fragment"
            android:layout_weight="2"
            android:layout_width="match_parent"
            android:layout_height="0px" />
    </LinearLayout>

fragment_sample.axml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">
    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/backgroundd"
        android:src="@drawable/SurfChicks"
        android:scaleType="centerCrop"
        android:alpha="0.35" />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
        <Smoothboard_Stylers_App.SlidingTabScrollView
            android:id="@+id/sliding_tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
        <android.support.v4.view.ViewPager
            android:id="@+id/viewpager"
            android:layout_width="match_parent"
            android:layout_height="0px"
            android:layout_weight="1" />
    </LinearLayout>
</RelativeLayout>

Scrollview:

namespace Smoothboard_Stylers_App
{
    public class SlidingTabScrollView : HorizontalScrollView
    {
        private const int TITLE_OFFSET_DIPS = 24;
        private const int TAB_VIEW_PADDING_DIPS = 16;
        private const int TAB_VIEW_TEXT_SIZE_SP = 12;

        private int mTitleOffset;

        private int mTabViewLayoutID;
        private int mTabViewTextViewID;

        private ViewPager mViewPager;
        private ViewPager.IOnPageChangeListener mViewPagerPageChangeListener;

        private static SlidingTabStrip mTabStrip;

        private int mScrollState;
        public interface TabColorizer
        {
            int GetIndicatorColor(int position);
            int GetDividerColor(int position);
        }

        public SlidingTabScrollView(Context context) : this(context, null) { }

        public SlidingTabScrollView(Context context, IAttributeSet attrs) : this(context, attrs, 0) { }

        public SlidingTabScrollView(Context context, IAttributeSet attrs, int defaultStyle)
            : base(context, attrs, defaultStyle)
        {
            //Disable the scroll bar
            HorizontalScrollBarEnabled = false;

            //Make sure the tab strips fill the view
            FillViewport = true;
            this.SetBackgroundColor(Android.Graphics.Color.Rgb(0xE5, 0xE5, 0xE5)); //Gray color

            mTitleOffset = (int)(TITLE_OFFSET_DIPS * Resources.DisplayMetrics.Density);

            mTabStrip = new SlidingTabStrip(context);
            this.AddView(mTabStrip, LayoutParams.MatchParent, LayoutParams.MatchParent);
        }

        public TabColorizer CustomTabColorizer
        {
            set { mTabStrip.CustomTabColorizer = value; }
        }

        public int[] SelectedIndicatorColor
        {
            set { mTabStrip.SelectedIndicatorColors = value; }
        }

        public int[] DividerColors
        {
            set { mTabStrip.DividerColors = value; }
        }

        public ViewPager.IOnPageChangeListener OnPageListener
        {
            set { mViewPagerPageChangeListener = value; }
        }

        public ViewPager ViewPager
        {
            set
            {
                mTabStrip.RemoveAllViews();

                mViewPager = value;
                if (value != null)
                {
                    value.PageSelected += value_PageSelected;
                    value.PageScrollStateChanged += value_PageScrollStateChanged;
                    value.PageScrolled += value_PageScrolled;
                    PopulateTabStrip();
                }
            }
        }

        void value_PageScrolled(object sender, ViewPager.PageScrolledEventArgs e)
        {
            int tabCount = mTabStrip.ChildCount;

            if ((tabCount == 0) || (e.Position < 0) || (e.Position >= tabCount))
            {
                //if any of these conditions apply, return, no need to scroll
                return;
            }

            mTabStrip.OnViewPagerPageChanged(e.Position, e.PositionOffset);

            View selectedTitle = mTabStrip.GetChildAt(e.Position);

            int extraOffset = (selectedTitle != null ? (int)(e.Position * selectedTitle.Width) : 0);

            ScrollToTab(e.Position, extraOffset);

            if (mViewPagerPageChangeListener != null)
            {
                mViewPagerPageChangeListener.OnPageScrolled(e.Position, e.PositionOffset, e.PositionOffsetPixels);
            }

        }

        void value_PageScrollStateChanged(object sender, ViewPager.PageScrollStateChangedEventArgs e)
        {
            mScrollState = e.State;

            if (mViewPagerPageChangeListener != null)
            {
                mViewPagerPageChangeListener.OnPageScrollStateChanged(e.State);
            }
        }

        void value_PageSelected(object sender, ViewPager.PageSelectedEventArgs e)
        {
            if (mScrollState == ViewPager.ScrollStateIdle)
            {
                mTabStrip.OnViewPagerPageChanged(e.Position, 0f);
                ScrollToTab(e.Position, 0);

            }

            if (mViewPagerPageChangeListener != null)
            {
                mViewPagerPageChangeListener.OnPageSelected(e.Position);
            }
        }

        private void PopulateTabStrip()
        {
            PagerAdapter adapter = mViewPager.Adapter;

            for (int i = 0; i < adapter.Count; i++)
            {
                TextView tabView = CreateDefaultTabView(Context);
                tabView.Text = ((SlidingTabsFragment.SamplePagerAdapter)adapter).GetHeaderTitle(i);
                tabView.SetTextColor(Android.Graphics.Color.Black);
                tabView.Tag = i;
                tabView.Click += tabView_Click;
                mTabStrip.AddView(tabView);
            }

        }

        void tabView_Click(object sender, EventArgs e)
        {
            TextView clickTab = (TextView)sender;
            int pageToScrollTo = (int)clickTab.Tag;
            mViewPager.CurrentItem = pageToScrollTo;
        }

        private TextView CreateDefaultTabView(Android.Content.Context context)
        {
            TextView textView = new TextView(context);
            textView.Gravity = GravityFlags.Center;
            textView.SetTextSize(ComplexUnitType.Sp, TAB_VIEW_TEXT_SIZE_SP);
            textView.Typeface = Android.Graphics.Typeface.DefaultBold;

            if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Honeycomb)
            {
                TypedValue outValue = new TypedValue();
                Context.Theme.ResolveAttribute(Android.Resource.Attribute.SelectableItemBackground, outValue, false);
                textView.SetBackgroundResource(outValue.ResourceId);
            }

            if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.IceCreamSandwich)
            {
                textView.SetAllCaps(true);
            }

            int padding = (int)(TAB_VIEW_PADDING_DIPS * Resources.DisplayMetrics.Density);
            textView.SetPadding(padding, padding, padding, padding);

            return textView;
        }

        protected override void OnAttachedToWindow()
        {
            base.OnAttachedToWindow();

            if (mViewPager != null)
            {
                ScrollToTab(mViewPager.CurrentItem, 0);
            }
        }

        private void ScrollToTab(int tabIndex, int extraOffset)
        {
            int tabCount = mTabStrip.ChildCount;

            if (tabCount == 0 || tabIndex < 0 || tabIndex >= tabCount)
            {
                //No need to go further, dont scroll
                return;
            }

            View selectedChild = mTabStrip.GetChildAt(tabIndex);
            if (selectedChild != null)
            {
                int scrollAmountX = selectedChild.Left + extraOffset;

                if (tabIndex > 0 || extraOffset > 0)
                {
                    scrollAmountX -= mTitleOffset;
                }

                this.ScrollTo(scrollAmountX, 0);
            }

        }
    }
}

这是它的样子: Image

非常感谢任何帮助,谢谢!

1 个答案:

答案 0 :(得分:4)

您应该使用DOMReady代替:

使用FragmentPagerAdapter方法创建片段并充气xml。

您的OnCreate应如下所示:

FragmentPagerAdapter

然后在您的活动或片段中初始化viewpager。

public class MenuPagerAdapter : FragmentPagerAdapter
{
    private string[] Titles;
    private List<Android.Support.V4.App.Fragment> _fragments;
    Android.Support.V4.App.FragmentManager _fragmentManager;

    public MenuPagerAdapter(Android.Support.V4.App.FragmentManager fm, string[] titles)
        : base(fm)
    {
        Titles = titles;
        _fragments = new List<Android.Support.V4.App.Fragment>();
        _fragments.Add(new HomeFragment());
        _fragments.Add(new SurfboardKopenFragment());
        _fragments.Add(new NieuwsbriefFragment());
        _fragments.Add(new ContactFragment()); // and etc.
    }

    public override Android.Support.V4.App.Fragment GetItem(int position)
    {
        return _fragments[position];
    }

    public override ICharSequence GetPageTitleFormatted(int position)
    {

       return new Java.Lang.String(Titles[position]);
    }

    public override int Count
    {
        get { Titles.Length; } // amount of fragments you have = Amount of Tab titles.
    }

    public override int GetItemPosition(Java.Lang.Object objectValue)
    {
        return PositionNone;
    }

    public Android.Support.V4.App.Fragment GetFragment(int position)
    {
        return  _fragments[position];
    }
}

在您的片段或活动中实施 private MenuPagerAdapter adapter; private CustomViewPager pager; void InitAdapter() { string[] titles = new [] { "Home", "..." }; pager = FindViewById<CustomViewPager>(Resource.Id.pager); pager.EnableTouchEvents(true); adapter = new MenuPagerAdapter(SupportFragmentManager, titles); var pageMargin = (int)TypedValue.ApplyDimension(ComplexUnitType.Dip, 4, Resources.DisplayMetrics); pager.OffscreenPageLimit = titles.Length;//amount of fragments you want to stay in memory(for faster tab change) pager.PageMargin = pageMargin; pager.AddOnPageChangeListener(this); pager.Adapter = adapter; pager.CurrentItem = 0; }

Android.Support.V4.View.ViewPager.IOnPageChangeListener

重要说明: 如果您坚持在片段中使用public void OnPageScrollStateChanged(int state) { } public void OnPageScrolled(int position, float positionOffset, int positionOffsetPixels) { // Do anything you like when page scrolls } public void OnPageSelected(int position) { // Do anything you like when tab is clicked. Position is clicked Tab position. switch (position) { case 0: break; case 1: break; case 2: break; case 3: break; case 4: break; case 5: break; default: break; } } ,则应使用ChildFragmentManager adapter = new MenuPagerAdapter(SupportFragmentManager, this, pager);代替SupportFragmentManager

重要建议: 完全删除viewpager并将所有内容从此处移至MainActivity。

编辑:由于代码中存在一些复制/粘贴错误,因此决定使用PagerSlidingTabStrip创建示例项目。玩得开心: PagerSlidingTabStrip-Sample