Переопределение Android onClick (View v) - есть ли хорошее решение для использования всех кнопок в приложении

Как вы знаете, мы можем переопределить несколько методов для каждого типа созданного нами представления. Я не делаю никакого кода макета xml, потому что многие вещи меняются во время выполнения, и есть вещи, которые создаются динамически, поэтому программное решение — лучший способ для меня здесь.

Итак, чтобы понять суть моей проблемы, скажем, что у меня есть 50 кнопок в моем приложении для Android. Эти кнопки потенциально могут быть в одном действии, но, скорее всего, могут располагаться на нескольких экранах (действиях).

Я создал класс кнопок CustomButton, который переопределяет метод onClick(View view). Что, если некоторые из кнопок должны выполнять какое-то действие (скажем, они являются частью линейного макета), а некоторые являются частью чего-то вроде относительного макета, и в каждом относительном макете вы хотите получить информацию об относительном макете, который эта кнопка находится в (возможно, вам нужно получить информацию обо всех текстовых представлениях в одном и том же относительном макете и т. д. и т. д.).

Одним из решений, конечно, является то, что вы можете получить идентификатор каждой кнопки и выполнить переключатель (случай) или что-то еще, и в зависимости от того, какой идентификатор возвращаемой кнопки вы можете что-то сделать. Проблема в том, что у меня 50 кнопок. А если бы у меня было 200? Должен ли я действительно делать 200 проверок регистра в своем операторе switch, чтобы выяснить, какие действия мне нужно предпринять?

Итак, я пытаюсь выяснить, какая информация доступна мне, о которой я не знаю, которую я мог бы использовать при переопределении onClick.

   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    if(!getClickInfo()){
        ((CustomButton)v).setText("I clicked the button");
        setClickInfo(true);
    }
    else{
        isClicked = false;
        ((CustomButton)v).setText("This is the button that i want to click");


    }

}

так вот пример. Я прошел в представлении, которое представляет нажатую кнопку, и я могу изменить текст кнопки, когда я нажимаю на нее снова и снова. Но что, если бы кнопка была частью относительного макета? Могу ли я получить любую другую информацию о других представлениях, которые также являются частью того же относительного макета? Что если для некоторых кнопок я хочу менять цвет фона каждый раз, когда я нажимаю на них, вместо того, чтобы менять текст? Если у меня есть X кнопок, я стараюсь не создавать X идентификаторов — как я уже говорил, у вас потенциально могут быть сотни из них.

Было интересно, есть ли у кого-нибудь какие-либо идеи о том, что было бы лучшим маршрутом здесь, чем наличие потенциально неограниченного количества проверок регистра внутри оператора switch. Если бы я мог узнать, из какого представления появилась кнопка (в моем случае кнопка была частью внешнего представления), тогда я мог бы переключать свои представления, а не только мои кнопки, и сделать мой оператор переключения намного менее громоздким и простым в использовании. поддерживать. Спасибо.


person cspam    schedule 09.03.2012    source источник
comment
Вы можете точно сказать, что вы хотите сделать, в нескольких предложениях? ваше объяснение не ясно!   -  person Keyhan Asghari    schedule 10.03.2012
comment
Я не знаю, понимаю ли я, что вы пытаетесь сделать (особенно дополнительную информацию, которую вы пытаетесь собрать), но вы можете установить атрибут tag на свой Button (в макете xml), представляющий String, и на основе этого String получить больше информации о контексте Button.   -  person user    schedule 10.03.2012
comment
пожалуйста, посмотрите ниже ответ на YuviDroid. извините за первоначальную путаницу.   -  person cspam    schedule 10.03.2012


Ответы (2)


Я не уверен, какова ваша конечная цель. Но с вашего представления (кнопки) вы можете получить его родителя (например, RelativeLayout). Затем, когда у вас есть группа просмотра, вы можете получить ее дочерние элементы и делать все, что вам нужно.

Например:

@Override
public void onClick(View v) {
    ViewParent parent = v.getParent();
    if (parent instanceof RelativeLayout) {
        // your button is inside a RelativeLayout
        RelativeLayout rl = (RelativeLayout) parent;
        int numChildren = rl.getChildCount();
        // loop through children if you need to (use rl.getChildAt(index) to get each child)
        ...
    }
}

