Страницы

Поиск по вопросам

Показаны сообщения с ярлыком android-on-click. Показать все сообщения
Показаны сообщения с ярлыком android-on-click. Показать все сообщения

вторник, 17 марта 2020 г.

Android: Как на кнопке одновременно задействовать два сушателя

#java #android #android_on_click #ontouchlistener


Возникла следующая проблема:

Имеется кнопка у которой необходимо обрабатывать два слушателя. Первый это onTouchListener,
второй onClickListener. Код слушателя onTouchListener() ниже:

OnTouchListener dragt = new OnTouchListener()
     {
        @Override
        public boolean onTouch(View v, MotionEvent event) 
        {
            FrameLayout.LayoutParams par = (LayoutParams) v.getLayoutParams();
            switch(v.getId())
            {
                case R.id.button1:

                {
                    switch(event.getAction())
                    {
                        case MotionEvent.ACTION_MOVE:
                        {
                            par.topMargin = (int)event.getRawY() - (v.getHeight());
                            par.leftMargin = (int)event.getRawX() - (v.getWidth()/2);
                            par.bottomMargin = (int)event.getRawX() - (v.getWidth()/2);
                            par.rightMargin = (int)event.getRawX() - (v.getWidth()/2);
                            v.setLayoutParams(par);
                            break;
                        }
                        case MotionEvent.ACTION_UP:
                        {
                            par.height = 120;
                            par.width = 120;
                            par.topMargin = (int)event.getRawY() - (v.getHeight());
                            par.leftMargin = (int)event.getRawX() - (v.getWidth()/2);
                            par.bottomMargin = (int)event.getRawX() - (v.getWidth()/2);
                            par.rightMargin = (int)event.getRawX() - (v.getWidth()/2);
                            v.setLayoutParams(par);
                            break;
                        }
                        case MotionEvent.ACTION_DOWN:
                        {
                            par.height = 150;
                            par.width = 150;
                            v.setLayoutParams(par);
                            break;
                        }
                    }
                    break;
                }
            }
            return true;
        }
     };


Мне же необходимо чтобы при обычном клике срабатывал onClick(). Назначал слушателя
onClickListener - не работает(то есть онтач срабатывает, а онклик нет), назначал кнопке
свойство 
    android:onClick="knopka"

Далее вызывал в активити:

public void knopka(View v) {
       System.out.println("Работай же!!!");
    }


Все равно не работает. Как еще сделать не представляю!
    


Ответы

Ответ 1



Как обычно, читаем документацию: Returns True if the listener has consumed the event, false otherwise. Таким образом, как нетрудно догадаться, вам нужно возвращать из OnTouchListener.onTouch false, а не true.

пятница, 31 января 2020 г.

Назначение OnClickListener

#java #android #button #android_on_click #android_button


Доброго времени суток. 

Есть MainActivity реализующая интерфейс View.OnClickListener, соответственно есть
метод OnClick типа такого:

public void onClick(View v) {
    if (v.getId()==R.id.btnDel){   //Кнопка Удалить
        Button btnDel = (Button) v;
        btnDel.setText("Отмена");
        btnDel.setOnClickListener(oclBtnDelWhileDel);


Выше по коду я создаю oclBtnDelWhileDel таким:

View.OnClickListener oclBtnDelWhileDel = new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        Button btnDel = (Button) v;
        btnDel.setText("Удалить");
        btnDel.setOnClickListener(this);
    }
} ;


Идея в том что метод OnClick класса назначает кнопке слушателя oclBtnDelWhileDel,
а oclBtnDelWhileDel назначает слушателем обратно метод OnClick.

Проблема в том, что при первом нажатии на кнопку, она меняет название на "Отмена"
и назначается слушатель oclBtnDelWhileDel. 

А вот при втором нажатии на кнопку название меняется на "Удалить", а вот слушатель
обратно не меняется. 

Через дебаггер выполняется опять код oclBtnDelWhileDel. 

Вопрос: не могу понять, почему?.
    


Ответы

Ответ 1



OnClickListener "прикрепляется" к определенной кнопке, и реализует метод обратного вызова (Callback), проще говоря, когда вы нажимаете на кнопку - происходит некоторое действие. Конкретно в вашей реализации очень много некрасивых мест, начиная с объявления кнопки при нажатии на другую кнопку - заканчивая установлением слушателя кнопки внутри реализации onClick другой кнопки. Вы можете просто менять динамически текст на кнопке, и выполнять тот, или иной функционал, допустим: if(btn.getText().equals("Удалить")){ // происходит операция удаления } else { //операция отмены. } Написано на коленке, и вероятно, ответ выше помог более по теме, но и этим не пренебрегайте. Зарефакторите код, станет легче.

Ответ 2



View.OnClickListener oclBtnDelWhileDel = new View.OnClickListener() { @Override public void onClick(View v) { Button btnDel = (Button) v; btnDel.setText("Удалить"); btnDel.setOnClickListener(this); //Вот тут ошибка } } ; В данном случае this указывает не на внешний класс, а на View.OnClickListener, таким образом вы устаналиваете слушателем его же самого

вторник, 31 декабря 2019 г.

Разные действия Click, LongClick и Touch на одно и то же место

#java #android #android_on_click #ontouchlistener


Есть определенные сомнения, но все таки вдруг такое поведение возможно.
Суть: у меня есть FrameLayout (отсюда) с событием onTouch для зуминга. В этом Frame
есть несколько элементов, которые принимают события onClick и onLongClick:

for (int i = 0; i < locations.size(); i++) {
        locations.get(i).getView().setOnClickListener(onPoleClick);
        locations.get(i).getView().setOnLongClickListener(onPoleLongClick);
}


если я выставляю слушателя на клик - перестает действовать MyFrame.onTouch и поле
не зумится. Если убираю - соответственно, сижу без кликов, но с зумящимся полем. Если
ставлю return false; в MyFrame.onTouch, он также перестает работать.
Пробовал заменить locations.get(i).onClick на onTouch (MotionEvent.UP) - при return
true клик до Frame не доходит, при return false MotionEvent.UP не срабатывает. MotionEvent.DOWN
не даст обработать onLongClick...

Дудочка и кувшинчик, в общем. Может быть есть какой-то способ, чтобы onTouch срабатывал
"сквозь" клики?
    


Ответы

Ответ 1



Можно попробовать вот так: public class ZoomFrameLayout extends FrameLayout { public ZoomFrameLayout(Context context) { super(context); } public ZoomFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); } public ZoomFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean upper = super.onInterceptTouchEvent(ev); if (!upper) { // Детектим жесты здесь стандартным детектором // и если зум - отрабатываем и выставляем return true } return upper; } } Т.е. вид ZoomFrameLayout будет забирать себе только зум, а клики уйдут детишкам. И кстати при таком использовании ScaleDetector будут все события перехватываться (там return true в конце). Можно попробовать что-нибуть вроде if (scaleDetector.isInProgress()) return true;

Ответ 2



Просто совместите оба действия в onTouch: private int min=50; private int x, dx; public boolean onTouch(View v, MotionEvent event) { if(event.getAction()==MotionEvent.ACTION_DOWN) { x = event.getX(); } else if(event.getAction()==MotionEvent.ACTION_UP) { dx = event.getX(); if (Math.abs( dx - x ) > min) { // зум } else { // клик } } }

воскресенье, 7 июля 2019 г.

Проблема со считываением клика Android

Здравствуйте. Наткнулся на такую проблему: имею 3 кнопки(ImageButton), необходимо после 1-ого нажатия на одну из кнопок,отследить послеующее нажатие(OnClick) на следующую кнопку(допустим-2).3-я не подойдет. Как отследить первый клик,я понимаю.Но как отследить вторую в нужную позицию,нет P.S. Создаю шахматы,пытаюсь реализовать перемещение фигуры посредством изменения ImageButton по клику


Ответ

@Андр спросил, как программно реализовать перемещение фигур? Я решил написать алгоритм. Начнем!
При нажатии на клетку обращаемся к массиву поля и определяем, какая фигура там стоит. Записываем значение в int1 (пешка - 1, конь - 2, ...) и позицию фигуры в int2 и int3 (лучше в формате двух цифр - к примеру 4 и 2). Если нажатая клетка пуста, ничего не делаем, в противном случае ждем нажатия другой клетки - клетки хода. При нажатии на клетку хода строим switch - смотрим, может ли туда ходить фигура. Тут и пригодится созданный int. Если все правильно, то проводим вторую проверку - занята ли та клетка? Делаем это через массив. Принимаем окончательное решение и производим (или не производим) перемещение фигуры. Изменяем массив фигур. Стоит учесть, чей ход!!!
Стоит заметить - изначально массив создается по правилам шахмат - происходит расстановка фигур. Приведем пример выполнения алгоритма в начале игры.
Пользователь нажал на пешку с позицией D2. Записываем в int1 значение 1, в int2 значение 4, в int3 значение 2 Пропускаем. Проверяем в switch(int1) значение. Так как оно равно 1, то смотрим возможные ходы для пешки. Она удовлетворяет требованиям. Происходит ход и запись новой позиции фигуры в массив.

Как в GridView при длинном тапе на элементе - плавно изменить размеры всех дочерних элементов

Есть GridView. Хочу сделать так, чтобы при длинном клике, элементы уменьшались в размере все одновременно, по-типу анимации.
Например, как в галерее фотографий. Когда при длинном клике происходит переход в режим мультивыбора.
Вот пример чего хочу добиться:

Пробовал делать анимацию на элемент - но срабатывает только на первом элементе, несмотря на то, на какой элемент нажимаю.
Сам GridView через Adapter и Holder наполняется элементами:



На элементах прикручены слушатели:
ticketsGrid.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override public boolean onItemLongClick(AdapterView parentLong, View viewLong, int positionLong, long idLong) { return true; } });
и:
ticketsGrid.setOnItemClickListener(new OnItemClickListener() {
@Override public void onItemClick(AdapterView parentShort, View viewShort, final int positionShort, long idShort) {
return true; } });
Может есть готовые библиотеки или кто-то уже делал такое?


Ответ

Делал для GridLayout через анимацию веса и такой класс:
public class WeightAnimation implements Animator.AnimatorListener { public static final int DURATION = 500; private ValueAnimator va;
WeightAnimation(float from, float to, final View view) { va = ValueAnimator.ofFloat(from, to); //fromWeight, toWeight va.setDuration(DURATION); va.setInterpolator(new LinearInterpolator()); va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { @Override public void onAnimationUpdate(ValueAnimator animation) { ((LinearLayout.LayoutParams) view.getLayoutParams()).weight = (float) animation.getAnimatedValue(); view.requestLayout(); } }); va.addListener(this); }
public void startAnimation() { va.start(); }
@Override public void onAnimationStart(Animator animation) {
}
@Override public void onAnimationEnd(Animator animation) { //код по окончанию анимации }
@Override public void onAnimationCancel(Animator animation) {
}
@Override public void onAnimationRepeat(Animator animation) {
} }
Использование, где нужно:
void collapseAnimation(final View view, final boolean isCollapsing) { WeightAnimation wa = new WeightAnimation(isCollapsing ? 1f : 0f, isCollapsing ? 0f : 1f, view); wa.startAnimation(); }
Передаете все ваши View, для нужного isCollapsing=false, для остальных = true
По прежнему остается вопрос быстродействия, особенно, если у вас много View. Но на небольшое их количество работает стабильно.
Если отслеживать анимацию не нужно - implements и animationListener'ы можно удалить.

четверг, 6 июня 2019 г.

Android: Как на кнопке одновременно задействовать два сушателя

Возникла следующая проблема:
Имеется кнопка у которой необходимо обрабатывать два слушателя. Первый это onTouchListener, второй onClickListener. Код слушателя onTouchListener() ниже:
OnTouchListener dragt = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { FrameLayout.LayoutParams par = (LayoutParams) v.getLayoutParams(); switch(v.getId()) { case R.id.button1:
{ switch(event.getAction()) { case MotionEvent.ACTION_MOVE: { par.topMargin = (int)event.getRawY() - (v.getHeight()); par.leftMargin = (int)event.getRawX() - (v.getWidth()/2); par.bottomMargin = (int)event.getRawX() - (v.getWidth()/2); par.rightMargin = (int)event.getRawX() - (v.getWidth()/2); v.setLayoutParams(par); break; } case MotionEvent.ACTION_UP: { par.height = 120; par.width = 120; par.topMargin = (int)event.getRawY() - (v.getHeight()); par.leftMargin = (int)event.getRawX() - (v.getWidth()/2); par.bottomMargin = (int)event.getRawX() - (v.getWidth()/2); par.rightMargin = (int)event.getRawX() - (v.getWidth()/2); v.setLayoutParams(par); break; } case MotionEvent.ACTION_DOWN: { par.height = 150; par.width = 150; v.setLayoutParams(par); break; } } break; } } return true; } };
Мне же необходимо чтобы при обычном клике срабатывал onClick(). Назначал слушателя onClickListener - не работает(то есть онтач срабатывает, а онклик нет), назначал кнопке свойство android:onClick="knopka"
Далее вызывал в активити:
public void knopka(View v) { System.out.println("Работай же!!!"); }
Все равно не работает. Как еще сделать не представляю!


Ответ

Как обычно, читаем документацию Returns True if the listener has consumed the event, false otherwise. Таким образом, как нетрудно догадаться, вам нужно возвращать из OnTouchListener.onTouch false, а не true

вторник, 2 апреля 2019 г.

Назначение OnClickListener

Доброго времени суток.
Есть MainActivity реализующая интерфейс View.OnClickListener, соответственно есть метод OnClick типа такого:
public void onClick(View v) { if (v.getId()==R.id.btnDel){ //Кнопка Удалить Button btnDel = (Button) v; btnDel.setText("Отмена"); btnDel.setOnClickListener(oclBtnDelWhileDel);
Выше по коду я создаю oclBtnDelWhileDel таким:
View.OnClickListener oclBtnDelWhileDel = new View.OnClickListener() { @Override public void onClick(View v) { Button btnDel = (Button) v; btnDel.setText("Удалить"); btnDel.setOnClickListener(this); } } ;
Идея в том что метод OnClick класса назначает кнопке слушателя oclBtnDelWhileDel, а oclBtnDelWhileDel назначает слушателем обратно метод OnClick
Проблема в том, что при первом нажатии на кнопку, она меняет название на "Отмена" и назначается слушатель oclBtnDelWhileDel.
А вот при втором нажатии на кнопку название меняется на "Удалить", а вот слушатель обратно не меняется.
Через дебаггер выполняется опять код oclBtnDelWhileDel.
Вопрос: не могу понять, почему?.


Ответ

OnClickListener "прикрепляется" к определенной кнопке, и реализует метод обратного вызова (Callback), проще говоря, когда вы нажимаете на кнопку - происходит некоторое действие.
Конкретно в вашей реализации очень много некрасивых мест, начиная с объявления кнопки при нажатии на другую кнопку - заканчивая установлением слушателя кнопки внутри реализации onClick другой кнопки.
Вы можете просто менять динамически текст на кнопке, и выполнять тот, или иной функционал, допустим:
if(btn.getText().equals("Удалить")){
// происходит операция удаления } else {
//операция отмены.
}
Написано на коленке, и вероятно, ответ выше помог более по теме, но и этим не пренебрегайте.
Зарефакторите код, станет легче.

вторник, 25 декабря 2018 г.

Разные действия Click, LongClick и Touch на одно и то же место

Есть определенные сомнения, но все таки вдруг такое поведение возможно. Суть: у меня есть FrameLayout (отсюда) с событием onTouch для зуминга. В этом Frame есть несколько элементов, которые принимают события onClick и onLongClick:
for (int i = 0; i < locations.size(); i++) { locations.get(i).getView().setOnClickListener(onPoleClick); locations.get(i).getView().setOnLongClickListener(onPoleLongClick); }
если я выставляю слушателя на клик - перестает действовать MyFrame.onTouch и поле не зумится. Если убираю - соответственно, сижу без кликов, но с зумящимся полем. Если ставлю return false; в MyFrame.onTouch, он также перестает работать. Пробовал заменить locations.get(i).onClick на onTouch (MotionEvent.UP) - при return true клик до Frame не доходит, при return false MotionEvent.UP не срабатывает. MotionEvent.DOWN не даст обработать onLongClick...
Дудочка и кувшинчик, в общем. Может быть есть какой-то способ, чтобы onTouch срабатывал "сквозь" клики?


Ответ

Можно попробовать вот так:
public class ZoomFrameLayout extends FrameLayout { public ZoomFrameLayout(Context context) { super(context); }
public ZoomFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); }
public ZoomFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); }
@Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean upper = super.onInterceptTouchEvent(ev); if (!upper) { // Детектим жесты здесь стандартным детектором // и если зум - отрабатываем и выставляем return true } return upper; } }
Т.е. вид ZoomFrameLayout будет забирать себе только зум, а клики уйдут детишкам.
И кстати при таком использовании ScaleDetector будут все события перехватываться (там return true в конце). Можно попробовать что-нибуть вроде if (scaleDetector.isInProgress()) return true;