Introduction

Within the first half of this tutorial,
we took care of cloning a template undertaking and organising our surroundings.

On this half, we are going to arrange a brand new exercise, outline a brand new structure and clear up the undertaking recordsdata.

Format

First, I’m going to create a brand new structure avoiding the normal XML and doing it programmatically utilizing solely Scala.

To be able to do that, we’re going to wish two png drawables for the totally different states of the LEDs.

One for the on state.

led_on

One other for the off state.

led_off

Subsequent, let’s create a brand new exercise that can change the default HelloScaloid exercise.

I’m going to name this new exercise BinaryClock that extends the SActivity and I’ll outline just a few members.

I hold references to all of the picture views inside the category scope since they are going to be up to date when the time modifications from one other methodology.

I additionally hold a single reference to the drawables I’ll be utilizing to be able to keep away from repeating myself.

Then I outline structure parameters and gravities for the sake of readability additional down.

The lazy val declarations makes it attainable to guard in opposition to NPE earlier than the values are initialized in the course of the oncreate
callback occasion, it is just when these variables are de-referenced for the primary that an object shall be instantiated and
their values shall be set accordingly.

class BinaryClock extends SActivity Gravity.CENTER_HORIZONTAL
  val legendColumnGravity = Gravity.TOP 

After, I outline just a few helper strategies that can deal with styling the UI components. Every will settle for a selected kind of Android UI
widget and set the proper attributes.

def styleBinaryPlaceHolder (t: STextView): STextView = {
  t peak 40.dip  typeface Typeface.MONOSPACE textSize 10.dip gravity Gravity.CENTER textColor getResources.getColor(R.coloration.label)
}

def styleTimePlaceHolder (t: STextView): STextView = {
  t peak 40.dip  typeface Typeface.MONOSPACE textSize 15.dip gravity Gravity.CENTER textColor getResources.getColor(R.coloration.label)
}

def styleLedDrawable (i: SImageView): SImageView = {
  i backgroundColor android.R.coloration.clear imageDrawable ledOffDrawable layoutParams squareElementLayoutParams scaleType ImageView.ScaleType.FIT_CENTER
}

Since we reference R.coloration into the earlier strategies, it’s essential to outline colours.xml with the suitable components.
We solely two colours, one the for background and one other for the textual content labels. This additionally makes it straightforward to alter colours in a while.

<?xml model="1.0" encoding="utf-8"?>
<sources>
    <coloration title="background">#f62a2a2a</coloration>
    <coloration title="label">#ffffdf10</coloration>
</sources>

Subsequent, let’s implement the onCreate methodology, it’s analogous to the common onCreate occasion from a Java Exercise.

See also  9 Methods to Solve Apps Keep Crashing Issue on Android

On this methodology, I’ll assemble the weather of the structure in 8 columns nested right into a root structure of kind of LinearLayout.

All of the columns are additionally LinearLayouts however Scaloid gives syntactic sugar to be able to keep away from having to manually specify a
vertical LinearLayout.

These columns of LinearLayouts comprise varied components, both picture views containing the LED drawables or textual content labels serving to
the consumer.

To be able to model these components, I name the helper strategies that I beforehand outlined.

