Как я могу запустить 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();
}
}
});
}
Ответы
Ответ 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(), затем добавьте дополнительную функциональность ниже.
Таким образом, вы сохраняете существующий код и добавляете дополнительные функции.