<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[[Android][Kotlin] Making a Radar View]]></title><description><![CDATA[[Android][Kotlin] Making a Radar View]]></description><link>https://androidkotlin-making-a-radar-view.hashnode.dev</link><generator>RSS for Node</generator><lastBuildDate>Wed, 23 Sep 2026 20:21:19 GMT</lastBuildDate><atom:link href="https://androidkotlin-making-a-radar-view.hashnode.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[[Android][Kotlin] I gave it a shot and made a radar screen view.]]></title><description><![CDATA[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 ...]]></description><link>https://androidkotlin-making-a-radar-view.hashnode.dev/androidkotlin-i-gave-it-a-shot-and-made-a-radar-screen-view</link><guid isPermaLink="true">https://androidkotlin-making-a-radar-view.hashnode.dev/androidkotlin-i-gave-it-a-shot-and-made-a-radar-screen-view</guid><category><![CDATA[Android]]></category><category><![CDATA[Kotlin]]></category><category><![CDATA[view]]></category><dc:creator><![CDATA[jun higashijima]]></dc:creator><pubDate>Fri, 29 Aug 2025 13:11:01 GMT</pubDate><content:encoded><![CDATA[<p><a target="_blank" href="https://github.com/aaaa1597/AndKot-RadarViewSample">https://github.com/aaaa1597/AndKot-RadarViewSample</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1756473747274/ad47692b-ab0c-4257-aa09-711334c53bac.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-abstract">Abstract</h3>
<ul>
<li><p>I created a typical-style radar as an Android View.</p>
</li>
<li><p>Includes instructions on how to use it.</p>
</li>
<li><p>Includes explanations of the source code.</p>
</li>
</ul>
<h3 id="heading-overview">Overview</h3>
<p>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.</p>
<h3 id="heading-how-to-use">How to Use</h3>
<ul>
<li><p>Just insert it into your layout XML as you like.</p>
</li>
<li><p>It assumes a fixed width and height for the view.</p>
</li>
<li><p>Radar points are simply added to the <code>radarPoints</code> list in <code>RadarView.kt</code> (line 69); feel free to add or remove as needed.</p>
</li>
<li><p>It supports switching between an arc-shaped radar and a full circle. Set a float value for <code>app:sweepRange</code> to control this.</p>
</li>
<li><p>Two patterns are supported for the radar line motion: continuous clockwise rotation, or back-and-forth sweeping. Control this behavior with the boolean attribute <code>app:isSweepWrapped</code>.</p>
</li>
</ul>
<h3 id="heading-layout-attributes-explanation">Layout Attributes Explanation</h3>
<p>Here’s a quick explanation of the layout attributes:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Attribute</td><td>Type</td><td>Value Range</td><td>Description</td></tr>
</thead>
<tbody>
<tr>
<td><code>sweepRange</code></td><td>float</td><td>0–359°</td><td>The angle of the arc</td></tr>
<tr>
<td><code>isSweepWrapped</code></td><td>boolean</td><td>true/false</td><td>Whether the radar sweep wraps and reverses</td></tr>
</tbody>
</table>
</div><h3 id="heading-key-points-in-the-source-code">Key Points in the Source Code</h3>
<ul>
<li><p>The custom view extends the Android <code>View</code> class. In Kotlin, it’s easy to override just one constructor:</p>
<pre><code class="lang-kotlin">  <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">RadarView</span> <span class="hljs-meta">@JvmOverloads</span> <span class="hljs-keyword">constructor</span></span>(
      context: Context, attrs: AttributeSet? = <span class="hljs-literal">null</span>, defStyleAttr: <span class="hljs-built_in">Int</span> = <span class="hljs-number">0</span>
  ) : View(context, attrs, defStyleAttr) {
</code></pre>
<p>  This approach is very convenient.</p>
</li>
<li><p><strong>Custom attributes:</strong> I didn’t even know you could create custom attributes before—great learning! It’s easier if you first create <code>res/values/attrs.xml</code>, and then you can retrieve values using <code>withStyledAttributes()</code>.</p>
<p>  <strong>Example</strong> <code>attrs.xml</code>:</p>
<pre><code class="lang-xml">  <span class="hljs-meta">&lt;?xml version="1.0" encoding="utf-8"?&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">resources</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">declare-styleable</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"RadarView"</span>&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">attr</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"sweepRange"</span> <span class="hljs-attr">format</span>=<span class="hljs-string">"float"</span>/&gt;</span> <span class="hljs-comment">&lt;!-- angle: 0–359° --&gt;</span>
          <span class="hljs-tag">&lt;<span class="hljs-name">attr</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"isSweepWrapped"</span> <span class="hljs-attr">format</span>=<span class="hljs-string">"boolean"</span>/&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">declare-styleable</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">resources</span>&gt;</span>
</code></pre>
<p>  In <code>RadarView.kt</code> (lines 24–32):</p>
<pre><code class="lang-kotlin">  <span class="hljs-keyword">init</span> {
      attrs?.let {
          context.withStyledAttributes(it, R.styleable.RadarView) {
              D_SWEEP_RANGE = getFloat(R.styleable.RadarView_sweepRange, <span class="hljs-number">360f</span>)
              D_START_ANGLE = -D_SWEEP_RANGE / <span class="hljs-number">2f</span>
              D_IS_SWEEP_WRAPPED = getBoolean(R.styleable.RadarView_isSweepWrapped, <span class="hljs-literal">false</span>)
          }
      }
  }
  ``` :contentReference[oaicite:<span class="hljs-number">6</span>]{index=<span class="hljs-number">6</span>}
</code></pre>
</li>
<li><p><strong>Radar drawing:</strong> The drawing logic resides in <code>onDraw()</code>. 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.</p>
</li>
</ul>
]]></content:encoded></item></channel></rss>