onCreate {
  
  //Linear layouts that can make all of the totally different the columns
  val binaryLegendLeft = new SVerticalLayout {
    model {
      case t: STextView => styleBinaryPlaceHolder(t)
    }
    STextView("8")
    STextView("4")
    STextView("2")
    STextView("1")
  } gravity legendColumnGravity layoutParams legendColumnLayoutParams
  
  val binaryLegendRight = new SVerticalLayout {
    model {
      case t: STextView => styleBinaryPlaceHolder(t)
    }
    STextView("8")
    STextView("4")
    STextView("2")
    STextView("1")
  } gravity legendColumnGravity layoutParams legendColumnLayoutParams
  
  val hours0 = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
      case i: SImageView => styleLedDrawable(i)
    }
    this += h0Led1
    this += h0Led2
    this += h0Led4
    this += h0Led8
    STextView("H")
  } gravity ledColumnGravity layoutParams ledColumnLayoutParams
  
  val hours1 = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
      case i: SImageView => styleLedDrawable(i)
    }
    this += h1Led1
    this += h1Led2
    STextView("H")
  } gravity ledColumnGravity layoutParams ledColumnLayoutParams
  
  val minutes0 = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
      case i: SImageView => styleLedDrawable(i)
    }
    this += m0Led1
    this += m0Led2
    this += m0Led4
    this += m0Led8
    STextView("M")
  } gravity ledColumnGravity layoutParams ledColumnLayoutParams
  
  val minutes1 = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
      case i: SImageView => styleLedDrawable(i)
    }
    this += m1Led1
    this += m1Led2
    this += m1Led4
    this += m1Led8
    STextView("M")
  } gravity ledColumnGravity layoutParams ledColumnLayoutParams
  
  val seconds0 = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
      case i: SImageView => styleLedDrawable(i)
    }
    this += s0Led1
    this += s0Led2
    this += s0Led4
    this += s0Led8
    STextView("S")
  } gravity ledColumnGravity layoutParams ledColumnLayoutParams
  
  val seconds1 = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
      case i: SImageView => styleLedDrawable(i)
    }
    this += s1Led1
    this += s1Led2
    this += s1Led4
    this += s1Led8
    STextView("S")
  } gravity ledColumnGravity layoutParams ledColumnLayoutParams
  
  val separatorLeft = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
    }
    STextView(":")
  } gravity separatorColumnGravity layoutParams separatorColumnLayoutParams
  
  val separatorRight = new SVerticalLayout {
    model {
      case t: STextView => styleTimePlaceHolder(t)
    }
    STextView(":")
  } gravity separatorColumnGravity layoutParams separatorColumnLayoutParams
  
  //That is the place we set the content material view
  contentView = new SLinearLayout {
    this += binaryLegendLeft
    this += hours1
    this += hours0
    this += separatorLeft
    this += minutes1
    this += minutes0
    this += separatorRight
    this += seconds1
    this += seconds0
    this += binaryLegendRight
  }.gravity(Gravity.CENTER)
   .orientation(LinearLayout.HORIZONTAL)
   .backgroundColor(getResources.getColor(R.coloration.background))
   .layoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
}

Consequence

bundle com.dontbelievethebyte.binaryclock

import android.graphics.Typeface
import android.view.{ViewGroup, Gravity}
import android.widget.{ImageView, LinearLayout}
import scala.language.postfixOps
import org.scaloid.frequent._

class BinaryClock extends SActivity{
  //Seconds first column LEDs
  lazy val s0Led1 : SImageView = new SImageView()
  lazy val s0Led2 : SImageView = new SImageView()
  lazy val s0Led4 : SImageView = new SImageView()
  lazy val s0Led8 : SImageView = new SImageView()

  //Seconds second column LEDs
  lazy val s1Led1 : SImageView = new SImageView()
  lazy val s1Led2 : SImageView = new SImageView()
  lazy val s1Led4 : SImageView = new SImageView()
  lazy val s1Led8 : SImageView = new SImageView()

  //Minutes first column LEDs
  lazy val m0Led1 : SImageView = new SImageView()
  lazy val m0Led2 : SImageView = new SImageView()
  lazy val m0Led4 : SImageView = new SImageView()
  lazy val m0Led8 : SImageView = new SImageView()

  //Minutes first column LEDs
  lazy val m1Led1 : SImageView = new SImageView()
  lazy val m1Led2 : SImageView = new SImageView()
  lazy val m1Led4 : SImageView = new SImageView()
  lazy val m1Led8 : SImageView = new SImageView()

  //Hours first column LEDs
  lazy val h0Led1 : SImageView = new SImageView()
  lazy val h0Led2 : SImageView = new SImageView()
  lazy val h0Led4 : SImageView = new SImageView()
  lazy val h0Led8 : SImageView = new SImageView()

  //Hours first column LEDs
  lazy val h1Led1 : SImageView = new SImageView()
  lazy val h1Led2 : SImageView = new SImageView()

  //Drawables
  lazy val ledOffDrawable = getResources.getDrawable(R.drawable.led_off)
  lazy val ledOnDrawable = getResources.getDrawable(R.drawable.led_on)

