Touch listeners in android

Полный список

Раньше мы для View-компонентов использовали OnClickListener и ловили короткие нажатия. Теперь попробуем ловить касания и перемещения пальца по компоненту. Они состоят из трех типов событий:

— нажатие (палец прикоснулся к экрану)
— движение (палец движется по экрану)
— отпускание (палец оторвался от экрана)

Все эти события мы сможем ловить в обработчике OnTouchListener, который присвоим для View-компонента. Этот обработчик дает нам объект MotionEvent, из которого мы извлекаем тип события и координаты.

На этом уроке рассмотрим только одиночные касания. А мультитач – на следующем уроке.

Project name: P1021_Touch
Build Target: Android 2.3.3
Application name: Touch
Package name: ru.startandroid.develop.p1021touch
Create Activity: MainActivity

strings.xml и main.xml нам не понадобятся, их не трогаем.

MainActivity реализует интерфейс OnTouchListener для того, чтобы выступить обработчиком касаний.

В onCreate мы создаем новый TextView, сообщаем ему, что обработчиком касаний будет Activity, и помещаем на экран.

Интерфейс OnTouchListener предполагает, что Activity реализует его метод onTouch. На вход методу идет View для которого было событие касания и объект MotionEvent с информацией о событии.

Методы getX и getY дают нам X и Y координаты касания. Метод getAction дает тип события касания:

ACTION_DOWN – нажатие
ACTION_MOVE – движение
ACTION_UP – отпускание
ACTION_CANCEL – практически никогда не случается. Насколько я понял, возникает в случае каких-либо внутренних сбоев, и следует трактовать это как ACTION_UP.

В случае ACTION_DOWN мы пишем в sDown координаты нажатия.

В случае ACTION_MOVE пишем в sMove координаты точки текущего положения пальца. Если мы будем перемещать палец по экрану – этот текст будет постоянно меняться.

В случае ACTION_UP или ACTION_CANCEL пишем в sUp координаты точки, в которой отпустили палец.

Все это в конце события выводим в TextView. И возвращаем true – мы сами обработали событие.

Теперь мы будем водить пальцем по экрану (курсором по эмулятору) в приложении, и на экране увидим координаты начала движения, текущие координаты и координаты окончания движения.

Все сохраним и запустим приложение.

Ставим палец (курсор) на экран

Если вчерашний вечер не удался, голова не болит, рука тверда и не дрожит :), то появились координаты нажатия.

Если же рука дрогнула, то появится еще и координаты перемещения.

Продолжаем перемещать палец и видим, как меняются координаты Move.

Теперь отрываем палец от экрана и видим координаты точки, в которой это произошло

В целом все несложно. При мультитаче процесс немного усложнится, там уже будем отслеживать до 10 касаний.

Если вы уже знакомы с техникой рисования в Android, то вполне можете создать приложение выводящее на экран геометрическую фигуру, которую можно пальцем перемещать. Простейший пример реализации можно посмотреть тут: http://forum.startandroid.ru/viewtopic.php?f=28&t=535.

На следующем уроке:

— обрабатываем множественные касания

Присоединяйтесь к нам в Telegram:

— в канале StartAndroid публикуются ссылки на новые статьи с сайта startandroid.ru и интересные материалы с хабра, medium.com и т.п.

— в чатах решаем возникающие вопросы и проблемы по различным темам: Android, Kotlin, RxJava, Dagger, Тестирование

— ну и если просто хочется поговорить с коллегами по разработке, то есть чат Флудильня

— новый чат Performance для обсуждения проблем производительности и для ваших пожеланий по содержанию курса по этой теме

Источник

Basic Event Listeners

Event Listening in Android development is largely centered around the View object.

Any View (Button, TextView, etc) has many event listeners that can be attached using the setOnEvent pattern which involves passing a class that implements a particular event interface. The listeners available to any View include:

  • setOnClickListener — Callback when the view is clicked
  • setOnDragListener — Callback when the view is dragged
  • setOnFocusChangeListener — Callback when the view changes focus
  • setOnGenericMotionListener — Callback for arbitrary gestures
  • setOnHoverListener — Callback for hovering over the view
  • setOnKeyListener — Callback for pressing a hardware key when view has focus
  • setOnLongClickListener — Callback for pressing and holding a view
  • setOnTouchListener — Callback for touching down or up on a view
Читайте также:  Антивирус с блокировкой рекламы для андроид

Using Java

In Java Code, attaching to any event works roughly the same way. Let’s take the OnClickListener as an example. First, you need a reference to the view and then you need to use the set method associated with that listener and pass in a class implementing a particular interface. For example:

Alternatively, it is sometimes useful to have your class implement the listener directly, in which case you would add the listener implementation to your class and pass a reference to your class to the set method. For Example:

This pattern works for any of the view-based event listeners.

Using XML

In addition onClick has a unique shortcut that allows the method to specified within the layout XML. So rather than attaching the event manually in the Java, the method can be attached in the view. For example:

Within the Activity that hosts this layout, the following method handles the click event:

In addition to the standard View listeners, AdapterView descendants have a few more key event listeners having to do with their items:

  • setOnItemClickListener — Callback when an item contained is clicked
  • setOnItemLongClickListener — Callback when an item contained is clicked and held
  • setOnItemSelectedListener — Callback when an item is selected

This works similarly to a standard listener, simply implementing the correct AdapterView.OnItemClickListener interface:

This works similarly for the setting up a «long click» where an item is pressed and held down using the OnItemLongClickListener:

