Skip to content

Commit 57580ac

Browse files
start shared transition tutorials
1 parent 0ea264d commit 57580ac

File tree

30 files changed

+681
-0
lines changed

30 files changed

+681
-0
lines changed

Tutorial3-1Transitions/.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build

Tutorial3-1Transitions/build.gradle

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
plugins {
2+
id 'com.android.application'
3+
id 'kotlin-android'
4+
id 'kotlin-android-extensions'
5+
id 'kotlin-kapt'
6+
}
7+
8+
android {
9+
compileSdkVersion 30
10+
buildToolsVersion "30.0.2"
11+
12+
defaultConfig {
13+
applicationId "com.smarttoolfactory.tutorial3_1transitions"
14+
minSdkVersion 21
15+
targetSdkVersion 30
16+
versionCode 1
17+
versionName "1.0"
18+
19+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
20+
}
21+
22+
buildTypes {
23+
release {
24+
minifyEnabled false
25+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26+
}
27+
}
28+
compileOptions {
29+
sourceCompatibility JavaVersion.VERSION_1_8
30+
targetCompatibility JavaVersion.VERSION_1_8
31+
}
32+
kotlinOptions {
33+
jvmTarget = '1.8'
34+
}
35+
36+
buildFeatures {
37+
dataBinding = true
38+
}
39+
40+
}
41+
42+
dependencies {
43+
44+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
45+
implementation 'androidx.core:core-ktx:1.3.2'
46+
47+
implementation 'androidx.appcompat:appcompat:1.2.0'
48+
implementation 'com.google.android.material:material:1.2.1'
49+
implementation 'androidx.constraintlayout:constraintlayout:2.0.1'
50+
implementation 'androidx.viewpager2:viewpager2:1.0.0'
51+
implementation 'io.reactivex.rxjava3:rxjava:3.0.6'
52+
53+
// LifeCycle
54+
implementation "androidx.lifecycle:lifecycle-common-java8:2.2.0"
55+
56+
// Coroutines
57+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.7"
58+
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.7"
59+
60+
// Dynamic Animation
61+
implementation "androidx.dynamicanimation:dynamicanimation:1.0.0"
62+
63+
// Leak Canary
64+
debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.5'
65+
66+
testImplementation 'junit:junit:4.+'
67+
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
68+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
69+
}
+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package com.smarttoolfactory.tutorial3_1transitions
2+
3+
import androidx.test.platform.app.InstrumentationRegistry
4+
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
6+
import org.junit.Test
7+
import org.junit.runner.RunWith
8+
9+
import org.junit.Assert.*
10+
11+
/**
12+
* Instrumented test, which will execute on an Android device.
13+
*
14+
* See [testing documentation](http://d.android.com/tools/testing).
15+
*/
16+
@RunWith(AndroidJUnit4::class)
17+
class ExampleInstrumentedTest {
18+
@Test
19+
fun useAppContext() {
20+
// Context of the app under test.
21+
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
22+
assertEquals("com.smarttoolfactory.tutorial3_1transitions", appContext.packageName)
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
package="com.smarttoolfactory.tutorial3_1transitions">
4+
5+
<application
6+
android:allowBackup="true"
7+
android:icon="@mipmap/ic_launcher"
8+
android:label="@string/app_name"
9+
android:roundIcon="@mipmap/ic_launcher_round"
10+
android:supportsRtl="true"
11+
android:theme="@style/Theme.AnimationTutorials">
12+
<activity android:name=".MainActivity">
13+
<intent-filter>
14+
<action android:name="android.intent.action.MAIN" />
15+
16+
<category android:name="android.intent.category.LAUNCHER" />
17+
</intent-filter>
18+
</activity>
19+
</application>
20+
21+
</manifest>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
package com.smarttoolfactory.tutorial3_1transitions
2+
3+
import android.content.Intent
4+
import androidx.appcompat.app.AppCompatActivity
5+
import android.os.Bundle
6+
import android.view.View
7+
import androidx.databinding.DataBindingUtil
8+
import androidx.recyclerview.widget.DividerItemDecoration
9+
import androidx.recyclerview.widget.LinearLayoutManager
10+
import com.smarttoolfactory.tutorial3_1transitions.adapter.BaseAdapter
11+
import com.smarttoolfactory.tutorial3_1transitions.adapter.ChapterSelectionAdapter
12+
import com.smarttoolfactory.tutorial3_1transitions.adapter.model.ActivityClassModel
13+
import com.smarttoolfactory.tutorial3_1transitions.databinding.ActivityMainBinding
14+
import java.util.ArrayList
15+
16+
class MainActivity : AppCompatActivity(), BaseAdapter.OnRecyclerViewItemClickListener {
17+
18+
private val activityClassModels = ArrayList<ActivityClassModel>()
19+
20+
override fun onCreate(savedInstanceState: Bundle?) {
21+
super.onCreate(savedInstanceState)
22+
23+
title = "MainActivity"
24+
25+
val activityMainBinding =
26+
DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
27+
28+
addChapters()
29+
30+
val recyclerView = activityMainBinding.recyclerView
31+
32+
recyclerView.apply {
33+
34+
// Use fixed size for performance
35+
setHasFixedSize(true)
36+
37+
// use a linear layout manager
38+
layoutManager = LinearLayoutManager(this@MainActivity)
39+
40+
// Add vertical divider
41+
addItemDecoration(
42+
DividerItemDecoration(
43+
this@MainActivity,
44+
DividerItemDecoration.VERTICAL
45+
)
46+
)
47+
48+
// Add Adapter
49+
recyclerView.adapter = ChapterSelectionAdapter(activityClassModels).apply {
50+
setOnItemClickListener(this@MainActivity)
51+
}
52+
}
53+
}
54+
55+
private fun addChapters() {
56+
57+
// Add Activities to list to be displayed on RecyclerView
58+
// activityClassModels.add(
59+
// ActivityClassModel(
60+
// Activity1_1Basics::class.java,
61+
// getString(R.string.activity1_1)
62+
// )
63+
// )
64+
65+
66+
}
67+
68+
@Override
69+
override fun onItemClicked(view: View, position: Int) {
70+
Intent(this@MainActivity, activityClassModels[position].clazz).also {
71+
startActivity(it)
72+
}
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
package com.smarttoolfactory.tutorial3_1transitions.adapter
2+
3+
import android.view.LayoutInflater
4+
import android.view.View
5+
import android.view.ViewGroup
6+
import androidx.databinding.DataBindingUtil
7+
import androidx.databinding.ViewDataBinding
8+
9+
import androidx.recyclerview.widget.RecyclerView
10+
import com.smarttoolfactory.tutorial3_1transitions.BR
11+
12+
/**
13+
* Base Adapter class for creating [RecyclerView.Adapter]
14+
*
15+
* Process to create Adapter is listed below:
16+
* * 1- Inflate layout and create binding object with DataBindingUtil.inflate
17+
* inside onCreateViewHolder() and create ViewHolder
18+
*
19+
* * 2- Get binding object inside constructor of MyViewHolder constructor
20+
*
21+
* * 3- Bind items to rows inside onCreateViewHolder() method
22+
*
23+
*/
24+
abstract class BaseAdapter : RecyclerView.Adapter<BaseAdapter.MyViewHolder>() {
25+
26+
private var listener: OnRecyclerViewItemClickListener? = null
27+
28+
inner class MyViewHolder// TODO #2
29+
(// each data item is just a string in this case
30+
private val binding: ViewDataBinding
31+
) : RecyclerView.ViewHolder(binding.root), View.OnClickListener {
32+
33+
// TODO #3
34+
internal fun bind(obj: Any) {
35+
binding.setVariable(BR.obj, obj)
36+
binding.executePendingBindings()
37+
38+
// Set click listener
39+
itemView.setOnClickListener(this)
40+
}
41+
42+
override fun onClick(v: View) {
43+
listener?.run {
44+
onItemClicked(v, layoutPosition)
45+
}
46+
}
47+
48+
}
49+
50+
// TODO #1
51+
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
52+
// create a new view
53+
val layoutInflater = LayoutInflater.from(parent.context)
54+
val binding =
55+
DataBindingUtil.inflate<ViewDataBinding>(
56+
layoutInflater,
57+
getLayoutIdForType(viewType),
58+
parent,
59+
false
60+
)
61+
// set the view's size, margins, paddings and layout parameters
62+
return MyViewHolder(binding)
63+
}
64+
65+
// TODO #3
66+
override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
67+
holder.bind(getDataAtPosition(position))
68+
}
69+
70+
71+
// TODO #3
72+
73+
/**
74+
* Get data in position for RecyclerView row. This method is invoked inside
75+
* onBindViewHolder() method of RecyclerView
76+
*
77+
* @param position indicates the item for the current row
78+
* @return data for the current row
79+
*/
80+
abstract fun getDataAtPosition(position: Int): Any
81+
82+
// TODO #1
83+
84+
/**
85+
* Get id of layout from R. This method is invoked from onCreateViewHolder method of Adapter
86+
*
87+
* @param viewType id of layout row of RecyclerView
88+
* @return id of layout
89+
*/
90+
abstract fun getLayoutIdForType(viewType: Int): Int
91+
92+
/**
93+
* RecyclerViewClickListener interface helps user to set a clickListener to the
94+
* RecyclerView. By setting this listener, any item of Recycler View can respond
95+
* to any interaction.
96+
*/
97+
interface OnRecyclerViewItemClickListener {
98+
/**
99+
* This is a callback method that be overridden by the class that implements this
100+
* interface
101+
*/
102+
fun onItemClicked(view: View, position: Int)
103+
}
104+
105+
fun setOnItemClickListener(listener: OnRecyclerViewItemClickListener) {
106+
this.listener = listener
107+
}
108+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.smarttoolfactory.tutorial3_1transitions.adapter
2+
3+
import com.smarttoolfactory.tutorial3_1transitions.adapter.model.ActivityClassModel
4+
5+
6+
/**
7+
* Process to create Adapter is listed below:
8+
* * 1- Inflate layout and create binding object with DataBindingUtil.inflate
9+
* inside onCreateViewHolder() and create ViewHolder
10+
*
11+
* * 2- Get binding object inside constructor of MyViewHolder constructor
12+
*
13+
* * 3- Bind items to rows inside onCreateViewHolder() method
14+
*
15+
*/
16+
17+
// Provide a suitable constructor (depends on the kind of data set)
18+
class ChapterSelectionAdapter(private val data: List<ActivityClassModel>) : BaseAdapter() {
19+
20+
override fun getDataAtPosition(position: Int): Any {
21+
return data[position]
22+
}
23+
24+
25+
override fun getLayoutIdForType(viewType: Int): Int {
26+
return R.layout.row_layout
27+
}
28+
29+
30+
override fun getItemCount(): Int {
31+
return data.size
32+
}
33+
}
34+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.smarttoolfactory.tutorial3_1transitions.adapter.model
2+
3+
data class ActivityClassModel(val clazz: Class<*>, val description: String = clazz.name)

0 commit comments

Comments
 (0)