首页 > 解决方案 > 空指针异常,同时访问 UI 元素

问题描述

在 Studio 中创建绘图应用程序,尝试访问我的 UI 元素时遇到空指针异常,因为我使用的是 View Binding 而不是普通的数据绑定。这是代码。

private lateinit var binding: ActivityMainBinding
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        var binding: ActivityMainBinding = ActivityMainBinding.inflate(layoutInflater)

        setContentView(binding.root)

binding.drawingView.setSizeForBrush(20.toFloat())

       binding.ibBrush.setOnClickListener {
            showBrushSizeChooserDialog()
        }

    }

    private fun showBrushSizeChooserDialog() {
        val brushDialog = Dialog(this)
        brushDialog.setContentView(R.layout.dialog_brush_size)
        brushDialog.setTitle("Brush size :")
        var smallbtn=findViewById<ImageButton>(R.id.ib_small_brush)
         smallbtn = brushDialog.ib_small_brush
       smallbtn.setOnClickListener(View.OnClickListener {
            binding.drawingView.setSizeForBrush(10.toFloat())
            brushDialog.dismiss()
        })
        brushDialog.show()
        }
    }

主要活动的活动 xml

  <com.example.drawing_app.DrawingView
       android:id="@+id/drawing_view"
       android:layout_width="0dp"
       android:layout_height="0dp"
       android:layout_margin="5dp"
       android:background="@drawable/backgroud_drawing_view_layout"
      app:layout_constraintTop_toTopOf="parent"
      app:layout_constraintRight_toRightOf="parent"
      app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintBottom_toTopOf="@+id/ib_brush"/>

   <ImageButton
       android:id="@+id/ib_brush"
       android:layout_width="50dp"
       android:layout_height="50dp"
       android:layout_margin="5dp"
       android:scaleType="fitXY"
       android:src="@drawable/ic_brush"
       app:layout_constraintBottom_toBottomOf="parent"
       app:layout_constraintHorizontal_bias="0.498"
       app:layout_constraintLeft_toLeftOf="parent"
       app:layout_constraintRight_toRightOf="parent"
       app:layout_constraintTop_toTopOf="parent"
       app:layout_constraintVertical_bias="0.976" />

dailoge 画笔大小--

<ImageButton
    android:id="@+id/ib_small_brush"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="image_small"
    android:src="@drawable/small"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintBottom_toTopOf="@+id/ib_medium_brush"/>
<ImageButton
    android:id="@+id/ib_medium_brush"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="image_medium"
    android:src="@drawable/medium"
    app:layout_constraintTop_toBottomOf="@+id/ib_small_brush"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintBottom_toTopOf="@+id/ib_large_brush"
    />
<ImageButton
    android:id="@+id/ib_large_brush"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:contentDescription="image_large"
    android:src="@drawable/large"
    app:layout_constraintTop_toBottomOf="@+id/ib_small_brush"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintBottom_toBottomOf="parent"
    />

DrawingView 类——

class DrawingView(context: Context, attrs:AttributeSet) : View(context,attrs) {//Yeh meri custom class hai
                                                                                // for setting the view
    private var mDrawPath: CustomPath?=null
    private var mCanvasBitmap:Bitmap?=null
    private var mDrawPaint: Paint?=null // The Paint class holds the style and color information about how to draw geometries, text and bitmaps
    private var mCanvasPaint:Paint?=null
    private var mBrushSize:Float=0.toFloat()
    private var color= Color.BLACK
    private var canvas:Canvas?=null
    private val mPaths=ArrayList<CustomPath>()//for making the drawing permanent

    init {//This method initializes the attributes of the   ViewForDrawing class.
        setUpDrawing()

    }
private fun setUpDrawing(){
    mDrawPaint=Paint()
    mDrawPath=CustomPath(color,mBrushSize)
    mDrawPaint!!.color=color
    mDrawPaint!!.style=Paint.Style.STROKE
    mDrawPaint!!.strokeJoin=Paint.Join.ROUND
    mDrawPaint!!.strokeCap=Paint.Cap.ROUND
    mCanvasPaint= Paint(Paint.DITHER_FLAG)
//    mBrushSize=20.toFloat()

}

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)
        mCanvasBitmap= Bitmap.createBitmap(w,h,Bitmap.Config.ARGB_8888)
        canvas = Canvas(mCanvasBitmap!!)
    }

    //This method is called when a stroke is drawn on the canvas
    // as a part of the painting.
    override fun onDraw(canvas: Canvas) {
        super.onDraw(canvas)
        canvas.drawBitmap(mCanvasBitmap!!, 0f,0f,mCanvasPaint)


        for (path in mPaths){
            mDrawPaint!!.strokeWidth=path.brushThicknes
            mDrawPaint!!.color=mDrawPath!!.color
            canvas.drawPath(path,mDrawPaint!!)
        }


        if(!mDrawPath!!.isEmpty ) {
            mDrawPaint!!.strokeWidth=mDrawPath!!.brushThicknes
            mDrawPaint!!.color=mDrawPath!!.color
            canvas.drawPath(mDrawPath!!,mDrawPaint!!)
        }

    }

    override fun onTouchEvent(event: MotionEvent?): Boolean {
        val touchx=event?.x
        val touchy=event?.y

        when(event?.action){
            MotionEvent.ACTION_DOWN -> {
                mDrawPath!!.color=color
                mDrawPath!!.brushThicknes=mBrushSize

                mDrawPath!!.reset()
                if (touchx != null) {
                    if (touchy != null) {
                        mDrawPath!!.moveTo(touchx,touchy)
                    }
                }
            } MotionEvent.ACTION_MOVE ->{
            if (touchx != null) {
                if (touchy != null) {
                    mDrawPath!!.lineTo(touchx,touchy)
                }
            }
            }MotionEvent.ACTION_UP ->{
            mPaths.add(mDrawPath!!)
                mDrawPath= CustomPath(color,mBrushSize)
            }
            else -> return false
        }
        invalidate()
        return true
    }
    fun setSizeForBrush(newSize:Float){
        mBrushSize=TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
            newSize,resources.displayMetrics)
        mDrawPaint!!.strokeWidth=mBrushSize
    }


    internal class CustomPath(var color:Int,var brushThicknes: Float): Path() {


    }

}

错误 -

   java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.ImageButton.setOnClickListener(android.view.View$OnClickListener)' on a null object reference
        at com.example.drawing_app.MainActivity.showBrushSizeChooserDialog(MainActivity.kt:38)
        at com.example.drawing_app.MainActivity.onCreate$lambda-0(MainActivity.kt:28)
        at com.example.drawing_app.MainActivity.lambda$vVSWa6PBtLfyDmpMU2VWZZJ9PGQ(Unknown Source:0)
        at com.example.drawing_app.-$$Lambda$MainActivity$vVSWa6PBtLfyDmpMU2VWZZJ9PGQ.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:7254)
        at android.view.View.performClickInternal(View.java:7212)
        at android.view.View.access$3800(View.java:828)
        at android.view.View$PerformClick.run(View.java:27889)
        at android.os.Handler.handleCallback(Handler.java:883)
        at android.os.Handler.dispatchMessage(Handler.java:100)
        at android.os.Looper.loop(Looper.java:227)
        at android.app.ActivityThread.main(ActivityThread.java:7822)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1026)

找不到东西有什么问题。先感谢您。

标签: javaandroidkotlin

解决方案


您在活动上调用 findViewById,而不是对话框。因此,它在 Activity 的视图树中搜索该视图。使用var smallbtn=dialog.findViewById<ImageButton>(R.id.ib_small_brush)它应该可以工作。


推荐阅读