Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Vamos ver como usar os conceitos da seção anterior em um aplicativo de trabalho. Vamos criar um aplicativo com quatro atividades. A primeira atividade será um menu ou um quadro de distribuição que iniciará as outras atividades para demonstrar as várias APIs. A captura de tela a seguir mostra a atividade principal:
A primeira Atividade, Exemplo de Toque, mostrará como usar manipuladores de eventos para tocar nos Modos de Exibição. A atividade Reconhecedor de gestos demonstrará como subclassificar Android.View.Views e manipular eventos, bem como mostrará como lidar com gestos de pinça. A terceira e última atividade, Gesto Personalizado, mostrará como usar gestos personalizados. Para tornar as coisas mais fáceis de seguir e absorver, dividiremos este passo a passo em seções, com cada seção se concentrando em uma das Atividades.
Atividade de amostra de toque
Abra o TouchWalkthrough_Start do projeto. A MainActivity está pronta para funcionar – cabe a nós implementar o comportamento de toque na atividade. Se você executar o aplicativo e clicar em Touch Sample, a seguinte atividade deverá ser iniciada:
Agora que confirmamos que a atividade é iniciada, abra o TouchActivity.cs de arquivo e adicione um manipulador para o
Touchevento doImageView:_touchMeImageView.Touch += TouchMeImageViewOnTouch;Em seguida, adicione o seguinte método ao TouchActivity.cs:
private void TouchMeImageViewOnTouch(object sender, View.TouchEventArgs touchEventArgs) { string message; switch (touchEventArgs.Event.Action & MotionEventActions.Mask) { case MotionEventActions.Down: case MotionEventActions.Move: message = "Touch Begins"; break; case MotionEventActions.Up: message = "Touch Ends"; break; default: message = string.Empty; break; } _touchInfoTextView.Text = message; }
Observe no código acima que tratamos a Move ação como Down a mesma. Isso porque, mesmo que o usuário não levante o dedo do ImageView, ele pode se movimentar ou a pressão exercida pelo usuário pode mudar. Esses tipos de alterações gerarão uma Move ação.
Cada vez que o usuário tocar no ImageView, o Touch evento será gerado e nosso manipulador exibirá a mensagem Touch Begins na tela, conforme mostrado na captura de tela a seguir:
Enquanto o usuário estiver tocando no ImageView, Touch Begins será exibido no TextView. Quando o usuário não estiver mais tocando no ImageView, a mensagem Touch Ends será exibida no TextView, conforme mostrado na captura de tela a seguir:
Atividade do Reconhecedor de Gestos
Agora vamos implementar a atividade Gesture Recognizer. Esta atividade demonstrará como arrastar uma exibição pela tela e ilustrará uma maneira de implementar o pinça-para-zoom.
Adicione uma nova Atividade ao aplicativo chamado
GestureRecognizer. Edite o código para essa atividade para que ele se pareça com o seguinte código:public class GestureRecognizerActivity : Activity { protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); View v = new GestureRecognizerView(this); SetContentView(v); } }Adicione um novo modo de exibição do Android ao projeto e nomeie-o
GestureRecognizerView. Adicione as seguintes variáveis a esta classe:private static readonly int InvalidPointerId = -1; private readonly Drawable _icon; private readonly ScaleGestureDetector _scaleDetector; private int _activePointerId = InvalidPointerId; private float _lastTouchX; private float _lastTouchY; private float _posX; private float _posY; private float _scaleFactor = 1.0f;Adicione o seguinte construtor ao
GestureRecognizerView. Este construtor irá adicionar um àImageViewnossa atividade. Neste ponto, o código ainda não será compilado – precisamos criar a classeMyScaleListenerque ajudará a redimensionar oImageViewquando o usuário o pinçar:public GestureRecognizerView(Context context): base(context, null, 0) { _icon = context.Resources.GetDrawable(Resource.Drawable.Icon); _icon.SetBounds(0, 0, _icon.IntrinsicWidth, _icon.IntrinsicHeight); _scaleDetector = new ScaleGestureDetector(context, new MyScaleListener(this)); }Para desenhar a imagem em nossa atividade, precisamos substituir o
OnDrawmétodo da classe View, conforme mostrado no trecho a seguir. Esse código moverá oImageViewpara a posição especificada por_posXe_posYtambém redimensionará a imagem de acordo com o fator de escala:protected override void OnDraw(Canvas canvas) { base.OnDraw(canvas); canvas.Save(); canvas.Translate(_posX, _posY); canvas.Scale(_scaleFactor, _scaleFactor); _icon.Draw(canvas); canvas.Restore(); }Em seguida, precisamos atualizar a variável
_scaleFactorde instância à medida que o usuário pinça oImageView. Vamos adicionar uma classe chamadaMyScaleListener. Essa classe ouvirá os eventos de escala que serão gerados pelo Android quando o usuário pinçar oImageView. Adicione a seguinte classe interna aoGestureRecognizerView. Esta classe é umScaleGesture.SimpleOnScaleGestureListenerarquivo . Essa classe é uma classe de conveniência que os ouvintes podem subclassificar quando você estiver interessado em um subconjunto de gestos:private class MyScaleListener : ScaleGestureDetector.SimpleOnScaleGestureListener { private readonly GestureRecognizerView _view; public MyScaleListener(GestureRecognizerView view) { _view = view; } public override bool OnScale(ScaleGestureDetector detector) { _view._scaleFactor *= detector.ScaleFactor; // put a limit on how small or big the image can get. if (_view._scaleFactor > 5.0f) { _view._scaleFactor = 5.0f; } if (_view._scaleFactor < 0.1f) { _view._scaleFactor = 0.1f; } _view.Invalidate(); return true; } }O próximo método que precisamos substituir é
GestureRecognizerViewOnTouchEvent. O código a seguir lista a implementação completa desse método. Há muito código aqui, então vamos dar um minuto e ver o que está acontecendo aqui. A primeira coisa que esse método faz é dimensionar o ícone, se necessário – isso é tratado chamando_scaleDetector.OnTouchEvent. Em seguida, tentamos descobrir qual ação chamou esse método:Se o usuário tocou na tela com, gravamos as posições X e Y e o ID do primeiro ponteiro que tocou na tela.
Se o usuário moveu seu toque na tela, então descobrimos até onde o usuário moveu o ponteiro.
Se o usuário tiver retirado o dedo da tela, pararemos de rastrear os gestos.
public override bool OnTouchEvent(MotionEvent ev) { _scaleDetector.OnTouchEvent(ev); MotionEventActions action = ev.Action & MotionEventActions.Mask; int pointerIndex; switch (action) { case MotionEventActions.Down: _lastTouchX = ev.GetX(); _lastTouchY = ev.GetY(); _activePointerId = ev.GetPointerId(0); break; case MotionEventActions.Move: pointerIndex = ev.FindPointerIndex(_activePointerId); float x = ev.GetX(pointerIndex); float y = ev.GetY(pointerIndex); if (!_scaleDetector.IsInProgress) { // Only move the ScaleGestureDetector isn't already processing a gesture. float deltaX = x - _lastTouchX; float deltaY = y - _lastTouchY; _posX += deltaX; _posY += deltaY; Invalidate(); } _lastTouchX = x; _lastTouchY = y; break; case MotionEventActions.Up: case MotionEventActions.Cancel: // We no longer need to keep track of the active pointer. _activePointerId = InvalidPointerId; break; case MotionEventActions.PointerUp: // check to make sure that the pointer that went up is for the gesture we're tracking. pointerIndex = (int) (ev.Action & MotionEventActions.PointerIndexMask) >> (int) MotionEventActions.PointerIndexShift; int pointerId = ev.GetPointerId(pointerIndex); if (pointerId == _activePointerId) { // This was our active pointer going up. Choose a new // action pointer and adjust accordingly int newPointerIndex = pointerIndex == 0 ? 1 : 0; _lastTouchX = ev.GetX(newPointerIndex); _lastTouchY = ev.GetY(newPointerIndex); _activePointerId = ev.GetPointerId(newPointerIndex); } break; } return true; }Agora execute o aplicativo e inicie a atividade do Reconhecedor de Gestos. Quando ele é iniciado, a tela deve se parecer com a captura de tela abaixo:
Agora toque no ícone e arraste-o pela tela. Experimente o gesto de apertar para ampliar. Em algum momento, sua tela pode se parecer com a seguinte captura de tela:
Neste ponto, você deve dar um tapinha nas costas: você acabou de implementar o pinch-to-zoom em um aplicativo Android! Faça uma pausa rápida e vamos passar para a terceira e última Atividade neste passo a passo – usando gestos personalizados.
Atividade de gesto personalizado
A tela final neste passo a passo usará gestos personalizados.
Para os fins deste Passo a passo, a biblioteca de gestos já foi criada usando a Ferramenta de Gestos e adicionada ao projeto no arquivo Recursos/raw/gestos. Com este pouco de limpeza fora do caminho, vamos continuar com a atividade final no passo a passo.
Adicione um arquivo de layout chamado custom_gesture_layout.axml ao projeto com o conteúdo a seguir. O projeto já tem todas as imagens na pasta Recursos :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> <ImageView android:src="@drawable/check_me" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="3" android:id="@+id/imageView1" android:layout_gravity="center_vertical" /> <LinearLayout android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" /> </LinearLayout>Em seguida, adicione uma nova Atividade ao projeto e nomeie-a
CustomGestureRecognizerActivity.cs. Adicione duas variáveis de instância à classe, conforme mostrado nas duas linhas de código a seguir:private GestureLibrary _gestureLibrary; private ImageView _imageView;Edite o
OnCreatemétodo desta atividade para que ele se pareça com o código a seguir. Vamos tirar um minuto para explicar o que está acontecendo neste código. A primeira coisa que fazemos é instanciar umGestureOverlayViewe defini-lo como a exibição raiz da Atividade. Também atribuímos um manipulador de eventos aoGesturePerformedevento deGestureOverlayView. Em seguida, inflamos o arquivo de layout que foi criado anteriormente e adicionamos isso como uma exibição filho doGestureOverlayView. A etapa final é inicializar a variável_gestureLibrarye carregar o arquivo de gestos dos recursos do aplicativo. Se o arquivo de gestos não puder ser carregado por algum motivo, não há muito que essa atividade possa fazer, então ele é desligado:protected override void OnCreate(Bundle bundle) { base.OnCreate(bundle); GestureOverlayView gestureOverlayView = new GestureOverlayView(this); SetContentView(gestureOverlayView); gestureOverlayView.GesturePerformed += GestureOverlayViewOnGesturePerformed; View view = LayoutInflater.Inflate(Resource.Layout.custom_gesture_layout, null); _imageView = view.FindViewById<ImageView>(Resource.Id.imageView1); gestureOverlayView.AddView(view); _gestureLibrary = GestureLibraries.FromRawResource(this, Resource.Raw.gestures); if (!_gestureLibrary.Load()) { Log.Wtf(GetType().FullName, "There was a problem loading the gesture library."); Finish(); } }A última coisa que precisamos fazer é implementar o método
GestureOverlayViewOnGesturePerformed, conforme mostrado no trecho de código a seguir. Quando o detecta um gestoGestureOverlayView, ele chama de volta para esse método. A primeira coisa que tentamos obter umIList<Prediction>objeto que corresponda ao gesto chamando_gestureLibrary.Recognize(). Usamos um pouco de LINQ para obter aPredictionpontuação mais alta para o gesto.Se não houver nenhum gesto de correspondência com uma pontuação alta o suficiente, o manipulador de eventos será encerrado sem fazer nada. Caso contrário, verificamos o nome da previsão e alteramos a imagem que está sendo exibida com base no nome do gesto:
private void GestureOverlayViewOnGesturePerformed(object sender, GestureOverlayView.GesturePerformedEventArgs gesturePerformedEventArgs) { IEnumerable<Prediction> predictions = from p in _gestureLibrary.Recognize(gesturePerformedEventArgs.Gesture) orderby p.Score descending where p.Score > 1.0 select p; Prediction prediction = predictions.FirstOrDefault(); if (prediction == null) { Log.Debug(GetType().FullName, "Nothing seemed to match the user's gesture, so don't do anything."); return; } Log.Debug(GetType().FullName, "Using the prediction named {0} with a score of {1}.", prediction.Name, prediction.Score); if (prediction.Name.StartsWith("checkmark")) { _imageView.SetImageResource(Resource.Drawable.checked_me); } else if (prediction.Name.StartsWith("erase", StringComparison.OrdinalIgnoreCase)) { // Match one of our "erase" gestures _imageView.SetImageResource(Resource.Drawable.check_me); } }Execute o aplicativo e inicie a atividade Custom Gesture Recognizer. Ele deve se parecer com a seguinte captura de tela:
Agora desenhe uma marca de seleção na tela, e o bitmap que está sendo exibido deve ser semelhante ao mostrado nas próximas capturas de tela:
Por fim, desenhe um rabisco na tela. A caixa de seleção deve voltar para sua imagem original, conforme mostrado nestas capturas de tela:
Agora você tem uma compreensão de como integrar toque e gestos em um aplicativo Android usando Xamarin.Android.







