Android 如何以编程方式触发 Onclick 事件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10894440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 05:20:43  来源:igfitidea点击:

How can I fire Onclick event programmatically?

androidonclicklistener

提问by Zakaria

I have a custom view with 2 linear layouts: the first is the view's header and the second is the the details view.

我有一个带有 2 个线性布局的自定义视图:第一个是视图的标题,第二个是详细信息视图。

In the custom view, the OnClickListener of the header Linearlayout is already defined: when it fires, it collapses/expandes the second linearlayout.

在自定义视图中,标题 Linearlayout 的 OnClickListener 已经定义:当它触发时,它会折叠/展开第二个线性布局。

What I want to do is to add more functionalities to my header's OnClickListener event (i.e.: collapse/expand the second layout and show a Toast).

我想要做的是向我的标题的 OnClickListener 事件添加更多功能(即:折叠/展开第二个布局并显示 Toast)。

I can't modify the source code of the custom view. I tried to set a new OnClickListener but it hides the initial event (collapse/expand).

我无法修改自定义视图的源代码。我试图设置一个新的 OnClickListener 但它隐藏了初始事件(折叠/展开)。

How should I implement this?

我应该如何实施?

The source code of 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();
            }
        });
    }
}

What I want to do is to add some code to the already defined OnClickListener event in my activity. Something like that:

我想要做的是向我的活动中已经定义的 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();
            }
        }
    });
}

采纳答案by Vladimir

Simple solution would be to get original OnClickListener and then fire it in new one:

简单的解决方案是获取原始 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();
        }
    }
});

Sadly, Viewdoes not have getOnClickListner(), but I guess you can use reflectionto get it. It is stored in the fieldmOnClickListener(source).

可悲的是,View没有getOnClickListner(),但我想您可以使用反射来获取它。它存储在字段mOnClickListener( source) 中。

This is how you can get OnClickListenerdefined for your layout:

这是您可以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's 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();
        }
});

I didn't really bother to handle all exception correctly, but it's enough to get the idea. It might look messy, but it's actually just 5 lines of new code to solve your problem.

我并没有真正费心去正确处理所有异常,但这足以理解这个想法。它可能看起来很乱,但实际上只需 5 行新代码即可解决您的问题。

回答by waqaslam

You can programmatically raise click event on a View to call it's OnClickListeneras below:

您可以以编程方式在视图上引发单击事件以调用它OnClickListener,如下所示:

view.performClick();

Now if you call this on your second layout under first layout's OnClickListenerthen i hope it should do the magic

现在,如果您在第一个布局的OnClickListener下在您的第二个布局上调用它,那么我希望它应该能发挥作用

回答by Vadim

Since SDK 15 you can just call method:

从 SDK 15 开始,您只需调用方法:

view.callOnClick()

回答by Sudhaker

If you cannot modify the code of CustomView then you have the below option.

如果您无法修改 CustomView 的代码,那么您可以选择以下选项。

  • Extend the CustomView.
  • Override the onClick() method and bind this as a Listener to the first layout.
  • Inside onClick() first call super.onClick() then add your additional functionality below.
  • 扩展自定义视图。
  • 覆盖 onClick() 方法并将其作为侦听器绑定到第一个布局。
  • 在 onClick() 内部首先调用 super.onClick() 然后在下面添加您的附加功能。

This way you are keeping the existing code and adding additional functionality as well.

通过这种方式,您可以保留现有代码并添加其他功能。