NGUI 仿android viewapger+listview效果

NGUI 仿android viewapger+listview效果

  辞职半个月,打算从cocos2dx转unity。这里吐槽一下触控,已经迷失了发展方向,cocos发展成现在这个不着调的样子,触控难辞其咎。本来是挺好的开源项目,如果能像mycat和jfinal这样的做开源的话,不会落到今天这样的地步。当然这只是个人的愚见,全当牢骚好了。
  进入正题,最近在玩《皇室战争》,很喜欢它的UI设计,所以打算在unity模仿。
  viewapger+listview效果的效果简而言之就是横向滑动时翻页,竖向滑动时滚动该页的内容。就像微信主界面,横向滑动可以在聊天、通讯录、朋友圈和我这几个界面页里切换,同时当在聊天列表里竖滑的时候可以查看聊天列表的内容。在android里开发可以很简单的实现,用viewapger+listview写好布局文件,自己处理一下滑动冲突,基本上就能实现了。在NGUI中需要自己实现一下触摸消息的分发才可以,下面介绍一下我的思路。
  首先定义一个scroll view 来处理横向滑动的翻页。这里提供一下我重载NGUI的俩个脚本:

ScrollViewDrageControll:用来控制滑动

    public class ScrollViewDrageControll : MonoBehaviour
{
    /// <summary>
    /// Reference to the scroll view that will be dragged by the script.
    /// </summary>

    public UIScrollView scrollView;

    // Legacy functionality, kept for backwards compatibility. Use 'scrollView' instead.
    [HideInInspector]
    [SerializeField]
    UIScrollView draggablePanel;

    UIScrollView.Movement curMovement;
    UIScrollView.Movement oldMovement = UIScrollView.Movement.Unrestricted;
    ScrollViewCenterChild curCenterChild;

    Transform mTrans;
    UIScrollView mScroll;
    bool mAutoFind = false;
    bool mStarted = false;

    /// <summary>
    /// Automatically find the scroll view if possible.
    /// </summary>

    void OnEnable()
    {
        mTrans = transform;

        // Auto-upgrade
        if (scrollView == null && draggablePanel != null)
        {
            scrollView = draggablePanel;
            draggablePanel = null;
        }

        if (mStarted && (mAutoFind || mScroll == null))
            FindScrollView();
    }

    /// <summary>
    /// Find the scroll view.
    /// </summary>

    void Start()
    {
        mStarted = true;
        GameObject gridObject = GameObject.FindGameObjectWithTag("main_scroll grid");
        curCenterChild = gridObject.GetComponentInChildren<ScrollViewCenterChild>();
        FindScrollView();
    }

    /// <summary>
    /// Find the scroll view to work with.
    /// </summary>

    void FindScrollView()
    {
        // If the scroll view is on a parent, don't try to remember it (as we want it to be dynamic in case of re-parenting)
        UIScrollView sv = NGUITools.FindInParents<UIScrollView>(mTrans);

        if (scrollView == null || (mAutoFind && sv != scrollView))
        {
            scrollView = sv;
            mAutoFind = true;
        }
        else if (scrollView == sv)
        {
            mAutoFind = true;
        }
        mScroll = scrollView;
    }

    /// <summary>
    /// Create a plane on which we will be performing the dragging.
    /// </summary>

    void OnPress(bool pressed)
    {
        // If the scroll view has been set manually, don't try to find it again
        if (mAutoFind && mScroll != scrollView)
        {
            mScroll = scrollView;
            mAutoFind = false;
        }

        if (scrollView && enabled && NGUITools.GetActive(gameObject))
        {
            scrollView.Press(pressed);

            if (!pressed && mAutoFind)
            {
                scrollView = NGUITools.FindInParents<UIScrollView>(mTrans);
                mScroll = scrollView;
            }
        }

        if (!pressed)
        {
            oldMovement = UIScrollView.Movement.Unrestricted;
        }
    }

    /// <summary>
    /// Drag the object along the plane.
    /// </summary>

    void OnDrag(Vector2 delta)
    {
        if (delta.x == 0)
        {
            curMovement = UIScrollView.Movement.Vertical;
        }
        else
        {
            curMovement = UIScrollView.Movement.Horizontal;
        }
        if(oldMovement == UIScrollView.Movement.Unrestricted)
        {
            oldMovement = curMovement;
        }
        if (oldMovement != curMovement)
        {
            return;
        }



        if (scrollView && NGUITools.GetActive(this))
        {
            //横向滑动的scroll view
            if (scrollView.transform.name == "main_scroll view")
            {
                if (delta.y == 0)
                {
                    scrollView.Drag();
                }
            }
            else
            {
                GameObject gameObject = curCenterChild.CurPage;
                if (gameObject && scrollView == gameObject.GetComponentInChildren<UIScrollView>())
                {
                    if (delta.x == 0)
                    {
                        scrollView.Drag();
                    }
                }
            }
        }
    }

    /// <summary>
    /// If the object should support the scroll wheel, do it.
    /// </summary>

    void OnScroll(float delta)
    {
        if (scrollView && NGUITools.GetActive(this))
            scrollView.Scroll(delta);
    }

    /// <summary>
    /// Pan the scroll view.
    /// </summary>

    public void OnPan(Vector2 delta)
    {
        if (scrollView && NGUITools.GetActive(this))
            scrollView.OnPan(delta);
    }
}
ScrollViewCenterChild:用来实现翻页效果并且记录当前页
    public class ScrollViewCenterChild : UICenterOnChild
{

    //当前页
    GameObject curPage;
    public GameObject CurPage
    {
        get { return curPage; }
    }
    // Use this for initialization
    void Start()
    {
        base.onCenter = new OnCenterCallback(this.getCurPage);
        base.Recenter();
    }

    void getCurPage(GameObject g)
    {
        curPage = g;
    }

}
  在UI Root下建立一个UI Widget,在这个UI Widget添加BOX Collider,有几个scroll view 就添加几个 ScrollViewDrageControll脚本,里面的参数添加需要控制的那个scroll view。ScrollViewCenterChild添加到与UI Grid同一个对象上即可。
  每一次翻页,ScrollViewCenterChild 都会记录下当前显示的页对象。在滑动的时候,首先判断方向,如果横滑则直接拖动主scroll view,如果竖滑则拖动当前正在显示的scroll view上。
  这里不足之处在于方向上的判断过于生硬,在正式的项目上扩大范围才能获得好的体验。
  实在不好意思,第一次发文章,图片死活插不进去,底下有例子的链接,里面有代码和资源。需要自己导入NGUI,我用的是3.9.4这版本。
  欢迎各位拍砖。
  下载地址:
  <http://pan.baidu.com/s/1dFjrdnz>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值