Если вам не нужно знать, действительно ли это RelativeLayout или LinearLayout или что-то еще, просто используйте ViewGroup.

Надеюсь, поможет.

person YuviDroid    schedule 09.03.2012
comment
Да, я понял, может быть, я был не так ясен, как хотел бы быть. Очевидно, это так, поскольку я получил несколько ответов, задаваясь вопросом, о чем я говорю. В моем случае у меня линейная компоновка относительных компоновок. В каждом относительном макете у меня есть кнопка и некоторые другие представления (текстовые представления). когда я нажимаю на любую из этих кнопок, я хочу иметь возможность получить значение текста одного из текстовых представлений, которые находятся в том же относительном макете. в зависимости от того, в каком относительном макете находится эта кнопка, значение вызова getText будет другим. - person cspam; 10.03.2012
comment
.. Продолжение - если я смогу сделать, как вы предлагаете выше, мне не придется назначать идентификаторы кнопок для каждой кнопки, от чего я хотел держаться подальше. В случае с относительными макетами, как вы предложили выше, я думаю, что само по себе это сработает хорошо. Что, если бы у меня было 5 линейных макетов, и в каждом линейном макете у меня было бы 5 кнопок. Если я проверю, является ли кнопка экземпляром линейного макета, в этом случае информации будет недостаточно, потому что каждый набор кнопок в каждом линейном макете будет иметь разные отправленные действия, которые я хочу осуществлять. - person cspam; 10.03.2012
comment
-- Снова продолжил. Я потенциально мог бы получить имя linearlayout, чтобы сообщить мне, какие действия я могу предпринять, но если у меня есть что-то вроде ArrayList‹LinearLayout› myLinearLayouts = new ArraysList‹LinearLayout›(некоторое число) - тогда мне придется либо проверить массив index и жестко запрограммировать проверку для этого в операторе switch. Во всяком случае, просто пытаюсь найти самый элегантный объектно-ориентированный подход, насколько это возможно. спасибо за ваш вклад Юви. - person cspam; 10.03.2012

Если я правильно вас понимаю, у вас может быть просто несколько разных расширений CustomButton: скажем, RelativeLayoutButton и LinearLayoutButton, и они реализуют OnClickListener. Переопределите onClick() в расширенном классе и обработайте реализацию для каждого типа кнопки.

При необходимости вы можете получить доступ ко всей иерархии представлений. Скажем, что-то вроде этого:

//assuming a reference to Button button

//get a reference to the parent
View v = button.getParent();
ViewGroup parent;
ArrayList<View> siblings = new ArrayList<>();

if(v instanceof ViewGroup) parent = (ViewGroup) v;
for(int i = 0; i < parent.getChildCount(); i++) {
    siblings.add(parent.getChildAt(i));
}
person Kevin Coppock    schedule 09.03.2012
comment
Думаю, вы с Юви придумали, что я хочу сделать. пожалуйста, обратитесь к моим ответам выше. Как только я узнаю, с каким экземпляром я работаю (instanceof RelativeLayout, LinearLayout и т. д.), было бы неплохо выяснить имя переменной макетов, которое я изначально назначил для каждого из них при их создании. myLinearLayoutCars, myLinearLayoutAnimals, myRelativeLayoutA, myRelativeLayoutB и, возможно, использовать оператор switch для проверки различных типов линейных или относительных макетов, которые у меня есть. Причина этого в том, как я так некрасноречиво пытался объяснить ранее... - person cspam; 10.03.2012
comment
заключается в том, что разные linearLayouts или relativeLayouts будут иметь разные типы представлений (дочерние элементы) внутри них и разное количество. Таким образом, в зависимости от того, какой тип макета у меня есть (проверьте по имени переменной макета?), Будет зависеть от того, какой тип представления я хочу извлечь. В случае RelativeLayoutA этот конкретный тип имеет представление изображения, 2 текстовых представления и рассматриваемую кнопку, которую я, конечно, нажимаю. Если я знаю, что я щелкнул родительским элементом RelativeLayoutA, то каким-то образом я хотел бы извлечь определенный текстовый вид (также по имени?). В любом случае, я надеюсь, что это не было слишком запутанным... - person cspam; 10.03.2012