您的位置:首页 > 产品设计 > UI/UE

NGUI 仿android viewapger+listview效果

2016-05-16 17:12 465 查看

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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: