skip to Main Content

I have created a custom view class extending Android’s WebView, but when I add it to an xml layout, it appears as a gray block. I would like to show a custom layout in place of the gray block to be able to preview it.

The definition of the custom view is as follows:

class CustomView(context: Context, attrs: AttributeSet?) : WebView(context, attrs) {

    constructor(context: Context) : this(context, null)

    init {
        if (isInEditMode) {
            //show preview layout
            context.getSystemService<LayoutInflater>()!!
                .inflate(R.layout.widget_match_preview, this, true)
        }
    }
}

As can be seen in the code above, I have tried to show a preview in the init block, but it stills shows the gray block in the Android Studio layout preview.

3

Answers


  1. Chosen as BEST ANSWER

    AFAIK this can not be done, as @cactustictacs said, WebView implements its own drawing and can not be changed to another layout. What I ended up doing is overrride the onDraw(canvas: Canvas) method, and add the following to render a preview icon at the center of the view:

    @SuppressLint("DrawAllocation")
    override fun onDraw(canvas: Canvas) {
        if (isInEditMode.not()) {
            super.onDraw(canvas)
            return
        }
        canvas.drawColor(Color.WHITE)
        val bitmap = ResourcesCompat.getDrawable(resources, R.drawable.widget_preview, null)!!.toBitmap()
        val size = minOf(width, height) / 2
        val rect = Rect((width - size) / 2, (height - size) / 2, (width + size) / 2, (height + size) / 2)
        canvas.drawBitmap(bitmap, null, rect, null)
    }
    

    Draw allocation is not a problem since will only be done once while in preview mode in the IDE. The only downside is that the icon is being drawn behind the "CustomView" text but is not big of a deal.


  2. I think you’re missing addView:

    class CustomView(context: Context, attrs: AttributeSet?) : WebView(context, attrs) {
    
        constructor(context: Context) : this(context, null)
    
        init {
            if (isInEditMode) {
                // inflate the preview layout
                val previewLayout = context.getSystemService<LayoutInflater>()!!
                    .inflate(R.layout.widget_match_preview, null)
    
                // add the preview layout as a child view of the CustomView
                addView(previewLayout)
            }
        }
    }
    
    Login or Signup to reply.
  3. You should:

    class CustomView : LinearLayout {
    
        constructor(context: Context) : super(context)
        constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
        constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    
        init {
            LayoutInflater.from(context).inflate(R.layout.widget_match_preview, this, true)
            if (!isInEditMode) {
                // skip code
            }
        }
    }
    
    • Result:
      previewlayout

    • In xml:

        <?xml version="1.0" encoding="utf-8"?>
        <LinearLayout 
         xmlns:android="http://schemas.android.com/apk/res/android"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:background="@color/red"/>
      
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search