开发者社区> 问答> 正文

Android自定义控件中为Button设置自定义监听器出现空指针。

Android自定义TopBar中给ImageButton设置自定义点击监听器,当点击ImageButton时在listener处出现NullPointerException。

会出错的地方我在后面写了//TODO 。

请问为什么会出现listener没有被实例化的情况?

还有为什么在MainActivity中使用findViewById实例化TopBar也会出现不能实例化控件的情况?

IDE : Android Studio ; 

Compile Sdk Version : API 23 ; 

Build Tool Version : 23.0.1 ; 

Min Sdk Version : API 15 ; 

Target Sdk Version : API 19 ; 

部分代码:

#MainActivity.java
public class MainActivity extends AppCompatActivity {

    private TopBar topBar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

//        topBar = (TopBar) findViewById(R.id.topBar);        //TODO 这样无法实例化topBar  ???
        topBar = new TopBar(getApplicationContext(), null);

        if (topBar == null) {
            Toast.makeText(MainActivity.this, "NULL", Toast.LENGTH_SHORT).show();
        }

        topBar.setOnTopBarClickListener(new TopBar.OnClickListener() {
            @Override
            public void onLeftButtonClick() {
                Toast.makeText(MainActivity.this, "Left", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onRightButtonClick() {
                Toast.makeText(MainActivity.this, "Right", Toast.LENGTH_SHORT).show();
            }
        });
    }
}


#TopBar.java
public class TopBar extends RelativeLayout {

    private ImageButton ibtLeft;
    private ImageButton ibtRight;
    private TextView tvTitle;

    private OnClickListener listener;

    public interface OnClickListener {

        void onLeftButtonClick();

        void onRightButtonClick();
    }

    public void setOnTopBarClickListener(OnClickListener listener) {
        this.listener = listener;
    }

    public TopBar(Context context, AttributeSet attrs) {
        super(context);
        LayoutInflater.from(context).inflate(R.layout.layout_top_bar, this);

        ibtLeft = (ImageButton) findViewById(R.id.ibt_left);
        ibtRight = (ImageButton) findViewById(R.id.ibt_right);
        tvTitle = (TextView) findViewById(R.id.tv_title);

        ibtLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(getContext(), "leftButton", Toast.LENGTH_SHORT).show();      //Toast可以显示
//                listener.onLeftButtonClick();       //TODO NullPointerException  为什么没有实例化listener?
            }
        });

        ibtRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                listener.onRightButtonClick();       //TODO NullPointerException
            }
        });

    }
}

logcat输出

10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime: FATAL EXCEPTION: main
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime: java.lang.NullPointerException
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at com.vder.puzzlegame.ui.TopBar$2.onClick(TopBar.java:55)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at android.view.View.performClick(View.java:4204)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:17355)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:725)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:92)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:137)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5041)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:511)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
10-14 13:42:14.442 1366-1366/com.vder.puzzlegame E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

展开
收起
爵霸 2016-06-01 11:22:16 10136 0
1 条回答
写回答
取消 提交回答
  • 一般的控件只要是继承了View 都可以添加这两个事件,只需要重写View的setOnClicklistener和setOnLongClickListener这两个函数就可以了。  添加这两个函数,别人就能用set方法给你传进来listener,而你可以在onTouch方法里通过判断aciton_down action_move action_up 通过时间来判断是长按还是单击。
    

    “答案来源于网络,供您参考” 希望以上信息可以帮到您!

    2019-09-27 19:45:35
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
58同城Android客户端Walle框架演进与实践之路 立即下载
Android组件化实现 立即下载
蚂蚁聚宝Android秒级编译——Freeline 立即下载