以下に関するカスタム ビューを使用して ToolBar コントロールを実装します。目標はActionBar
、ビジネス要件に応じて Xamarin.Android フレームワークを使用せずにスクロール機能を実現することです。必要な機能は、左右のスワイプ、ツールバーのボタンのドラッグ、フリングなどです。
スクロールはより正確に機能する必要があります。たとえば、ユーザーがツールバーを左から右または右から左に非常に速くスクロール (またはフリング) すると、最後のボタンが直接表示されます。つまりActionBar
、最新の Android デバイスのほとんどに付属しています。
これを達成するための正しいコールバック方法は何ですか?
高レベルの設計上の考慮事項は次のとおりです。ツールバー ボタン クラスの実装ImageButton
。ActionBar
ToolBar ボタンは、現時点では使用したくない ViewGroup を実装するカスタム ビューである ToolBarControl クラスの内部クラスとして設計されています。OnMeasure
、OnLayout
メソッドをオーバーライドして実装OnTouch()
したいと思いOnFling()
ます。をオーバーライドOnInterceptTouchEvent(MotionEvent ev)
しOnTouchEvent(MotionEvent ev)
ます。http://developer.android.com/training/gestures/index.htmlのサンプル コードに基づく
コードスニペット:
//To Implement Scrolling
//to watch events by ViewGroup as they are dispatched to child Views
public override bool OnInterceptTouchEvent(MotionEvent e)
{
//System.out.println(...)
Console.WriteLine("OnInterceptTouchEvent");
Boolean intercept = false;
ViewConfiguration configuration = ViewConfiguration
.Get(Context);
int mTouchSlop = configuration.ScaledTouchSlop;
try
{
switch (e.Action)
{
case MotionEventActions.Move:
{
int xDiff = (int)Math.Abs(e.GetX() - m_fLastX);
if (xDiff > mTouchSlop)
{
m_nTouchState = c_nTouchStateHorizontalScrolling;
m_fLastX = e.GetX();
}
int yDiff = (int)Math.Abs(e.GetY() - m_fLastY);
if (yDiff > mTouchSlop)
{
m_nTouchState = -1;
}
if (Math.Abs(xDiff * 2) > Math.Abs(yDiff) && xDiff > mTouchSlop)
{
intercept = true;
}
break;
}
case MotionEventActions.Cancel:
case MotionEventActions.Up:
// Release the drag.
m_nTouchState = c_nTouchStateRest;
break;
case MotionEventActions.Down:
m_fLastY = e.GetY();
m_fLastX = e.GetX();
break;
default:
break;
}
}
catch (Exception ex)
{
}
return intercept;
}
public override bool OnTouchEvent(MotionEvent e)
{
//System.out.println(...)
Console.WriteLine("TB OnTouchEvent");
try
{
float x = e.GetX();
float y = e.GetY();
switch (e.Action)
{
case MotionEventActions.Down:
if (!m_scroller.IsFinished)
{
m_scroller.AbortAnimation();
}
m_fLastX = x;
if (m_scroller.IsFinished)
{
m_nTouchState = c_nTouchStateRest;
}
else
{
m_nTouchState = c_nTouchStateHorizontalScrolling;
}
break;
case MotionEventActions.Move:
int deltaX = (int)(m_fLastX - x);
m_fLastX = x;
int scrollX = ScrollX;
// Scroll to right
if (deltaX < 0)
{
if (scrollX > 0)
{
ScrollBy(Math.Max(-scrollX, deltaX), 0);
}
}
// Scroll to left
else if (deltaX > 0)
{
// Visible full icons always without empty spaces
int availableToScroll =
GetChildAt(ChildCount - 1).Right - scrollX - (display.Width - c_nToolIndent);
if (availableToScroll > 0)
{
ScrollBy(Math.Min(availableToScroll, deltaX), 0);
}
}
break;