[Android][Kotlin] I gave it a shot and made a radar screen view.

jun higashijimajun higashijima
2 min read

https://github.com/aaaa1597/AndKot-RadarViewSample

Abstract

  • I created a typical-style radar as an Android View.

  • Includes instructions on how to use it.

  • Includes explanations of the source code.

Overview

I wanted to display a radar screen for a BLE (Bluetooth Low Energy) app I’m building. I looked around but couldn’t find one, so I decided to build it myself. A radar screen typically appears greenish, so I focused on that aesthetic. The source code is available via the GitHub link at the top of the page.

How to Use

  • Just insert it into your layout XML as you like.

  • It assumes a fixed width and height for the view.

  • Radar points are simply added to the radarPoints list in RadarView.kt (line 69); feel free to add or remove as needed.

  • It supports switching between an arc-shaped radar and a full circle. Set a float value for app:sweepRange to control this.

  • Two patterns are supported for the radar line motion: continuous clockwise rotation, or back-and-forth sweeping. Control this behavior with the boolean attribute app:isSweepWrapped.

Layout Attributes Explanation

Here’s a quick explanation of the layout attributes:

AttributeTypeValue RangeDescription
sweepRangefloat0–359°The angle of the arc
isSweepWrappedbooleantrue/falseWhether the radar sweep wraps and reverses

Key Points in the Source Code

  • The custom view extends the Android View class. In Kotlin, it’s easy to override just one constructor:

      class RadarView @JvmOverloads constructor(
          context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
      ) : View(context, attrs, defStyleAttr) {
    

    This approach is very convenient.

  • Custom attributes: I didn’t even know you could create custom attributes before—great learning! It’s easier if you first create res/values/attrs.xml, and then you can retrieve values using withStyledAttributes().

    Example attrs.xml:

      <?xml version="1.0" encoding="utf-8"?>
      <resources>
          <declare-styleable name="RadarView">
              <attr name="sweepRange" format="float"/> <!-- angle: 0–359° -->
              <attr name="isSweepWrapped" format="boolean"/>
          </declare-styleable>
      </resources>
    

    In RadarView.kt (lines 24–32):

      init {
          attrs?.let {
              context.withStyledAttributes(it, R.styleable.RadarView) {
                  D_SWEEP_RANGE = getFloat(R.styleable.RadarView_sweepRange, 360f)
                  D_START_ANGLE = -D_SWEEP_RANGE / 2f
                  D_IS_SWEEP_WRAPPED = getBoolean(R.styleable.RadarView_isSweepWrapped, false)
              }
          }
      }
      ``` :contentReference[oaicite:6]{index=6}
    
  • Radar drawing: The drawing logic resides in onDraw(). It draws arcs or circles, radar lines, and even the trailing effect of the radar sweep. It was challenging to implement—but I feel there must be a simpler way.

0
Subscribe to my newsletter

Read articles from jun higashijima directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

jun higashijima
jun higashijima