├── .gitignore ├── CHANGELOG_SIMPLE_ADAPTER.md ├── CHANGELOG_SIMPLE_ADAPTER_DATA_BINDING.md ├── CHANGELOG_SIMPLE_ADAPTER_VIEW_BINDING.md ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── app │ │ └── thdev │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── app │ │ │ └── thdev │ │ │ ├── MainActivity.kt │ │ │ ├── SimpleAdapterSampleFirstFragment.kt │ │ │ └── ui │ │ │ ├── adapter_control │ │ │ ├── SimpleAdapterControlSampleAdapterControl.kt │ │ │ └── SimpleAdapterControlSampleFragment.kt │ │ │ └── databinding │ │ │ ├── SimpleAdapterDataBindingSampleAdapterControl.kt │ │ │ ├── SimpleAdapterDataBindingSampleFragment.kt │ │ │ └── SimpleAdapterDataBindingSampleViewModel.kt │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ └── ic_launcher_background.xml │ │ ├── layout │ │ ├── adapter_control_sample_fragment.xml │ │ ├── adapter_data_binding_sample_fragment.xml │ │ ├── adapter_sample_fragment.xml │ │ ├── item_data_binding_text_view.xml │ │ ├── item_text_view.xml │ │ ├── main_activity.xml │ │ └── main_content.xml │ │ ├── menu │ │ └── menu_main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── navigation │ │ └── nav_graph.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── app │ └── thdev │ └── ExampleUnitTest.kt ├── build.gradle ├── dependencies.gradle ├── gradle.properties ├── gradle ├── publish.gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── jcenter.gradle ├── settings.gradle ├── simple-adapter-databinding ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── tech │ │ └── thdev │ │ └── simpleadapter │ │ ├── SimpleDataBindingAdapter.kt │ │ ├── control │ │ └── SimpleDataBindingAdapterControl.kt │ │ ├── data │ │ ├── SimpleAdapterCreateItem.kt │ │ └── source │ │ │ ├── SimpleDataBindingAdapterRepository.kt │ │ │ └── SimpleDataBindingAdapterRepositoryImpl.kt │ │ ├── holder │ │ └── SimpleDataBindingViewHolder.kt │ │ └── util │ │ └── SimpleDataBindingAdapterExtension.kt │ └── res │ └── layout │ └── simple_temp_item.xml ├── simple-adapter-viewbinding ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ └── java │ └── tech │ └── thdev │ └── simpleadapter │ ├── SimpleViewBindingAdapter.kt │ ├── control │ └── SimpleViewBindingAdapterControl.kt │ ├── data │ └── SimpleViewBindingAdapterCreateItem.kt │ ├── holder │ └── SimpleViewBindingViewHolder.kt │ └── util │ └── SimpleViewBindingAdapterExtension.kt └── simple-adapter ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src └── main ├── AndroidManifest.xml └── java └── tech └── thdev └── simpleadapter ├── SimpleBaseAdapter.kt ├── data ├── SimpleBaseAdapterCreateItem.kt └── source │ ├── SimpleBaseAdapterRepository.kt │ └── SimpleBaseAdapterRepositoryImpl.kt └── holder └── SimpleBaseViewHolder.kt /.gitignore: -------------------------------------------------------------------------------- 1 | ### Android template 2 | # Built application files 3 | *.apk 4 | *.aar 5 | *.ap_ 6 | *.aab 7 | 8 | # Files for the ART/Dalvik VM 9 | *.dex 10 | 11 | # Java class files 12 | *.class 13 | 14 | # Generated files 15 | bin/ 16 | gen/ 17 | out/ 18 | # Uncomment the following line in case you need and you don't have the release build type files in your app 19 | # release/ 20 | 21 | # Gradle files 22 | .gradle/ 23 | build/ 24 | 25 | # Local configuration file (sdk path, etc) 26 | local.properties 27 | 28 | # Proguard folder generated by Eclipse 29 | proguard/ 30 | 31 | # Log Files 32 | *.log 33 | 34 | # Android Studio Navigation editor temp files 35 | .navigation/ 36 | 37 | # Android Studio captures folder 38 | captures/ 39 | 40 | # IntelliJ 41 | *.iml 42 | .idea 43 | 44 | # Keystore files 45 | # Uncomment the following lines if you do not want to check your keystore files in. 46 | #*.jks 47 | #*.keystore 48 | 49 | # External native build folder generated in Android Studio 2.2 and later 50 | .externalNativeBuild 51 | .cxx/ 52 | 53 | # Google Services (e.g. APIs or Firebase) 54 | # google-services.json 55 | 56 | # Freeline 57 | freeline.py 58 | freeline/ 59 | freeline_project_description.json 60 | 61 | # fastlane 62 | fastlane/report.xml 63 | fastlane/Preview.html 64 | fastlane/screenshots 65 | fastlane/test_output 66 | fastlane/readme.md 67 | 68 | # Version control 69 | vcs.xml 70 | 71 | # lint 72 | lint/intermediates/ 73 | lint/generated/ 74 | lint/outputs/ 75 | lint/tmp/ 76 | # lint/reports/ 77 | 78 | # ect 79 | .DS_Store -------------------------------------------------------------------------------- /CHANGELOG_SIMPLE_ADAPTER.md: -------------------------------------------------------------------------------- 1 | ### Version 1.1.0 (2020. 05. 23) 2 | - Only base SimpleAdapter 3 | - remove other interface 4 | - Remove Android Kotlin extension. 5 | 6 | ### Version 1.0.0 (2020. 04. 10) 7 | - New release -------------------------------------------------------------------------------- /CHANGELOG_SIMPLE_ADAPTER_DATA_BINDING.md: -------------------------------------------------------------------------------- 1 | ### Version 1.1.0 (2020. 05. 23) 2 | - Add DataBinding 3 | - Simple DataBinding use. 4 | ``` 5 | add kotlin kapt 6 | 7 | dataBinding { 8 | enabled = true 9 | } 10 | ``` -------------------------------------------------------------------------------- /CHANGELOG_SIMPLE_ADAPTER_VIEW_BINDING.md: -------------------------------------------------------------------------------- 1 | ### Version 1.1.0 (2020. 05. 23) 2 | - Add two bindViewHolder extension. 3 | - Experimentally added samples using reflection and ViewBinding. 4 | - There is no way to initialize ViewBinding yet and reflection call. is Deprecated ... 5 | - Bast use DataBinding. 6 | - Default on ViewBinding. 7 | ``` 8 | add kotlin kapt 9 | 10 | viewBinding { 11 | enabled = true 12 | } 13 | ``` 14 | - Remove Android Kotlin extension. 15 | 16 | ### Version 1.0.0 (2020. 04. 10) 17 | - New release -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Android Simple Adapter 2 | [![License](https://img.shields.io/hexpm/l/plug.svg)]() 3 | 4 | This is Android Simple Adapter library. 5 | Only kotlin library. 6 | 7 | - SimpleBaseAdapter : Abstract BaseAdapter 8 | - DataBinding : SimpleBaseAdapter can be used by extension library. 9 | - ViewBinding : SimpleBaseAdapter can be used by extension library. 10 | 11 | ## Library version 12 | 13 | It can be used jcenter(), as follows 14 | 15 | ### SimpleBaseAdapter - DataBinding 16 | 17 | add Android DataBinding library and dependency 18 | 19 | [ ![Download](https://api.bintray.com/packages/taehwandev/thdev.tech/simple-adapter/images/download.svg) ](https://bintray.com/taehwandev/thdev.tech/simple-adapter/_latestVersion) 20 | [ ![Download](https://api.bintray.com/packages/taehwandev/thdev.tech/simple-adapter-databinding/images/download.svg) ](https://bintray.com/taehwandev/thdev.tech/simple-adapter-databinding/_latestVersion) 21 | 22 | ``` 23 | plugins { 24 | id 'kotlin-android' 25 | id 'kotlin-kapt' 26 | } 27 | 28 | dataBinding { 29 | enabled = true 30 | } 31 | 32 | dependencies { 33 | implementation "tech.thdev.recyclerview:simple-adapter:$lastVersion" 34 | implementation "tech.thdev.recyclerview:simple-adapter-databinding:$lastVersion" 35 | } 36 | ``` 37 | 38 | #### Use DataBinding 39 | 40 | Inherit SimpleDataBindingAdapterControl and use as below. 41 | 42 | onCreateViewHolder, onCreateItems init. 43 | 44 | setItem can set data class and ViewModel in group type. 45 | 46 | ```kotlin 47 | class SimpleAdapterDataBindingSampleAdapterControl : 48 | SimpleDataBindingAdapterControl() { 49 | 50 | /** 51 | * CreateItem is parentView, viewType support. 52 | */ 53 | override fun SimpleDataBindingAdapterCreateItem.onCreateViewHolder(): SimpleDataBindingViewHolder { 54 | return when (viewType) { 55 | else -> createDataBindingHolder(R.layout.item_data_binding_text_view) 56 | } 57 | } 58 | 59 | /** 60 | * add Item and ViewModel 61 | */ 62 | override fun SimpleDataBindingAdapter.onCreateItems( 63 | item: AdapterDataBindingItemGroup, 64 | viewModel: ViewModel? 65 | ) { 66 | val startPosition = getItemSize() 67 | var newItem = 0 68 | // AddItem. 69 | item.itemList.forEach { 70 | newItem++ 71 | addItem(0, it, viewModel) 72 | } 73 | notifyItemRangeInserted(startPosition, newItem) 74 | } 75 | } 76 | 77 | data class AdapterDataBindingItemGroup( 78 | val itemList: List 79 | ) 80 | 81 | data class AdapterDataBindingItem( 82 | val index: Int 83 | ) 84 | ``` 85 | 86 | ### SimpleBaseAdapter - ViewBinding 87 | 88 | add Android viewBinding library and dependency 89 | 90 | [ ![Download](https://api.bintray.com/packages/taehwandev/thdev.tech/simple-adapter/images/download.svg) ](https://bintray.com/taehwandev/thdev.tech/simple-adapter/_latestVersion) 91 | [ ![Download](https://api.bintray.com/packages/taehwandev/thdev.tech/simple-adapter-viewbinding/images/download.svg) ](https://bintray.com/taehwandev/thdev.tech/simple-adapter-viewbinding/_latestVersion) 92 | 93 | ``` 94 | plugins { 95 | id 'kotlin-android' 96 | id 'kotlin-kapt' 97 | } 98 | 99 | viewBinding { 100 | enabled = true 101 | } 102 | 103 | dependencies { 104 | implementation "tech.thdev.recyclerview:simple-adapter:$lastVersion" 105 | implementation "tech.thdev.recyclerview:simple-adapter-viewbinding:$lastVersion" 106 | } 107 | ``` 108 | 109 | #### Use ViewBinding. 110 | 111 | Inherit SimpleViewBindingAdapterControl and use as below. 112 | 113 | onCreateViewHolder, setItem init. setItem should be used in group form. 114 | 115 | ```kotlin 116 | class SimpleAdapterControlSampleAdapterControl( 117 | private val onClick: (item: Int) -> Unit 118 | ) : SimpleViewBindingAdapterControl() { 119 | 120 | override fun SimpleViewBindingAdapterCreateItem.onCreateViewHolder(): SimpleViewBindingViewHolder<*, *> = 121 | createViewBindingHolder { item -> 122 | textView.text = "Message $item" 123 | root.setOnClickListener { 124 | onClick(item) 125 | } 126 | } 127 | 128 | override fun setItem(item: AdapterItemGroup) { 129 | item.itemList.forEach { 130 | adapter.addItem(0, it) 131 | } 132 | } 133 | } 134 | 135 | data class AdapterItemGroup( 136 | val itemList: List 137 | ) 138 | ``` 139 | 140 | !!!! caution! There are two createViewBindingHolder extensions. When using the following code, use reflection because it uses reflection. 141 | 142 | ```kotlin 143 | inline fun SimpleViewBindingAdapterCreateItem.createViewBindingHolder( 144 | noinline onBindViewHolder: BINDING.(item: ITEM) -> Unit 145 | ): SimpleViewBindingViewHolder { 146 | val method = BINDING::class.java.getDeclaredMethod( 147 | "inflate", 148 | LayoutInflater::class.java, 149 | ViewGroup::class.java, 150 | Boolean::class.java 151 | ) 152 | val newBinding = method.invoke( 153 | null, 154 | LayoutInflater.from(parent.context), 155 | parent, 156 | false 157 | ) as BINDING 158 | 159 | // ... 160 | } 161 | 162 | inline fun SimpleViewBindingAdapterCreateItem.createViewBindingHolder( 163 | viewBinding: BINDING, 164 | noinline onBindViewHolder: BINDING.(item: ITEM) -> Unit 165 | ): SimpleViewBindingViewHolder = 166 | // ... 167 | ``` 168 | 169 | ## License 170 | 171 | ``` 172 | Copyright 2020 Tae-hwan 173 | 174 | Licensed under the Apache License, Version 2.0 (the "License"); 175 | you may not use this file except in compliance with the License. 176 | You may obtain a copy of the License at 177 | 178 | http://www.apache.org/licenses/LICENSE-2.0 179 | 180 | Unless required by applicable law or agreed to in writing, software 181 | distributed under the License is distributed on an "AS IS" BASIS, 182 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 183 | See the License for the specific language governing permissions and 184 | limitations under the License. 185 | ``` 186 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'kotlin-kapt' 5 | } 6 | 7 | android { 8 | compileSdkVersion compileSdkVersionInfo 9 | buildToolsVersion buildToolsVersionInfo 10 | 11 | defaultConfig { 12 | applicationId "tech.thdev.app" 13 | minSdkVersion minSdkVerisonInfo 14 | targetSdkVersion targetSdkVersionInfo 15 | versionCode 1 16 | versionName "1.0" 17 | 18 | testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 | } 20 | 21 | buildTypes { 22 | release { 23 | minifyEnabled false 24 | proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 25 | } 26 | } 27 | compileOptions { 28 | sourceCompatibility JavaVersion.VERSION_1_8 29 | targetCompatibility JavaVersion.VERSION_1_8 30 | } 31 | kotlinOptions { 32 | jvmTarget = '1.8' 33 | } 34 | viewBinding { 35 | enabled = true 36 | } 37 | dataBinding { 38 | enabled = true 39 | } 40 | } 41 | 42 | dependencies { 43 | implementation fileTree(dir: "libs", include: ["*.jar"]) 44 | 45 | implementation kotlinLibrary 46 | implementation appcompat 47 | implementation recyclerView 48 | implementation project(path: ':simple-adapter') 49 | implementation project(path: ':simple-adapter-viewbinding') 50 | implementation project(path: ':simple-adapter-databinding') 51 | // implementation "tech.thdev.recyclerview:simple-adapter:1.1.0" 52 | // implementation "tech.thdev.recyclerview:simple-adapter-databinding:1.1.0" 53 | // implementation "tech.thdev.recyclerview:simple-adapter-viewbinding:1.1.0" 54 | 55 | implementation 'androidx.core:core-ktx:1.2.0' 56 | implementation 'com.google.android.material:material:1.1.0' 57 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3' 58 | implementation 'androidx.navigation:navigation-fragment-ktx:2.2.1' 59 | implementation 'androidx.navigation:navigation-ui-ktx:2.2.1' 60 | testImplementation 'junit:junit:4.12' 61 | androidTestImplementation 'androidx.test.ext:junit:1.1.1' 62 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' 63 | 64 | } -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 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 -------------------------------------------------------------------------------- /app/src/androidTest/java/app/thdev/ExampleInstrumentedTest.kt: -------------------------------------------------------------------------------- 1 | package app.thdev 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("app.thdev", appContext.packageName) 23 | } 24 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 12 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package app.thdev 2 | 3 | import android.os.Bundle 4 | import android.view.Menu 5 | import android.view.MenuItem 6 | import androidx.appcompat.app.AppCompatActivity 7 | import androidx.appcompat.widget.Toolbar 8 | import com.google.android.material.floatingactionbutton.FloatingActionButton 9 | import com.google.android.material.snackbar.Snackbar 10 | 11 | class MainActivity : AppCompatActivity() { 12 | 13 | override fun onCreate(savedInstanceState: Bundle?) { 14 | super.onCreate(savedInstanceState) 15 | setContentView(R.layout.main_activity) 16 | 17 | setSupportActionBar(findViewById(R.id.toolbar)) 18 | 19 | findViewById(R.id.fab).setOnClickListener { view -> 20 | Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) 21 | .setAction("Action", null).show() 22 | } 23 | } 24 | 25 | override fun onCreateOptionsMenu(menu: Menu): Boolean { 26 | // Inflate the menu; this adds items to the action bar if it is present. 27 | menuInflater.inflate(R.menu.menu_main, menu) 28 | return true 29 | } 30 | 31 | override fun onOptionsItemSelected(item: MenuItem): Boolean { 32 | // Handle action bar item clicks here. The action bar will 33 | // automatically handle clicks on the Home/Up button, so long 34 | // as you specify a parent activity in AndroidManifest.xml. 35 | return when (item.itemId) { 36 | R.id.action_settings -> true 37 | else -> super.onOptionsItemSelected(item) 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/SimpleAdapterSampleFirstFragment.kt: -------------------------------------------------------------------------------- 1 | package app.thdev 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.Toast 8 | import androidx.fragment.app.Fragment 9 | import androidx.navigation.fragment.findNavController 10 | import androidx.recyclerview.widget.LinearLayoutManager 11 | import app.thdev.databinding.AdapterSampleFragmentBinding 12 | import app.thdev.databinding.ItemTextViewBinding 13 | import tech.thdev.simpleadapter.SimpleViewBindingAdapter 14 | import tech.thdev.simpleadapter.util.createViewBindingHolder 15 | 16 | /** 17 | * A simple [Fragment] subclass as the default destination in the navigation. 18 | */ 19 | class SimpleAdapterSampleFirstFragment : Fragment() { 20 | 21 | private lateinit var binding: AdapterSampleFragmentBinding 22 | 23 | private val simpleAdapter: SimpleViewBindingAdapter by lazy { 24 | SimpleViewBindingAdapter { 25 | android.util.Log.w("TEMP", "viewType $viewType") 26 | when (viewType) { 27 | 1 -> createViewBindingHolder( 28 | ItemTextViewBinding.inflate(layoutInflater, parent, false) 29 | ) { item -> 30 | root.setOnClickListener { 31 | Toast.makeText(requireContext(), "show Index $item", Toast.LENGTH_SHORT) 32 | .show() 33 | } 34 | textView.text = "Use inflate $item" 35 | } 36 | else -> createViewBindingHolder { 37 | textView.text = "User reflection $it" 38 | } 39 | } 40 | } 41 | } 42 | 43 | override fun onCreateView( 44 | inflater: LayoutInflater, container: ViewGroup?, 45 | savedInstanceState: Bundle? 46 | ): View? { 47 | // Inflate the layout for this fragment 48 | return AdapterSampleFragmentBinding.inflate(inflater, container, false).also { 49 | binding = it 50 | }.root 51 | } 52 | 53 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 54 | super.onViewCreated(view, savedInstanceState) 55 | 56 | binding.buttonFirst.setOnClickListener { 57 | findNavController().navigate(R.id.action_AdapterSample_to_AdapterControlSample) 58 | } 59 | 60 | binding.recyclerView.run { 61 | this.adapter = simpleAdapter 62 | this.layoutManager = LinearLayoutManager(requireContext()) 63 | } 64 | (0..100).forEach { 65 | simpleAdapter.addItem(it % 2, it) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/ui/adapter_control/SimpleAdapterControlSampleAdapterControl.kt: -------------------------------------------------------------------------------- 1 | package app.thdev.ui.adapter_control 2 | 3 | import app.thdev.databinding.ItemTextViewBinding 4 | import tech.thdev.simpleadapter.control.SimpleViewBindingAdapterControl 5 | import tech.thdev.simpleadapter.data.SimpleViewBindingAdapterCreateItem 6 | import tech.thdev.simpleadapter.holder.SimpleViewBindingViewHolder 7 | import tech.thdev.simpleadapter.util.createViewBindingHolder 8 | 9 | class SimpleAdapterControlSampleAdapterControl( 10 | private val onClick: (item: Int) -> Unit 11 | ) : SimpleViewBindingAdapterControl() { 12 | 13 | override fun SimpleViewBindingAdapterCreateItem.onCreateViewHolder(): SimpleViewBindingViewHolder<*, *> = 14 | createViewBindingHolder { item -> 15 | textView.text = "Message $item" 16 | root.setOnClickListener { 17 | onClick(item) 18 | } 19 | } 20 | 21 | override fun setItem(item: AdapterItemGroup) { 22 | item.itemList.forEach { 23 | adapter.addItem(0, it) 24 | } 25 | } 26 | } 27 | 28 | data class AdapterItemGroup( 29 | val itemList: List 30 | ) -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/ui/adapter_control/SimpleAdapterControlSampleFragment.kt: -------------------------------------------------------------------------------- 1 | package app.thdev.ui.adapter_control 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.Toast 8 | import androidx.fragment.app.Fragment 9 | import androidx.navigation.fragment.findNavController 10 | import androidx.recyclerview.widget.LinearLayoutManager 11 | import app.thdev.R 12 | import app.thdev.databinding.AdapterControlSampleFragmentBinding 13 | 14 | /** 15 | * A simple [Fragment] subclass as the second destination in the navigation. 16 | */ 17 | class SimpleAdapterControlSampleFragment : Fragment() { 18 | 19 | private val adapterControl: SimpleAdapterControlSampleAdapterControl by lazy { 20 | SimpleAdapterControlSampleAdapterControl { 21 | Toast.makeText(requireContext(), "message $it", Toast.LENGTH_SHORT).show() 22 | } 23 | } 24 | 25 | private lateinit var binding: AdapterControlSampleFragmentBinding 26 | 27 | override fun onCreateView( 28 | inflater: LayoutInflater, container: ViewGroup?, 29 | savedInstanceState: Bundle? 30 | ): View? { 31 | return AdapterControlSampleFragmentBinding.inflate(inflater, container, false).also { 32 | binding = it 33 | }.root 34 | } 35 | 36 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 37 | super.onViewCreated(view, savedInstanceState) 38 | 39 | binding.buttonPrev.setOnClickListener { 40 | findNavController().navigate(R.id.action_AdapterControlSample_to_AdapterSample) 41 | } 42 | 43 | binding.buttonNext.setOnClickListener { 44 | findNavController().navigate(R.id.action_AdapterControlSample_to_DataBindingSample) 45 | } 46 | 47 | binding.recyclerView.run { 48 | adapter = adapterControl.adapter 49 | layoutManager = LinearLayoutManager(requireContext()) 50 | } 51 | adapterControl.setItem( 52 | AdapterItemGroup(itemList = (1..100).toList()) 53 | ) 54 | } 55 | } -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/ui/databinding/SimpleAdapterDataBindingSampleAdapterControl.kt: -------------------------------------------------------------------------------- 1 | package app.thdev.ui.databinding 2 | 3 | import androidx.lifecycle.ViewModel 4 | import app.thdev.R 5 | import tech.thdev.simpleadapter.SimpleDataBindingAdapter 6 | import tech.thdev.simpleadapter.control.SimpleDataBindingAdapterControl 7 | import tech.thdev.simpleadapter.data.SimpleDataBindingAdapterCreateItem 8 | import tech.thdev.simpleadapter.holder.SimpleDataBindingViewHolder 9 | import tech.thdev.simpleadapter.util.createDataBindingHolder 10 | 11 | class SimpleAdapterDataBindingSampleAdapterControl : 12 | SimpleDataBindingAdapterControl() { 13 | 14 | /** 15 | * CreateItem is parentView, viewType support. 16 | */ 17 | override fun SimpleDataBindingAdapterCreateItem.onCreateViewHolder(): SimpleDataBindingViewHolder { 18 | return when (viewType) { 19 | else -> createDataBindingHolder(R.layout.item_data_binding_text_view) 20 | } 21 | } 22 | 23 | 24 | /** 25 | * add Item and ViewModel 26 | */ 27 | override fun SimpleDataBindingAdapter.onCreateItems( 28 | item: AdapterDataBindingItemGroup, 29 | viewModel: ViewModel? 30 | ) { 31 | val startPosition = getItemSize() 32 | var newItem = 0 33 | // AddItem. 34 | item.itemList.forEach { 35 | newItem++ 36 | addItem(0, it, viewModel) 37 | } 38 | notifyItemRangeInserted(startPosition, newItem) 39 | } 40 | } 41 | 42 | data class AdapterDataBindingItemGroup( 43 | val itemList: List 44 | ) 45 | 46 | data class AdapterDataBindingItem( 47 | val index: Int 48 | ) -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/ui/databinding/SimpleAdapterDataBindingSampleFragment.kt: -------------------------------------------------------------------------------- 1 | package app.thdev.ui.databinding 2 | 3 | import android.os.Bundle 4 | import android.view.LayoutInflater 5 | import android.view.View 6 | import android.view.ViewGroup 7 | import android.widget.Toast 8 | import androidx.fragment.app.Fragment 9 | import androidx.fragment.app.viewModels 10 | import androidx.lifecycle.Observer 11 | import androidx.lifecycle.ViewModel 12 | import androidx.lifecycle.ViewModelProvider 13 | import androidx.navigation.fragment.findNavController 14 | import app.thdev.R 15 | import app.thdev.databinding.AdapterDataBindingSampleFragmentBinding 16 | 17 | /** 18 | * A simple [Fragment] subclass as the second destination in the navigation. 19 | */ 20 | class SimpleAdapterDataBindingSampleFragment : Fragment() { 21 | 22 | private val adapterControl by lazy { 23 | SimpleAdapterDataBindingSampleAdapterControl() 24 | } 25 | 26 | private lateinit var binding: AdapterDataBindingSampleFragmentBinding 27 | 28 | private val viewModel by viewModels { 29 | object : ViewModelProvider.Factory { 30 | override fun create(modelClass: Class): T = 31 | SimpleAdapterDataBindingSampleViewModel( 32 | adapterControl 33 | ) as T 34 | } 35 | } 36 | 37 | override fun onCreateView( 38 | inflater: LayoutInflater, container: ViewGroup?, 39 | savedInstanceState: Bundle? 40 | ): View? { 41 | return AdapterDataBindingSampleFragmentBinding.inflate(inflater, container, false).also { 42 | binding = it 43 | }.root 44 | } 45 | 46 | override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 47 | super.onViewCreated(view, savedInstanceState) 48 | 49 | binding.buttonPrev.setOnClickListener { 50 | findNavController().navigate(R.id.action_AdapterDataBindingSample_to_AdapterControlSample) 51 | } 52 | 53 | binding.recyclerView.adapter = adapterControl.adapter 54 | 55 | viewModel.showToast.observe(viewLifecycleOwner, Observer { 56 | Toast.makeText(requireContext(), "Show message $it", Toast.LENGTH_SHORT).show() 57 | }) 58 | viewModel.initItem() 59 | } 60 | } -------------------------------------------------------------------------------- /app/src/main/java/app/thdev/ui/databinding/SimpleAdapterDataBindingSampleViewModel.kt: -------------------------------------------------------------------------------- 1 | package app.thdev.ui.databinding 2 | 3 | import androidx.lifecycle.LiveData 4 | import androidx.lifecycle.MutableLiveData 5 | import androidx.lifecycle.ViewModel 6 | 7 | class SimpleAdapterDataBindingSampleViewModel( 8 | private val adapterControl: SimpleAdapterDataBindingSampleAdapterControl 9 | ) : ViewModel() { 10 | 11 | private val _showToast = MutableLiveData() 12 | val showToast: LiveData get() = _showToast 13 | 14 | fun initItem() { 15 | adapterControl.setItems( 16 | AdapterDataBindingItemGroup( 17 | (1..150).map { 18 | AdapterDataBindingItem(it) 19 | }.toList() 20 | ), 21 | this@SimpleAdapterDataBindingSampleViewModel 22 | ) 23 | } 24 | 25 | fun onClickItem(item: AdapterDataBindingItem) { 26 | _showToast.value = item.index 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 9 | 15 | 18 | 21 | 22 | 23 | 24 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/layout/adapter_control_sample_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 19 | 20 |