Подтвердить что ты не робот

Как я могу запустить Onclick событие программно в android?

У меня есть пользовательский вид с двумя макетами lineat: первый - это заголовок представления, а второй - просмотр деталей.

В пользовательском представлении уже определено OnClickListener заголовка Linringayout: когда он срабатывает, он сворачивает/расширяет второй linearlayout.

Что я хочу сделать, так это добавить дополнительные функции в заголовок OnClickListener (например: свернуть/развернуть второй макет и показать Toast).

Я не могу изменить исходный код пользовательского представления. Я попытался установить новый OnClickListener, но он скрывает начальное событие (свернуть/развернуть).

Как это реализовать?

Исходный код My Custom View:

public class ExpandoLayout extends ViewGroup
{
    /* some declarations */
    private Linearlayout header;
    private linearlayout footer;

    /* some code */
    @override
    protected void onFinishInflate() {
    header= new LinearLayout(context);
    header.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                toggleExpand();
            }
        });
    }
}

то, что я хочу сделать, - добавить код в уже определенное событие OnClickListener в мою активность. Что-то вроде этого:

public class myActivity extends Activity {
private Linearlayout myCustomView;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.rsdetail);
    myCustomView= (MyCustomView) findViewById(R.id.expanded);

    myCustomView.getChildAt(0).setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View v) {
            if(v instanceof LinearLayout)
            {
                v.performClick();

                Toast.makeText(getActivity(), "ExpandoOnClickListener", 2000).show();
            }
        }
    });
}
4b9b3361

Ответ 1

Простым решением было бы получить оригинальный OnClickListener, а затем запустить его в новом:

final OnClickListener preDefinedListener = myCustomView.getChildAt(0).getOnClickListner();

myCustomView.getChildAt(0).setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        if(v instanceof LinearLayout)
        {
            preDefinedListener.onClick(v); // calls default (defined by MyCustomView)

            Toast.makeText(getActivity(), "ExpandoOnClickListener", 2000).show();
        }
    }
});

К сожалению, View не имеет getOnClickListner(), но я думаю, вы можете использовать reflection, чтобы получить его. Он хранится в field mOnClickListener (source).

Вот как вы можете получить OnClickListener для вашего макета:

OnClickListener tmpOnClickListener = null;
try {
    Class<View> cls = (Class<View>) Class.forName("android.view.View");
    Field fld = cls.getDeclaredField("mOnClickListener");
    fld.setAccessible(true); // because it is protected

    tmpOnClickListener = (OnClickListener) fld.get(myCustomView.getChildAt(0));

    fld.setAccessible(false); // restore it original property
} catch (SecurityException e) {
    e.printStackTrace();
} catch (NoSuchFieldException e) {
    e.printStackTrace();
} catch (IllegalArgumentException e) {
    e.printStackTrace();
} catch (IllegalAccessException e) {
    e.printStackTrace();
} catch (ClassNotFoundException e) {
    e.printStackTrace();
} 

final OnClickListener preDefinedListener = tmpOnClickListener;

if (preDefinedListener != null) {
    myCustomView.getChildAt(0).setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View paramView) {
            preDefinedListener.onClick(paramView);

            Toast.makeText(getActivity(), "ExpandoOnClickListener", Toast.LENGTH_LONG).show();
        }
});

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

Ответ 2

Вы можете программно поднять событие клика на вид, чтобы вызвать его OnClickListener, как показано ниже:

view.performClick();

Теперь, если вы назовете это на своем втором макете в первом макете OnClickListener, я надеюсь, что он должен сделать волшебство

Ответ 3

С SDK 15 вы можете просто вызвать метод:

view.callOnClick()

Ответ 4

Если вы не можете изменить код CustomView, у вас есть опция ниже.

  • Расширьте CustomView.
  • Переопределите метод onClick() и привяжите его как прослушиватель к первому макету.
  • Внутри onClick() сначала вызовите super.onClick(), затем добавьте дополнительную функциональность ниже.

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