Troubleshooting: Item Click Not Firing If the item is more complex and does not seem to be properly responding to clicks after setting up the handler, the views inside the item might be drawing the focus. Check out this stackoverflow post and add the property android:descendantFocusability=»blocksDescendants» to the root layout within the template for the item.

In addition to the listeners described above, there are a few other common listeners for input fields in particular.

  • addTextChangedListener — Fires each time the text in the field is being changed
  • setOnEditorActionListener — Fires when an «action» button on the soft keyboard is pressed

If you want to handle an event as the text in the view is being changed, you only need to look as far as the addTextChangedListener method on an EditText (or even TextView):

This is great for any time you want to have the UI update as the user enters text.

Another case is when you want an action to occur once the user has finished typing text with the Soft Keyboard. Keep in mind that this is especially useful when you can see the virtual keyboard which is disabled by default in the emulator but can be enabled as explained in this graphic.

First, we need to setup an «action» button for our text field. To setup an «action button» such as a Done button on the soft Keyboard, simply configure your EditText with the following properties:

Читайте также:  Клавиатурный шпион для андроид 4pda

In particular, singleLine and imeOptions are required for the Done button to display. Now, we can hook into a editor listener for when the done button is pressed with:

This is often great whenever a user needs to type text and then explicitly have an action performed when they are finished. There are many imeOptions for different situations.

Similarly to EditText, many common input views have listeners of their own including NumberPicker has setOnValueChangedListener and SeekBar has setOnSeekBarChangeListener which allow us to listen for changes:

Almost all input views have similar methods available.

Источник

Creating Custom Listeners

The «listener» or «observer» pattern is the most common tegy for creating asynchronous callbacks within Android development. Listeners are used for any type of asynchronous event in order to implement the code to run when an event occurs. We see this pattern with any type of I/O as well as for view events on screen. For example, here’s a common usage of the listener pattern to attach a click event to a button:

This listener is built-in but we can also create our own listeners and attach callbacks to the events they fire from other areas in our code. This is useful in a variety of cases including:

  • Firing events from list items upwards to an activity from within an adapter
  • Firing events from a fragment upwards to an activity.
  • Firing async events from an abstraction (i.e networking library) to a parent handler.

In short, a listener is useful anytime a child object wants to emit events upwards to notify a parent object and allow that object to respond.

Listeners are a powerful mechanism for properly separating concerns in your code. One of the essential principles around writing maintainable code is to reduce coupling and complexity using proper encapsulation. Listeners are about ensuring that code is properly organized into the correct places. In particular, this table below offers guidelines about where different types of code should be called:

Type Called By Description
Intents Activity Intents should be created and executed within activities.
Networking Activity , Fragment Networking code should invoked in an activity or fragment.
FragmentManager Activity Fragment changes should be invoked by an activity.
Persistence Activity , Fragment Writing to disk should be invoked by activity or fragment.

While there are exceptions, generally speaking this table helps to provide guidelines as to when you need a listener to propagate an event to the appropriate owner. For example, if you are inside an adapter and you want to launch a new activity, this is best done by firing an event using a custom listener triggering the parent activity.

There are four steps to using a custom listener to manage callbacks in your code:

Define an interface as an event contract with methods that define events and arguments which are relevant event data.

Setup a listener member variable and setter in the child object which can be assigned an implementation of the interface.

Owner passes in a listener which implements the interface and handles the events from the child object.

Trigger events on the defined listener when the object wants to communicate events to it’s owner

The sample code below will demonstrate this process step-by-step.

First, we define an interface in the child object. This object can be a plain java object, an Adapter , a Fragment , or any object created by a «parent» object such as an activity which will handle the events that are triggered.

This involves creating an interface class and defining the events that will be fired up to the parent. We need to design the events as well as the data passed when the event is triggered.

With the interface defined, we need to setup a listener variable to store a particular implementation of the callbacks which will be defined by the owner.

In the child object, we need to define an instance variable for an implementation of the listener:

as well as a «setter» which allows the listener callbacks to be defined in the parent object:

This allows the parent object to pass in an implementation of the listener after this child object is created similar to how the button accepts the click listener.

Now that we have created the setters, the parent object can construct and set callbacks for the child object:

Here we’ve created the child object and passed in the callback implementation for the listener. These events can now be fired by the child object to pass the event to the parent as appropriate.

Now the child object should trigger events to the listener whenever appropriate and pass along the data to the parent object through the event. These events can be triggered when a user action is taken or when an asynchronous task such as networking or persistence is completed. For example, we will trigger the onDataLoaded(SomeData data) event once this network request comes back on the child:

Notice that we fire the listener event listener.onDataLoaded(data) when the asynchronous network request has completed. Whichever callback has been passed by the parent (shown in the previous step) will be fired.

The «listener pattern» is a very powerful Java pattern that can be used to emit events to a single parent in order to communicate important information asynchronously. This can be used to move complex logic out of adapters, create useful abstractions for your code or communicate from a fragment to your activities.

There are several different ways to pass a listener callback into the child object:

  1. Pass the callback through a method call
  2. Pass the callback through the constructor
  3. Pass the callback through a lifecycle event

The code earlier demonstrated passing the callback through a method call like this:

which is defined in the child object as follows:

If the callback is critical to the object’s function, we can pass the callback directly into the constructor of the child object as an argument:

and then when we can create the child object from the parent we can do the following:

The third case is most common with fragments or other android components that need to communicate upward to a parent. In this case, we can leverage existing Android lifecycle events to get access to the listener. In the case below, a fragment being attached to an activity:

For the full details on this approach, check out the fragments guide.

Источник

Читайте также:  Самый хороший переводчик для андроида
Оцените статью