[Xamarin] 可滑動Tab 實作

2016-07-27

今天要製作一個有滑動功能的Tab ,大概像是這樣
Screenshot_20160727-161822
因為網路上的範例都頗複雜,所以我就把範例盡量簡單化
1.首先,當然我們不是全部都自己寫,我們主要是用一個網路上的open source ( https://github.com/Cheesebaron/ViewPagerIndicator ) ,在這邊感謝各位Open source 的大大提供套件,之後編譯你會拿到 DK.Ostebaronen.Droid.ViewPagerIndicator.v4.dll 並且把他引入。

2.我們要下載一些xamarin 上的 components
Xamarin Android Support Library v4Android Support Library v7 AppCompat ,引入第一步的 DK.Ostebaronen.Droid.ViewPagerIndicator.v4.dll  跟這兩個 components

3. simple_tabs.axml View 的部分

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <dk.ostebaronen.droid.viewpagerindicator.TabPageIndicator
        android:id="@+id/indicator"
        android:layout_height="wrap_content"
        android:layout_width="fill_parent" />
    <android.support.v4.view.ViewPager
        android:id="@+id/pager"
        android:layout_width="fill_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
</LinearLayout>

4. 製作Adapter  ,主要放入 Tab 上方標題跟圖示的相關資訊 TestDataAdapter.cs :

class TestDataAdapter : FragmentPagerAdapter, IIconPageAdapter
{
 
    //上方選單
    private static readonly string[] MenuText = { "Tab1", "選單2" };
 
    /// <summary>
    /// 預設的Icon 清單
    /// </summary>
    private static readonly int[] MenuIcons =
    {
        Resource.Drawable.ic_sentiment_dissatisfied_white_48dp,
        Resource.Drawable.ic_sentiment_neutral_white_48dp,
 
    };
 
    public TestDataAdapter(IntPtr javaReference, JniHandleOwnership transfer) : base(javaReference, transfer)
    {
    }
 
    public TestDataAdapter(FragmentManager fm) : base(fm)
    {
    }
 
 
    //取得Icon 
    public int GetIconResId(int index)
    {
        return MenuIcons[index % MenuIcons.Length];
    }
 
    public override int Count
    {
        get { return MenuText.Length; }
    }
    public override Fragment GetItem(int position)
    {
        var res = new TabContentFragment();
        res.Content = MenuText[position % MenuText.Length];
        return res;
    }
 
 
    public override Java.Lang.ICharSequence GetPageTitleFormatted(int p0)
    {
        return new Java.Lang.String(MenuText[p0 % MenuText.Length].ToLower());
    }
}

5. 其中GetItem  的時候他必須要知道你的內容是啥,這時候我們宣告一個TabContentFragment 來處理選到每一個tab 的時候的處理事件

public class TabContentFragment : Fragment
{
    public string Content { get; set; }
 
 
    public override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
 
    }
 
    public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
    {
        //判斷是哪一個Tab被選取了
 
        if (Content == "Tab1")
        {
            var v = inflater.Inflate(Resource.Layout.firstpage, container, false);
            return v;
        }
        else if (Content == "選單2")
        {
            var v = inflater.Inflate(Resource.Layout.second, container, false);
            return v;
        }
 
 
        //如果不是自訂的 我就回傳一個簡單的東西
        return new LinearLayout(Activity)
        {
            LayoutParameters =
                      new ViewGroup.LayoutParams(
                          ViewGroup.LayoutParams.MatchParent,
                          ViewGroup.LayoutParams.MatchParent)
        };
 
    }
}

這裡面在OnCreateView 會根據傳入的Content 決定要去Inflate啥,這裡也可以在inflate 時候處理相關的資料

6.將第三部的View 邦定程式 MainActivity.cs:

[Activity(Label = "SlideTabSample", MainLauncher = true, Icon = "@drawable/icon")]
public class MainActivity : FragmentActivity
{
  //  protected TestFragmentAdapter _adapter;
    protected ViewPager _pager;
    protected IPageIndicator _indicator;
 
    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
 
        SetContentView(Resource.Layout.simple_tabs);
 
        var adapter = new TestDataAdapter(SupportFragmentManager);
 
        _pager = FindViewById<ViewPager>(Resource.Id.pager);
        _pager.Adapter = adapter;
 
        _indicator = FindViewById<TabPageIndicator>(Resource.Id.indicator);
        _indicator.SetViewPager(_pager);
    }
}

結果:
Screenshot_20160727-161443Screenshot_20160727-161446

reference : https://github.com/Cheesebaron/ViewPagerIndicator

source : https://www.dropbox.com/s/328kfpe77hjwdza/SlideTabSample.7z?dl=0


當麻許的超技八 2014 | Donma Hsu Design.