diff --git a/.idea/gradle.xml b/.idea/gradle.xml
index 6c252ba..0b0a983 100644
--- a/.idea/gradle.xml
+++ b/.idea/gradle.xml
@@ -13,6 +13,7 @@
+
diff --git a/app/build.gradle b/app/build.gradle
index d8e97ed..0fceb54 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -32,6 +32,7 @@ android {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':design_system')
implementation project(':rally_pie')
+ implementation project(':rally_scrollable_tab')
implementation project(':rally_line_chart')
implementation project(':rally_line_indicator')
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
diff --git a/app/src/main/java/io/material/rally/ui/detail/DetailActivity.kt b/app/src/main/java/io/material/rally/ui/detail/DetailActivity.kt
index e9e2c0a..4236eda 100644
--- a/app/src/main/java/io/material/rally/ui/detail/DetailActivity.kt
+++ b/app/src/main/java/io/material/rally/ui/detail/DetailActivity.kt
@@ -3,11 +3,23 @@ package io.material.rally.ui.detail
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import io.material.rally.R
+import kotlinx.android.synthetic.main.activity_detail.tab
class DetailActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_detail)
+
+ setUpTab()
+ }
+
+ private fun setUpTab() {
+ tab.addTabs(
+ listOf(
+ "OverView", "Jan 2018", "Jan 2018", "Jan 2018", "Jan 2018", "Jan 2018", "Jan 2018",
+ "Jan 2018"
+ )
+ )
}
}
diff --git a/app/src/main/res/layout/activity_detail.xml b/app/src/main/res/layout/activity_detail.xml
index 0e4deb4..7bcc55e 100644
--- a/app/src/main/res/layout/activity_detail.xml
+++ b/app/src/main/res/layout/activity_detail.xml
@@ -1,5 +1,5 @@
-
-
\ No newline at end of file
+
+
+
\ No newline at end of file
diff --git a/design_system/src/main/res/values/type.xml b/design_system/src/main/res/values/type.xml
index ad9e52c..83a1427 100644
--- a/design_system/src/main/res/values/type.xml
+++ b/design_system/src/main/res/values/type.xml
@@ -106,4 +106,8 @@
- 10sp
+
+
diff --git a/rally_scrollable_tab/.gitignore b/rally_scrollable_tab/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/rally_scrollable_tab/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/rally_scrollable_tab/build.gradle b/rally_scrollable_tab/build.gradle
new file mode 100644
index 0000000..df1bb76
--- /dev/null
+++ b/rally_scrollable_tab/build.gradle
@@ -0,0 +1,35 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 29
+ buildToolsVersion "29.0.1"
+
+ defaultConfig {
+ minSdkVersion 19
+ targetSdkVersion 29
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: 'libs', include: ['*.jar'])
+
+ implementation 'androidx.appcompat:appcompat:1.0.2'
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test:runner:1.2.0'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ implementation 'androidx.recyclerview:recyclerview:1.0.0'
+}
diff --git a/rally_scrollable_tab/proguard-rules.pro b/rally_scrollable_tab/proguard-rules.pro
new file mode 100644
index 0000000..f1b4245
--- /dev/null
+++ b/rally_scrollable_tab/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
diff --git a/rally_scrollable_tab/src/androidTest/java/com/example/rally_scrollable_tab/ExampleInstrumentedTest.java b/rally_scrollable_tab/src/androidTest/java/com/example/rally_scrollable_tab/ExampleInstrumentedTest.java
new file mode 100644
index 0000000..da35d52
--- /dev/null
+++ b/rally_scrollable_tab/src/androidTest/java/com/example/rally_scrollable_tab/ExampleInstrumentedTest.java
@@ -0,0 +1,24 @@
+package com.example.rally_scrollable_tab;
+
+import android.content.Context;
+import androidx.test.InstrumentationRegistry;
+import androidx.test.runner.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see Testing documentation
+ */
+@RunWith(AndroidJUnit4.class) public class ExampleInstrumentedTest {
+ @Test public void useAppContext() {
+ // Context of the app under test.
+ Context appContext = InstrumentationRegistry.getTargetContext();
+
+ assertEquals("com.example.rally_scrollable_tab.test", appContext.getPackageName());
+ }
+}
diff --git a/rally_scrollable_tab/src/main/AndroidManifest.xml b/rally_scrollable_tab/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..6dce5b3
--- /dev/null
+++ b/rally_scrollable_tab/src/main/AndroidManifest.xml
@@ -0,0 +1,2 @@
+
diff --git a/rally_scrollable_tab/src/main/java/com/example/rally_scrollable_tab/RallyScrollableTab.kt b/rally_scrollable_tab/src/main/java/com/example/rally_scrollable_tab/RallyScrollableTab.kt
new file mode 100644
index 0000000..4d4361f
--- /dev/null
+++ b/rally_scrollable_tab/src/main/java/com/example/rally_scrollable_tab/RallyScrollableTab.kt
@@ -0,0 +1,124 @@
+package com.example.rally_scrollable_tab
+
+import android.animation.ArgbEvaluator
+import android.content.Context
+import android.graphics.Color
+import android.util.AttributeSet
+import android.view.View
+import android.widget.TextView
+import androidx.annotation.StyleRes
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.LinearSnapHelper
+import androidx.recyclerview.widget.RecyclerView
+
+/**
+ * Created by Chan Myae Aung on 8/4/19.
+ */
+//click listener
+//integration with viewpager
+class RallyScrollableTab : RecyclerView {
+
+ private val tabAdapter by lazy { TabAdapter(style = tabTextStyle) }
+ private var selectedColor = Color.WHITE
+ private var unSelectedColor = Color.GRAY
+ private var tabTextStyle = TabStyle(R.style.TabTextStyle)
+
+ constructor(
+ context: Context,
+ attrs: AttributeSet?
+ ) : super(context, attrs) {
+ init(attrs)
+ }
+
+ constructor(
+ context: Context,
+ attrs: AttributeSet?,
+ defStyle: Int
+ ) : super(context, attrs, defStyle) {
+ init(attrs)
+ }
+
+ private fun init(set: AttributeSet?) {
+ initAttributes(set)
+
+ layoutManager = LinearLayoutManager(context, HORIZONTAL, false)
+ setHasFixedSize(true)
+ adapter = tabAdapter
+
+ val snapHelper = LinearSnapHelper()
+ snapHelper.attachToRecyclerView(this)
+
+ createPagerStyle()
+
+ addOnScrollListener(object : OnScrollListener() {
+ override fun onScrolled(
+ recyclerView: RecyclerView,
+ dx: Int,
+ dy: Int
+ ) {
+ super.onScrolled(recyclerView, dx, dy)
+ post {
+ (0 until childCount).forEach {
+ val child = getChildAt(it)
+ val childCenterX = (child.left + child.right) / 2
+ val scaleValue = getGaussianScale(childCenterX, 1f, 1f, 150.toDouble())
+// child.scaleX = scaleValue
+// child.scaleY = scaleValue
+ colorView(child, scaleValue)
+ }
+ }
+ }
+ })
+ }
+
+ private fun initAttributes(set: AttributeSet?) {
+ val ta = context.obtainStyledAttributes(set, R.styleable.RallyScrollableTab)
+ selectedColor = ta.getColor(R.styleable.RallyScrollableTab_selectedColor, Color.WHITE)
+ unSelectedColor = ta.getColor(R.styleable.RallyScrollableTab_unSelectedColor, Color.GRAY)
+ tabTextStyle =
+ TabStyle(ta.getResourceId(R.styleable.RallyScrollableTab_tabTextStyle, R.style.TabTextStyle))
+ ta.recycle()
+
+ }
+
+ private fun createPagerStyle() {
+ //add padding and set clipToPadding false so other tab items are also visible at left,right edge screen
+ clipToPadding = false
+ val halfSWidth = context.resources.displayMetrics.widthPixels / 2
+ val padding = halfSWidth / 2
+ setPadding(padding, 0, padding, 0)
+ }
+
+ fun addTabs(list: List) {
+ tabAdapter.addAll(list)
+ }
+
+ private fun colorView(
+ child: View,
+ scaleValue: Float
+ ) {
+ val percent = (scaleValue - 1) / 1f
+ val color = ArgbEvaluator().evaluate(percent, unSelectedColor, selectedColor) as Int
+ child.findViewById(R.id.tvTab)
+ .setTextColor(color)
+
+ }
+
+ private fun getGaussianScale(
+ childCenterX: Int,
+ minScaleOffest: Float,
+ scaleFactor: Float,
+ spreadFactor: Double
+ ): Float {
+ val recyclerCenterX = (left + right) / 2
+ return (Math.pow(
+ Math.E,
+ -Math.pow(childCenterX - recyclerCenterX.toDouble(), 2.toDouble()) / (2 * Math.pow(
+ spreadFactor,
+ 2.toDouble()
+ ))
+ ) * scaleFactor + minScaleOffest).toFloat()
+ }
+}
+
+data class TabStyle(@StyleRes val tabTextStyle: Int)
diff --git a/rally_scrollable_tab/src/main/java/com/example/rally_scrollable_tab/TabAdapter.kt b/rally_scrollable_tab/src/main/java/com/example/rally_scrollable_tab/TabAdapter.kt
new file mode 100644
index 0000000..6726feb
--- /dev/null
+++ b/rally_scrollable_tab/src/main/java/com/example/rally_scrollable_tab/TabAdapter.kt
@@ -0,0 +1,53 @@
+package com.example.rally_scrollable_tab
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.annotation.StyleRes
+import androidx.core.widget.TextViewCompat
+import androidx.recyclerview.widget.RecyclerView
+
+/**
+ * Created by Chan Myae Aung on 8/4/19.
+ */
+class TabAdapter(
+ private val tabs: MutableList = mutableListOf(),
+ private val style: TabStyle
+) : RecyclerView.Adapter() {
+
+ override fun onCreateViewHolder(
+ parent: ViewGroup,
+ viewType: Int
+ ): TabViewHolder {
+ val view = LayoutInflater.from(parent.context)
+ .inflate(R.layout.item_tab, parent, false)
+
+ TextViewCompat.setTextAppearance(view.findViewById(R.id.tvTab), style.tabTextStyle)
+ return TabViewHolder(view)
+ }
+
+ override fun getItemCount(): Int {
+ return tabs.size
+ }
+
+ override fun onBindViewHolder(
+ holder: TabViewHolder,
+ position: Int
+ ) {
+ holder.bind(tabs[position])
+ }
+
+ fun addAll(list: List) {
+ tabs.clear()
+ tabs.addAll(list)
+ notifyDataSetChanged()
+ }
+}
+
+class TabViewHolder(view: View) : RecyclerView.ViewHolder(view) {
+ private val tab: TextView = view.findViewById(R.id.tvTab)
+ fun bind(model: String) {
+ tab.text = model
+ }
+}
diff --git a/rally_scrollable_tab/src/main/res/layout/item_tab.xml b/rally_scrollable_tab/src/main/res/layout/item_tab.xml
new file mode 100644
index 0000000..efbf51b
--- /dev/null
+++ b/rally_scrollable_tab/src/main/res/layout/item_tab.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rally_scrollable_tab/src/main/res/values/attrs.xml b/rally_scrollable_tab/src/main/res/values/attrs.xml
new file mode 100644
index 0000000..6a2c229
--- /dev/null
+++ b/rally_scrollable_tab/src/main/res/values/attrs.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/rally_scrollable_tab/src/main/res/values/strings.xml b/rally_scrollable_tab/src/main/res/values/strings.xml
new file mode 100644
index 0000000..8dfff9e
--- /dev/null
+++ b/rally_scrollable_tab/src/main/res/values/strings.xml
@@ -0,0 +1,3 @@
+
+ rally_scrollable_tab
+
diff --git a/rally_scrollable_tab/src/main/res/values/styles.xml b/rally_scrollable_tab/src/main/res/values/styles.xml
new file mode 100644
index 0000000..9ce5991
--- /dev/null
+++ b/rally_scrollable_tab/src/main/res/values/styles.xml
@@ -0,0 +1,6 @@
+
+
+
+
\ No newline at end of file
diff --git a/rally_scrollable_tab/src/test/java/com/example/rally_scrollable_tab/ExampleUnitTest.java b/rally_scrollable_tab/src/test/java/com/example/rally_scrollable_tab/ExampleUnitTest.java
new file mode 100644
index 0000000..970fd18
--- /dev/null
+++ b/rally_scrollable_tab/src/test/java/com/example/rally_scrollable_tab/ExampleUnitTest.java
@@ -0,0 +1,16 @@
+package com.example.rally_scrollable_tab;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * @see Testing documentation
+ */
+public class ExampleUnitTest {
+ @Test public void addition_isCorrect() {
+ assertEquals(4, 2 + 2);
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index e37def5..11f5b61 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app', ':themebuilder', ':design_system', ':rally_pie', ':rally_line_chart', ':rally_line_indicator'
+include ':app', ':themebuilder', ':design_system', ':rally_pie', ':rally_line_chart', ':rally_line_indicator', ':rally_scrollable_tab'