編輯:關於Android編程
由於項目需要+有網友咨詢,所以做了個橫向滑頁+某一橫向滑頁中有豎向滑頁的demo,實現有點繞彎子,但基本功能還是比較完善,發上來共享一下。
第一步的思路是自己判斷觸屏拖動位置,然後控制界面橫向或者縱向滑動。
然後,
由於UGUI組件重疊時會屏蔽事件
比如Button會屏蔽掉PointerDown
(PS:當然也可以采取繼承UGUI組件的方式釋放屏蔽事件,
這裡對UGUI源碼不熟,采取自己寫一個事件分發器方便一點)
這裡就不贅述咯,我的前一篇blog有詳細配置說明:
1.首先建立兩個ScrollRect
2.分別給兩個ScrollRect配置格子的ScrollBar,然後關掉以下設置
3.在最外層的ScrollRect配置ScrollControl代碼
(PS:代碼後續給出)
4.配置InputControl
(PS:新建一個Gameobjct就可以咯,也可以掛在已有物體上)
5.運行,檢查效果...
代碼寫的比較急,很多不規范的地方,使用者請看懂邏輯之後自行重構,直接使用者有坑勿怪
using UnityEngine;
public delegate void MouseDownEvent(Vector2 mousePosition);
public delegate void MouseUpEvent(Vector2 mousePosition);
public delegate void MouseDragEvent(Vector2 dragVector);
public delegate void MouseClickEvent(Vector2 mousePosition);
public class InputControl : MonoBehaviour
{
private static InputControl mInstance;
///
/// 逗比單例模式
///
public static InputControl Instance
{
get
{
return mInstance;
}
}
private bool isPress;
private bool isClick;
private bool tempPress;
private Vector2 oldMousePosition;
private Vector2 tempMousePosition;
public event MouseDownEvent EVENT_MOUSE_DOWN;
public event MouseUpEvent EVENT_MOUSE_UP;
public event MouseDragEvent EVENT_MOUSE_DRAG;
public event MouseClickEvent EVENT_MOUSE_CLICK;
///
/// 拖動起始判斷參數,可自行更改
///
public const float JUDGE_DISTANCE = 1F;
void Awake()
{
mInstance = this;
//以下代碼可優化
EVENT_MOUSE_DOWN += AvoidEmpty;
EVENT_MOUSE_UP += AvoidEmpty;
EVENT_MOUSE_DRAG += AvoidEmpty;
EVENT_MOUSE_CLICK += AvoidEmpty;
}
void Start()
{
isPress = false;
isClick = false;
}
///
/// 防空保護函數,無用處,可自行優化
///
///
private void AvoidEmpty(Vector2 noUse) { }
void Update()
{
tempPress = Input.GetMouseButton(0);
tempMousePosition = Input.mousePosition;
// 兩次狀態不同,觸發點擊和抬起事件
if (tempPress != isPress)
{
// 按下事件
if (tempPress)
{
isClick = true;
EVENT_MOUSE_DOWN(tempMousePosition);
}
// 抬起事件
else
{
EVENT_MOUSE_UP(tempMousePosition);
// 點擊事件
if (isClick)
{
EVENT_MOUSE_CLICK(tempMousePosition);
}
isClick = false;
}
}
// 按下的過程中發生了移動,發生事件變化
else if (isClick && JudgeMove(oldMousePosition, tempMousePosition))
{
isClick = false;
}
// 拖動事件
else if (tempPress && !isClick)
{
EVENT_MOUSE_DRAG(tempMousePosition - oldMousePosition);
}
isPress = tempPress;
oldMousePosition = tempMousePosition;
}
///
/// 判斷是否超出靜止范圍,用static速度更快
///
///
///
///
private static bool JudgeMove(Vector2 p1, Vector2 p2)
{
return Mathf.Abs(p1.x - p2.x) > JUDGE_DISTANCE || Mathf.Abs(p1.y - p2.y) > JUDGE_DISTANCE;
}
}
using UnityEngine;
using UnityEngine.UI;
public class ScrollControl : MonoBehaviour
{
///
/// 橫向滾動條
///
public Scrollbar m_HScrollBar;
///
/// 豎向滾動條
///
public Scrollbar[] m_VScrollBars;
///
/// 有豎向滾動的頁面
///
public int[] m_VScrollIndexs;
///
/// 頁面個數
///
public int m_Num;
///
/// 設置移動超過多少百分比之後向下翻頁
///
public float m_NextLimit;
///
/// 滑動敏感值
///
public float m_Sensitive;
///
/// 鼠標上一次的位置
///
private Vector3 mOldPosition;
///
/// 記錄上一次的value
///
private float mOldValue;
private float mTargetPosition = 0.5f;
private int mCurrentIndex = 3;
private int mTargetIndex = 3;
///
/// 是否可以移動
///
private bool mCanMove = false;
///
/// 初始移動速度
///
private float mMoveSpeed;
///
/// 平滑移動參數
///
private const float SMOOTH_TIME = 0.2F;
private float mDragParam = 0;
private float mPageWidth = 0;
///
/// 是否需要進行滑動方向判定
///
private bool mNeedCaculate = false;
///
/// 是否進行豎向滾動
///
private bool mIsScollV = false;
///
/// 豎向臨時滾動條
///
private Scrollbar mVScrollBar;
public void SetNextIndex(int pIndex)
{
mTargetIndex = pIndex;
mTargetPosition = (mTargetIndex - 1) * mPageWidth;
mIsScollV = false;
mCanMove = true;
}
private void OnPointerDown(Vector2 mousePosition)
{
// 記錄當前value
mOldValue = m_HScrollBar.value;
mOldPosition = Input.mousePosition;
// mCanMove = false;
mCurrentIndex = GetCurrentIndex(mOldValue);
// 判斷當前是否在可豎向滑動的頁面上
for (int i = 0; i < m_VScrollIndexs.Length; ++i)
{
if (m_VScrollIndexs[i] == mCurrentIndex)
{
mNeedCaculate = true;
mVScrollBar = m_VScrollBars[i];
break;
}
}
}
private void OnDrag(Vector2 mousePosition)
{
Vector2 dragVector = Input.mousePosition - mOldPosition;
if (mNeedCaculate)
{
mNeedCaculate = false;
if (Mathf.Abs(dragVector.x) > Mathf.Abs(dragVector.y))
{
mIsScollV = false;
}
else
{
mIsScollV = true;
}
}
DragScreen(dragVector);
mOldPosition = Input.mousePosition;
}
private void OnPointerUp(Vector2 mousePosition)
{
Vector2 dragVector = Input.mousePosition - mOldPosition;
DragScreen(dragVector);
mOldPosition = Input.mousePosition;
float valueOffset = m_HScrollBar.value - mOldValue;
if (Mathf.Abs((valueOffset) / mPageWidth) > m_NextLimit)
{
mTargetIndex += valueOffset > 0 ? 1 : -1;
mTargetPosition = (mTargetIndex - 1) * mPageWidth;
}
mCanMove = true;
}
private int GetCurrentIndex(float pCurrentValue)
{
return Mathf.RoundToInt(pCurrentValue / mPageWidth + 1);
}
private void DragScreen(Vector2 pDragVector)
{
if (mIsScollV)
{
float oldValue = mVScrollBar.value;
mVScrollBar.value -= pDragVector.y / Screen.height * mVScrollBar.size;
mMoveSpeed = mVScrollBar.value - oldValue;
}
else
{
float oldValue = m_HScrollBar.value;
m_HScrollBar.value -= pDragVector.x / Screen.width * mDragParam;
mMoveSpeed = m_HScrollBar.value - oldValue;
}
}
void Awake()
{
if (m_Num <= 1)
{
Debug.LogError("參數錯誤:頁面個數不對");
}
mDragParam = 1f / (m_Num - 1) * m_Sensitive;
mPageWidth = 1f / (m_Num - 1);
mCurrentIndex = GetCurrentIndex(m_HScrollBar.value);
mTargetIndex = mCurrentIndex;
}
void Start()
{
InputControl.Instance.EVENT_MOUSE_DOWN += OnPointerDown;
InputControl.Instance.EVENT_MOUSE_UP += OnPointerUp;
InputControl.Instance.EVENT_MOUSE_DRAG += OnDrag;
}
void OnDestory()
{
InputControl.Instance.EVENT_MOUSE_DOWN -= OnPointerDown;
InputControl.Instance.EVENT_MOUSE_UP -= OnPointerUp;
InputControl.Instance.EVENT_MOUSE_DRAG -= OnDrag;
}
void Update()
{
if (mCanMove)
{
if (mIsScollV)
{
mVScrollBar.value += mMoveSpeed;
float absValue = Mathf.Abs(mMoveSpeed);
absValue -= 0.001f;
if (absValue <= 0)
{
mCanMove = false;
}
else
{
mMoveSpeed = mMoveSpeed > 0 ? absValue : -absValue;
}
}
else
{
if (Mathf.Abs(m_HScrollBar.value - mTargetPosition) < 0.01f)
{
m_HScrollBar.value = mTargetPosition;
mCurrentIndex = mTargetIndex;
mCanMove = false;
return;
}
m_HScrollBar.value = Mathf.SmoothDamp(m_HScrollBar.value, mTargetPosition, ref mMoveSpeed, SMOOTH_TIME);
}
}
}
}
新版的微信裡,細心的朋友應該能看到在搜索那裡多出了一個功能:朋友圈熱文。隨時了解朋友圈的熱門文章,不過有不少人都很疑惑微信朋友圈熱文要怎麼查看,下面就讓小編
Starting an Activity 開啟一個ActivityThis lesson teaches you to 這節課教給你Understand the Life
安卓異步任務 ---AsyncTask 為什麼要異步任務: 1.Android單線程模型 2.耗時操作放在非主線程中執行 AsyncTask為何而生 1.子線程中更新
原文來自官方文檔:https://developer.android.com/guide/components/tasks-and-back-stack.html 應用