  //Format params definitions
  lazy val ledColumnLayoutParams = new LinearLayout.LayoutParams(40 dip, 200.dip)
  lazy val legendColumnLayoutParams = new LinearLayout.LayoutParams(20 dip, 200.dip)
  lazy val separatorColumnLayoutParams = new LinearLayout.LayoutParams(8 dip, 200 dip)
  lazy val squareElementLayoutParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, 40 dip)

  //Columns gravity definitions
  val ledColumnGravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL
  val legendColumnGravity = Gravity.TOP | Gravity.CENTER_HORIZONTAL
  val separatorColumnGravity = Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL
  val squareElementGravity = Gravity.CENTER | Gravity.CENTER_HORIZONTAL

  onCreate {

    //Linear layouts that can make all of the totally different the columns
    val binaryLegendLeft = new SVerticalLayout {
      model {
        case t: STextView => styleBinaryPlaceHolder(t)
      }
      STextView("8")
      STextView("4")
      STextView("2")
      STextView("1")
    } gravity legendColumnGravity layoutParams legendColumnLayoutParams

    val binaryLegendRight = new SVerticalLayout {
      model {
        case t: STextView => styleBinaryPlaceHolder(t)
      }
      STextView("8")
      STextView("4")
      STextView("2")
      STextView("1")
    } gravity legendColumnGravity layoutParams legendColumnLayoutParams

    val hours0 = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
        case i: SImageView => styleLedDrawable(i)
      }
      this += h0Led1
      this += h0Led2
      this += h0Led4
      this += h0Led8
      STextView("H")
    } gravity ledColumnGravity layoutParams ledColumnLayoutParams

    val hours1 = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
        case i: SImageView => styleLedDrawable(i)
      }
      this += h1Led1
      this += h1Led2
      STextView("H")
    } gravity ledColumnGravity layoutParams ledColumnLayoutParams

    val minutes0 = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
        case i: SImageView => styleLedDrawable(i)
      }
      this += m0Led1
      this += m0Led2
      this += m0Led4
      this += m0Led8
      STextView("M")
    } gravity ledColumnGravity layoutParams ledColumnLayoutParams

    val minutes1 = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
        case i: SImageView => styleLedDrawable(i)
      }
      this += m1Led1
      this += m1Led2
      this += m1Led4
      this += m1Led8
      STextView("M")
    } gravity ledColumnGravity layoutParams ledColumnLayoutParams

    val seconds0 = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
        case i: SImageView => styleLedDrawable(i)
      }
      this += s0Led1
      this += s0Led2
      this += s0Led4
      this += s0Led8
      STextView("S")
    } gravity ledColumnGravity layoutParams ledColumnLayoutParams

    val seconds1 = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
        case i: SImageView => styleLedDrawable(i)
      }
      this += s1Led1
      this += s1Led2
      this += s1Led4
      this += s1Led8
      STextView("S")
    } gravity ledColumnGravity layoutParams ledColumnLayoutParams

    val separatorLeft = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
      }
      STextView(":")
    } gravity separatorColumnGravity layoutParams separatorColumnLayoutParams

    val separatorRight = new SVerticalLayout {
      model {
        case t: STextView => styleTimePlaceHolder(t)
      }
      STextView(":")
    } gravity separatorColumnGravity layoutParams separatorColumnLayoutParams

    //That is the place we set the content material view
    contentView = new SLinearLayout {
      this += binaryLegendLeft
      this += hours1
      this += hours0
      this += separatorLeft
      this += minutes1
      this += minutes0
      this += separatorRight
      this += seconds1
      this += seconds0
      this += binaryLegendRight
    }.gravity(Gravity.CENTER)
     .orientation(LinearLayout.HORIZONTAL)
     .backgroundColor(getResources.getColor(R.coloration.background))
     .layoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT))
  }

  def styleBinaryPlaceHolder (t: STextView): STextView = {
    t peak 40.dip  typeface Typeface.MONOSPACE textSize 10.dip gravity Gravity.CENTER textColor getResources.getColor(R.coloration.label)
  }

  def styleTimePlaceHolder (t: STextView): STextView = {
    t peak 40.dip  typeface Typeface.MONOSPACE textSize 15.dip gravity Gravity.CENTER textColor getResources.getColor(R.coloration.label)
  }

  def styleLedDrawable (i: SImageView): SImageView = {
    i backgroundColor android.R.coloration.clear imageDrawable ledOffDrawable layoutParams squareElementLayoutParams scaleType ImageView.ScaleType.FIT_CENTER
  }
}

Cleanup

We will now delete the HelloScaloid exercise and commit our modifications.

See also  Kudos 2--and Kudos plain

We will additionally change the bundle title from the manifest.

<?xml model="1.0" encoding="utf-8"?>
<manifest xmlns_android="http://schemas.android.com/apk/res/android"
      bundle="com.dontbelievethebyte.binaryclock"
      android_versionCode="1"
      android_versionName="1.0">
    <software android_label="BinaryClock" >
        <exercise android_name="BinaryClock"
                  android_label="BinaryClock">
            <intent-filter>
                <motion android_name="android.intent.action.MAIN" />
                <class android_name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </exercise>
    </software>
</manifest>

Return 0

That’s it for now.

Partly 3, I’ll implement the logic that updates the SImageView(s) based on the present time and outline one other methodology
that show a toast reflecting the present time within the conventional human readable type.

Leave a Reply

Your email address will not be published.