diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 000000000..236922881 --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +--- +BUNDLE_PATH: "vendor/bundle" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index cb563fba8..fa3967032 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -55,7 +55,7 @@ jobs: if: github.event_name == 'pull_request' uses: ruby/setup-ruby@v1 with: - ruby-version: '2.6.3' + ruby-version: '3.0' bundler-cache: true - name: Run Danger diff --git a/.gitignore b/.gitignore index b150f9953..e8ae59e15 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ proguard/ !.idea/dictionaries *.DS_STORE +/vendor/* diff --git a/Gemfile.lock b/Gemfile.lock index 1e841c989..8bf8da739 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,11 +1,11 @@ GEM remote: https://rubygems.org/ specs: - addressable (2.8.0) - public_suffix (>= 2.0.2, < 5.0) + addressable (2.8.1) + public_suffix (>= 2.0.2, < 6.0) ansi (1.5.0) ast (2.4.2) - claide (1.0.3) + claide (1.1.0) claide-plugins (0.9.2) cork nap @@ -13,7 +13,7 @@ GEM colored2 (3.1.2) cork (0.3.0) colored2 (~> 3.1) - danger (8.2.3) + danger (9.0.0) claide (~> 1.0) claide-plugins (>= 0.9.2) colored2 (~> 3.1) @@ -24,51 +24,70 @@ GEM kramdown (~> 2.3) kramdown-parser-gfm (~> 1.0) no_proxy_fix - octokit (~> 4.7) + octokit (~> 5.0) terminal-table (>= 1, < 4) - danger-android_lint (0.0.8) + danger-android_lint (0.0.11) danger-plugin-api (~> 1.0) oga danger-kotlin_detekt (0.0.3) danger-plugin-api (~> 1.0) danger-plugin-api (1.0.0) danger (> 2.0) - faraday (1.3.0) + faraday (1.10.2) + faraday-em_http (~> 1.0) + faraday-em_synchrony (~> 1.0) + faraday-excon (~> 1.1) + faraday-httpclient (~> 1.0) + faraday-multipart (~> 1.0) faraday-net_http (~> 1.0) - multipart-post (>= 1.2, < 3) - ruby2_keywords - faraday-http-cache (2.2.0) + faraday-net_http_persistent (~> 1.0) + faraday-patron (~> 1.0) + faraday-rack (~> 1.0) + faraday-retry (~> 1.0) + ruby2_keywords (>= 0.0.4) + faraday-em_http (1.0.0) + faraday-em_synchrony (1.0.0) + faraday-excon (1.1.0) + faraday-http-cache (2.4.1) faraday (>= 0.8) + faraday-httpclient (1.0.1) + faraday-multipart (1.0.4) + multipart-post (~> 2) faraday-net_http (1.0.1) - git (1.8.1) + faraday-net_http_persistent (1.2.0) + faraday-patron (1.0.0) + faraday-rack (1.0.0) + faraday-retry (1.0.3) + git (1.12.0) + addressable (~> 2.8) rchardet (~> 1.8) - kramdown (2.3.1) + kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) kramdown (~> 2.0) - multipart-post (2.1.1) + multipart-post (2.2.3) nap (1.1.0) no_proxy_fix (0.1.2) - octokit (4.20.0) - faraday (>= 0.9) - sawyer (~> 0.8.0, >= 0.5.3) - oga (3.3) + octokit (5.6.1) + faraday (>= 1, < 3) + sawyer (~> 0.9) + oga (3.4) ast ruby-ll (~> 2.1) open4 (1.3.4) - public_suffix (4.0.6) + public_suffix (5.0.0) rchardet (1.8.0) rexml (3.2.5) ruby-ll (2.1.2) ansi ast - ruby2_keywords (0.0.4) - sawyer (0.8.2) + ruby2_keywords (0.0.5) + sawyer (0.9.2) addressable (>= 2.3.5) - faraday (> 0.8, < 2.0) - terminal-table (3.0.0) - unicode-display_width (~> 1.1, >= 1.1.1) - unicode-display_width (1.7.0) + faraday (>= 0.17.3, < 3) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) + unicode-display_width (2.3.0) PLATFORMS ruby @@ -79,4 +98,4 @@ DEPENDENCIES danger-kotlin_detekt BUNDLED WITH - 2.1.4 + 2.3.22 diff --git a/README.md b/README.md index c5ea8f3b6..6d68aee5d 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ It's blazing fast, minimizing the code you need to write, and is easy to extend. ## Latest releases 🛠 -- Kotlin | [v5.6.0](https://github.com/mikepenz/FastAdapter/tree/v5.6.0) +- Kotlin | [v5.7.0](https://github.com/mikepenz/FastAdapter/tree/v5.7.0) - [Deprecated] Java && AndroidX | [v3.3.1](https://github.com/mikepenz/FastAdapter/tree/v3.3.1) - [Deprecated] Java && AppCompat | [v3.2.9](https://github.com/mikepenz/FastAdapter/tree/v3.2.9) diff --git a/app/build.gradle b/app/build.gradle index e5985a22b..09fd69570 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -79,12 +79,6 @@ repositories { url "https://oss.sonatype.org/content/repositories/snapshots/" content { includeGroup "com.mikepenz.thirdparty" } } - jcenter() { - content { - includeGroup "com.mopub" - includeGroup "com.mopub.volley" - } - } } dependencies { @@ -148,21 +142,11 @@ dependencies { //used to load the images in the ImageListSample //https://github.com/coil-kt/coil - implementation 'io.coil-kt:coil:1.4.0' + implementation 'io.coil-kt:coil:2.2.1' //Used to provide the drag selection like google photos implementation 'com.github.MFlisar:DragSelectRecyclerView:0.3' - //mopub sdk to showcase the usage of the mopub adapter - implementation('com.mopub:mopub-sdk:4.11.0@aar') { - transitive = true - exclude group: "com.google.android.exoplayer" - } - implementation('com.mopub:mopub-sdk-native-static:4.11.0@aar') { - transitive = true - exclude group: "com.google.android.exoplayer" - } - //Used to async operations implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'io.reactivex.rxjava2:rxjava:2.2.21' @@ -187,10 +171,9 @@ dependencies { buildscript { repositories { mavenCentral() - jcenter() { content { includeGroup "io.realm" } } } dependencies { - classpath "io.realm:realm-gradle-plugin:10.8.1" + classpath "io.realm:realm-gradle-plugin:10.12.0" } } \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 57191a716..d858cf850 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,95 +1,110 @@ + xmlns:tools="http://schemas.android.com/tools" + package="com.mikepenz.fastadapter.app"> - + + android:name="com.mikepenz.fastadapter.app.CustomApplication" + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:networkSecurityConfig="@xml/network_security_config" + android:roundIcon="@mipmap/ic_launcher_round" + android:theme="@style/SampleApp.DayNight" + tools:ignore="GoogleAppIndexingWarning"> + android:name="org.apache.http.legacy" + android:required="false"/> - + - - + + + android:name="com.mikepenz.fastadapter.app.PagedActivity" + android:label="@string/sample_paged_list" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.SimpleItemListActivity" + android:label="@string/sample_simple_item_list" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.SwipeListActivity" + android:label="@string/sample_swipe_list" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.SwipeDrawerListActivity" + android:label="@string/sample_swipe_drawer_list" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.ImageListActivity" + android:label="@string/sample_image_list" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.MultiselectSampleActivity" + android:label="@string/sample_multi_select" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.ExpandableSampleActivity" + android:label="@string/sample_collapsible" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.ExpandableMultiselectDeleteSampleActivity" + android:label="@string/sample_collapsible_multi_select_delete" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.StickyHeaderSampleActivity" + android:label="@string/sample_sticky_header" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.AdvancedSampleActivity" + android:label="@string/sample_advanced" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.IconGridActivity" + android:label="@string/sample_icon_grid" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.ModelItemActivity" + android:label="@string/sample_model_item" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.MultiTypeModelItemActivity" + android:label="@string/sample_multi_model_item" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.CheckBoxSampleActivity" + android:label="@string/sample_checkbox_item" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.RadioButtonSampleActivity" + android:label="@string/sample_radiobutton_item" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.EndlessScrollListActivity" + android:label="@string/sample_endless_scroll_item" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.SortActivity" + android:label="@string/sample_sort" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.RealmActivity" + android:label="@string/sample_realm_list" + android:exported="false"/> + android:name="com.mikepenz.fastadapter.app.DiffUtilActivity" + android:label="@string/sample_diff_util" + android:exported="false"/> - - + android:name="com.mikepenz.fastadapter.app.DragAndDropActivity" + android:label="Drag & Drop Sample" + android:exported="false"/> diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/MopubAdsActivity.kt b/app/src/main/java/com/mikepenz/fastadapter/app/MopubAdsActivity.kt deleted file mode 100644 index 392e20948..000000000 --- a/app/src/main/java/com/mikepenz/fastadapter/app/MopubAdsActivity.kt +++ /dev/null @@ -1,82 +0,0 @@ -package com.mikepenz.fastadapter.app - -import android.os.Bundle -import android.view.MenuItem -import android.widget.Toast -import androidx.appcompat.app.AppCompatActivity -import androidx.recyclerview.widget.GridLayoutManager -import com.mikepenz.fastadapter.app.adapters.MopubFastItemAdapter -import com.mikepenz.fastadapter.app.databinding.ActivitySampleBinding -import com.mikepenz.fastadapter.app.items.LetterItem -import com.mopub.nativeads.MoPubRecyclerAdapter -import com.mopub.nativeads.MoPubStaticNativeAdRenderer -import com.mopub.nativeads.ViewBinder - -class MopubAdsActivity : AppCompatActivity() { - private lateinit var binding: ActivitySampleBinding - - private lateinit var adapter: MopubFastItemAdapter - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivitySampleBinding.inflate(layoutInflater).also { - setContentView(it.root) - } - - // Handle Toolbar - setSupportActionBar(binding.toolbar) - - adapter = MopubFastItemAdapter() - adapter.onClickListener = { _, _, item, position -> - Toast.makeText(this, "Item pressed " + item.letter + " at position " + position, Toast.LENGTH_SHORT).show() - false - } - - for (i in 65..90) { - adapter.add(LetterItem(i.toChar().toString())) - } - - val viewBinder = ViewBinder.Builder(R.layout.native_ad_item) - .iconImageId(R.id.native_icon_image) - .titleId(R.id.native_title) - .textId(R.id.native_text) - .callToActionId(R.id.native_cta) - .privacyInformationIconImageId(R.id.native_privacy_information_icon_image) - .build() - - val adapter = MoPubRecyclerAdapter(this, adapter) - adapter.registerAdRenderer(MoPubStaticNativeAdRenderer(viewBinder)) - adapter.loadAds("76a3fefaced247959582d2d2df6f4757") - - binding.rv.layoutManager = GridLayoutManager(this, 1) - binding.rv.adapter = adapter - - //provide the mopub adapter - this.adapter.withMoPubAdAdapter(adapter) - - //restore selections (this has to be done after the items were added - this.adapter.withSavedInstanceState(savedInstanceState) - - //set the back arrow in the toolbar - supportActionBar?.setDisplayHomeAsUpEnabled(true) - supportActionBar?.setHomeButtonEnabled(false) - } - - override fun onSaveInstanceState(_outState: Bundle) { - var outState = _outState - //add the values which need to be saved from the adapter to the bundle - outState = adapter.saveInstanceState(outState) - super.onSaveInstanceState(outState) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - //handle the click on the back arrow click - return when (item.itemId) { - android.R.id.home -> { - onBackPressed() - true - } - else -> super.onOptionsItemSelected(item) - } - } -} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.kt b/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.kt index 539a751b5..bf0f16017 100755 --- a/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.kt +++ b/app/src/main/java/com/mikepenz/fastadapter/app/SampleActivity.kt @@ -67,30 +67,49 @@ class SampleActivity : AppCompatActivity() { //Create the drawer binding.slider.apply { addItems( - PrimaryDrawerItem().withName(R.string.sample_icon_grid).withDescription(R.string.sample_icon_grid_descr).withSelectable(false).withIdentifier(8).withIcon(MaterialDesignIconic.Icon.gmi_grid), - PrimaryDrawerItem().withName(R.string.sample_simple_item_list).withDescription(R.string.sample_simple_item_list_descr).withSelectable(false).withIdentifier(6).withIcon(MaterialDesignIconic.Icon.gmi_format_align_justify), - PrimaryDrawerItem().withName(R.string.sample_image_list).withDescription(R.string.sample_image_list_descr).withSelectable(false).withIdentifier(5).withIcon(MaterialDesignIconic.Icon.gmi_wallpaper), - PrimaryDrawerItem().withName(R.string.sample_multi_select).withDescription(R.string.sample_multi_select_descr).withSelectable(false).withIdentifier(1).withIcon(MaterialDesignIconic.Icon.gmi_select_all), - PrimaryDrawerItem().withName(R.string.sample_collapsible).withDescription(R.string.sample_collapsible_descr).withSelectable(false).withIdentifier(2).withIcon(MaterialDesignIconic.Icon.gmi_check_all), - PrimaryDrawerItem().withName(R.string.sample_sticky_header).withDescription(R.string.sample_sticky_header_descr).withSelectable(false).withIdentifier(3).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), - PrimaryDrawerItem().withName(R.string.sample_paged_list).withDescription(R.string.sample_paged_list_descr).withSelectable(false).withIdentifier(21).withIcon(MaterialDesignIconic.Icon.gmi_pages), - PrimaryDrawerItem().withName(R.string.sample_advanced).withDescription(R.string.sample_advanced_descr).withSelectable(false).withIdentifier(4).withIcon(MaterialDesignIconic.Icon.gmi_coffee), - PrimaryDrawerItem().withName(R.string.sample_model_item).withDescription(R.string.sample_model_item_descr).withSelectable(false).withIdentifier(7).withIcon(MaterialDesignIconic.Icon.gmi_font), - PrimaryDrawerItem().withName(R.string.sample_multi_model_item).withDescription(R.string.sample_multi_model_item_descr).withSelectable(false).withIdentifier(9).withIcon(MaterialDesignIconic.Icon.gmi_format_list_numbered), - PrimaryDrawerItem().withName(R.string.sample_checkbox_item).withDescription(R.string.sample_checkbox_item_descr).withSelectable(false).withIdentifier(10).withIcon(CommunityMaterial.Icon.cmd_checkbox_marked), - PrimaryDrawerItem().withName(R.string.sample_radiobutton_item).withDescription(R.string.sample_radiobutton_item_descr).withSelectable(false).withIdentifier(11).withIcon(CommunityMaterial.Icon3.cmd_radiobox_marked), - PrimaryDrawerItem().withName(R.string.sample_swipe_list).withDescription(R.string.sample_swipe_list_descr).withSelectable(false).withIdentifier(12).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), - PrimaryDrawerItem().withName(R.string.sample_swipe_drawer_list).withDescription(R.string.sample_swipe_drawer_list_descr).withSelectable(false).withIdentifier(13).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), - PrimaryDrawerItem().withName(R.string.sample_endless_scroll_list).withDescription(R.string.sample_endless_scroll_list_descr).withSelectable(false).withIdentifier(14).withIcon(MaterialDesignIconic.Icon.gmi_long_arrow_down), - PrimaryDrawerItem().withName(R.string.sample_sort).withDescription(R.string.sample_sort_descr).withSelectable(false).withIdentifier(15).withIcon(MaterialDesignIconic.Icon.gmi_sort_by_alpha), - PrimaryDrawerItem().withName(R.string.sample_mopub).withDescription(R.string.sample_mopub_descr).withSelectable(false).withIdentifier(16).withIcon(MaterialDesignIconic.Icon.gmi_accounts_list), - PrimaryDrawerItem().withName(R.string.sample_realm_list).withDescription(R.string.sample_realm_list_descr).withSelectable(false).withIdentifier(17).withIcon(MaterialDesignIconic.Icon.gmi_format_color_text), - PrimaryDrawerItem().withName(R.string.sample_collapsible_multi_select_delete).withDescription(R.string.sample_collapsible_multi_select_delete_descr).withSelectable(false).withIdentifier(18).withIcon(MaterialDesignIconic.Icon.gmi_check_all), - PrimaryDrawerItem().withName(R.string.sample_sticky_header_mopub).withDescription(R.string.sample_sticky_header_mopub_descr).withSelectable(false).withIdentifier(19).withIcon(MaterialDesignIconic.Icon.gmi_accounts_list), - PrimaryDrawerItem().withName(R.string.sample_diff_util).withDescription(R.string.sample_diff_util_descr).withSelectable(false).withIdentifier(20).withIcon(MaterialDesignIconic.Icon.gmi_refresh), - PrimaryDrawerItem().withName(R.string.sample_drag_and_drop).withDescription(R.string.sample_drag_and_drop_descr).withSelectable(false).withIdentifier(22).withIcon(MaterialDesignIconic.Icon.gmi_reorder), - DividerDrawerItem(), - PrimaryDrawerItem().withName(R.string.open_source).withSelectable(false).withIdentifier(100).withIcon(MaterialDesignIconic.Icon.gmi_github) + PrimaryDrawerItem().withName(R.string.sample_icon_grid).withDescription(R.string.sample_icon_grid_descr).withSelectable(false).withIdentifier(8) + .withIcon(MaterialDesignIconic.Icon.gmi_grid), + PrimaryDrawerItem().withName(R.string.sample_simple_item_list).withDescription(R.string.sample_simple_item_list_descr).withSelectable(false) + .withIdentifier(6).withIcon(MaterialDesignIconic.Icon.gmi_format_align_justify), + PrimaryDrawerItem().withName(R.string.sample_image_list).withDescription(R.string.sample_image_list_descr).withSelectable(false) + .withIdentifier(5).withIcon(MaterialDesignIconic.Icon.gmi_wallpaper), + PrimaryDrawerItem().withName(R.string.sample_multi_select).withDescription(R.string.sample_multi_select_descr).withSelectable(false) + .withIdentifier(1).withIcon(MaterialDesignIconic.Icon.gmi_select_all), + PrimaryDrawerItem().withName(R.string.sample_collapsible).withDescription(R.string.sample_collapsible_descr).withSelectable(false) + .withIdentifier(2).withIcon(MaterialDesignIconic.Icon.gmi_check_all), + PrimaryDrawerItem().withName(R.string.sample_sticky_header).withDescription(R.string.sample_sticky_header_descr).withSelectable(false) + .withIdentifier(3).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), + PrimaryDrawerItem().withName(R.string.sample_paged_list).withDescription(R.string.sample_paged_list_descr).withSelectable(false) + .withIdentifier(21).withIcon(MaterialDesignIconic.Icon.gmi_pages), + PrimaryDrawerItem().withName(R.string.sample_advanced).withDescription(R.string.sample_advanced_descr).withSelectable(false).withIdentifier(4) + .withIcon(MaterialDesignIconic.Icon.gmi_coffee), + PrimaryDrawerItem().withName(R.string.sample_model_item).withDescription(R.string.sample_model_item_descr).withSelectable(false) + .withIdentifier(7).withIcon(MaterialDesignIconic.Icon.gmi_font), + PrimaryDrawerItem().withName(R.string.sample_multi_model_item).withDescription(R.string.sample_multi_model_item_descr).withSelectable(false) + .withIdentifier(9).withIcon(MaterialDesignIconic.Icon.gmi_format_list_numbered), + PrimaryDrawerItem().withName(R.string.sample_checkbox_item).withDescription(R.string.sample_checkbox_item_descr).withSelectable(false) + .withIdentifier(10).withIcon(CommunityMaterial.Icon.cmd_checkbox_marked), + PrimaryDrawerItem().withName(R.string.sample_radiobutton_item).withDescription(R.string.sample_radiobutton_item_descr).withSelectable(false) + .withIdentifier(11).withIcon(CommunityMaterial.Icon3.cmd_radiobox_marked), + PrimaryDrawerItem().withName(R.string.sample_swipe_list).withDescription(R.string.sample_swipe_list_descr).withSelectable(false) + .withIdentifier(12).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), + PrimaryDrawerItem().withName(R.string.sample_swipe_drawer_list).withDescription(R.string.sample_swipe_drawer_list_descr).withSelectable(false) + .withIdentifier(13).withIcon(MaterialDesignIconic.Icon.gmi_format_align_left), + PrimaryDrawerItem().withName(R.string.sample_endless_scroll_list).withDescription(R.string.sample_endless_scroll_list_descr) + .withSelectable(false).withIdentifier(14).withIcon(MaterialDesignIconic.Icon.gmi_long_arrow_down), + PrimaryDrawerItem().withName(R.string.sample_sort).withDescription(R.string.sample_sort_descr).withSelectable(false).withIdentifier(15) + .withIcon(MaterialDesignIconic.Icon.gmi_sort_by_alpha), + PrimaryDrawerItem().withName(R.string.sample_realm_list).withDescription(R.string.sample_realm_list_descr).withSelectable(false) + .withIdentifier(17).withIcon(MaterialDesignIconic.Icon.gmi_format_color_text), + PrimaryDrawerItem().withName(R.string.sample_collapsible_multi_select_delete) + .withDescription(R.string.sample_collapsible_multi_select_delete_descr).withSelectable(false).withIdentifier(18) + .withIcon(MaterialDesignIconic.Icon.gmi_check_all), + PrimaryDrawerItem().withName(R.string.sample_diff_util).withDescription(R.string.sample_diff_util_descr).withSelectable(false) + .withIdentifier(20).withIcon(MaterialDesignIconic.Icon.gmi_refresh), + PrimaryDrawerItem().withName(R.string.sample_drag_and_drop).withDescription(R.string.sample_drag_and_drop_descr).withSelectable(false) + .withIdentifier(22).withIcon(MaterialDesignIconic.Icon.gmi_reorder), + DividerDrawerItem(), + PrimaryDrawerItem().withName(R.string.open_source).withSelectable(false).withIdentifier(100).withIcon(MaterialDesignIconic.Icon.gmi_github) ) onDrawerItemClickListener = { v, drawerItem, position -> val intent: Intent? = when (drawerItem.identifier) { @@ -109,20 +128,19 @@ class SampleActivity : AppCompatActivity() { 13L -> Intent(this@SampleActivity, SwipeDrawerListActivity::class.java) 14L -> Intent(this@SampleActivity, EndlessScrollListActivity::class.java) 15L -> Intent(this@SampleActivity, SortActivity::class.java) - 16L -> Intent(this@SampleActivity, MopubAdsActivity::class.java) 17L -> Intent(this@SampleActivity, RealmActivity::class.java) 18L -> Intent(this@SampleActivity, ExpandableMultiselectDeleteSampleActivity::class.java) - 19L -> Intent(this@SampleActivity, StickyHeaderMopubAdsActivity::class.java) 20L -> Intent(this@SampleActivity, DiffUtilActivity::class.java) 21L -> Intent(this@SampleActivity, PagedActivity::class.java) 22L -> Intent(this@SampleActivity, DragAndDropActivity::class.java) 100L -> LibsBuilder() - .withActivityTitle(getString(R.string.open_source)) - .withAboutIconShown(true) - .withVersionShown(true) - .withAboutVersionShown(true) - .withEdgeToEdge(true) - .intent(this@SampleActivity) + .withActivityTitle(getString(R.string.open_source)) + .withAboutIconShown(true) + .withVersionShown(true) + .withAboutVersionShown(true) + .withEdgeToEdge(true) + .intent(this@SampleActivity) + else -> throw UnsupportedOperationException() } if (intent != null) { @@ -180,8 +198,10 @@ class SampleActivity : AppCompatActivity() { inflater.inflate(R.menu.menu, menu) menu.findItem(R.id.item_add).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_plus_square).apply { colorInt = Color.BLACK; actionBar() } menu.findItem(R.id.item_delete).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_minus_square).apply { colorInt = Color.BLACK; actionBar() } - menu.findItem(R.id.item_change).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_settings_square).apply { colorInt = Color.BLACK; actionBar() } - menu.findItem(R.id.item_move).icon = IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_format_valign_bottom).apply { colorInt = Color.BLACK; actionBar() } + menu.findItem(R.id.item_change).icon = + IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_settings_square).apply { colorInt = Color.BLACK; actionBar() } + menu.findItem(R.id.item_move).icon = + IconicsDrawable(this, MaterialDesignIconic.Icon.gmi_format_valign_bottom).apply { colorInt = Color.BLACK; actionBar() } return true } @@ -204,6 +224,7 @@ class SampleActivity : AppCompatActivity() { mItemAdapter.add(firstVisiblePosition + 1, ImageDummyData.dummyItem) return true } + R.id.item_change -> { for (pos in selectExtension.selections) { val i = mItemAdapter.getAdapterItem(pos) @@ -213,6 +234,7 @@ class SampleActivity : AppCompatActivity() { } return true } + R.id.item_move -> { val items = mItemAdapter.adapterItems if (items.size > firstVisiblePosition + 3) { @@ -220,14 +242,17 @@ class SampleActivity : AppCompatActivity() { } return true } + R.id.item_delete -> { selectExtension.deleteAllSelectedItems() return true } + android.R.id.home -> { onBackPressed() return true } + else -> return super.onOptionsItemSelected(item) } } diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/StickyHeaderMopubAdsActivity.kt b/app/src/main/java/com/mikepenz/fastadapter/app/StickyHeaderMopubAdsActivity.kt deleted file mode 100644 index 9919a273e..000000000 --- a/app/src/main/java/com/mikepenz/fastadapter/app/StickyHeaderMopubAdsActivity.kt +++ /dev/null @@ -1,111 +0,0 @@ -package com.mikepenz.fastadapter.app - -import android.os.Bundle -import android.view.MenuItem -import androidx.appcompat.app.AppCompatActivity -import androidx.recyclerview.widget.DefaultItemAnimator -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.mikepenz.fastadapter.adapters.ItemAdapter -import com.mikepenz.fastadapter.app.adapters.MopubFastItemAdapter -import com.mikepenz.fastadapter.app.adapters.StickyHeaderAdapter -import com.mikepenz.fastadapter.app.databinding.ActivitySampleBinding -import com.mikepenz.fastadapter.app.helpers.CustomStickyRecyclerHeadersDecoration -import com.mikepenz.fastadapter.app.items.SimpleItem -import com.mopub.nativeads.MoPubRecyclerAdapter -import com.mopub.nativeads.MoPubStaticNativeAdRenderer -import com.mopub.nativeads.ViewBinder -import java.util.* - -/** - * Created by Gagan on 5/3/2017. - */ - -class StickyHeaderMopubAdsActivity : AppCompatActivity() { - private lateinit var binding: ActivitySampleBinding - - private lateinit var mAdapter: MopubFastItemAdapter - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - binding = ActivitySampleBinding.inflate(layoutInflater).also { - setContentView(it.root) - } - - // Handle Toolbar - setSupportActionBar(binding.toolbar) - - val stickyHeaderAdapter = StickyHeaderAdapter() - val headerAdapter = ItemAdapter() - mAdapter = MopubFastItemAdapter() - mAdapter.addAdapter(0, headerAdapter) - - val viewBinder = ViewBinder.Builder(R.layout.native_ad_item) - .iconImageId(R.id.native_icon_image) - .titleId(R.id.native_title) - .textId(R.id.native_text) - .callToActionId(R.id.native_cta) - .privacyInformationIconImageId(R.id.native_privacy_information_icon_image) - .build() - - val adapter = MoPubRecyclerAdapter(this, stickyHeaderAdapter.wrap(mAdapter)) - adapter.registerAdRenderer(MoPubStaticNativeAdRenderer(viewBinder)) - adapter.loadAds("76a3fefaced247959582d2d2df6f4757") - - binding.rv.layoutManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false) - //provide the mopub adapter - mAdapter.withMoPubAdAdapter(adapter) - binding.rv.itemAnimator = DefaultItemAnimator() - binding.rv.adapter = adapter - - //Note: Only major change to prevent Mopub Ads from pushing items out of the sections, - //other than CustomHeaderViewCache, CustomStickyRecyclerHeadersDecoration, and HeaderPositionCalculator - val decoration = CustomStickyRecyclerHeadersDecoration(stickyHeaderAdapter, adapter) - binding.rv.addItemDecoration(decoration) - - //fill with some sample data - val items = ArrayList() - for (i in 1..100) { - val simpleItem = SimpleItem().withName("Test $i").withHeader(headers[i / 5]) - simpleItem.identifier = (100 + i).toLong() - items.add(simpleItem) - } - mAdapter.add(items) - - //so the headers are aware of changes - stickyHeaderAdapter.registerAdapterDataObserver(object : RecyclerView.AdapterDataObserver() { - override fun onChanged() { - decoration.invalidateHeaders() - } - }) - - //restore selections (this has to be done after the items were added - mAdapter.withSavedInstanceState(savedInstanceState) - - //set the back arrow in the toolbar - supportActionBar?.setDisplayHomeAsUpEnabled(true) - supportActionBar?.setHomeButtonEnabled(false) - } - - override fun onSaveInstanceState(_outState: Bundle) { - var outState = _outState - //add the values which need to be saved from the adapter to the bundle - outState = mAdapter.saveInstanceState(outState) - super.onSaveInstanceState(outState) - } - - override fun onOptionsItemSelected(item: MenuItem): Boolean { - //handle the click on the back arrow click - return when (item.itemId) { - android.R.id.home -> { - onBackPressed() - true - } - else -> super.onOptionsItemSelected(item) - } - } - - companion object { - private val headers = arrayOf("A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z") - } -} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/adapters/MopubFastItemAdapter.kt b/app/src/main/java/com/mikepenz/fastadapter/app/adapters/MopubFastItemAdapter.kt deleted file mode 100644 index 8b34d59db..000000000 --- a/app/src/main/java/com/mikepenz/fastadapter/app/adapters/MopubFastItemAdapter.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.mikepenz.fastadapter.app.adapters - -import androidx.recyclerview.widget.RecyclerView -import com.mikepenz.fastadapter.GenericItem -import com.mikepenz.fastadapter.adapters.FastItemAdapter -import com.mopub.nativeads.MoPubRecyclerAdapter - -/** - * Created by mikepenz on 28.06.16. - */ - -class MopubFastItemAdapter : FastItemAdapter() { - private var mMoPubAdAdapter: MoPubRecyclerAdapter? = null - - init { - legacyBindViewMode = true - } - - fun withMoPubAdAdapter(moPubAdAdapter: MoPubRecyclerAdapter): MopubFastItemAdapter<*> { - this.mMoPubAdAdapter = moPubAdAdapter - return this - } - - override fun getHolderAdapterPosition(holder: RecyclerView.ViewHolder): Int { - return mMoPubAdAdapter!!.getOriginalPosition(super.getHolderAdapterPosition(holder)) - } -} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/helpers/CustomHeaderViewCache.kt b/app/src/main/java/com/mikepenz/fastadapter/app/helpers/CustomHeaderViewCache.kt deleted file mode 100644 index 6e21b7e2a..000000000 --- a/app/src/main/java/com/mikepenz/fastadapter/app/helpers/CustomHeaderViewCache.kt +++ /dev/null @@ -1,27 +0,0 @@ -package com.mikepenz.fastadapter.app.helpers - -import android.view.View -import androidx.recyclerview.widget.RecyclerView -import com.mopub.nativeads.MoPubRecyclerAdapter -import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter -import com.timehop.stickyheadersrecyclerview.caching.HeaderViewCache -import com.timehop.stickyheadersrecyclerview.util.OrientationProvider - -/** - * Created by Gagan on 5/3/2017. - */ - -class CustomHeaderViewCache(adapter: StickyRecyclerHeadersAdapter<*>, private var moPubRecyclerAdapter: MoPubRecyclerAdapter, orientationProvider: OrientationProvider) : HeaderViewCache(adapter, orientationProvider) { - - override fun getHeader(parent: RecyclerView, position: Int): View { - var originalPosition = moPubRecyclerAdapter.getOriginalPosition(position) - if (originalPosition < 0) { - originalPosition = if (position == 0) { - 0 - } else { - moPubRecyclerAdapter.getOriginalPosition(position - 1) - } - } - return super.getHeader(parent, originalPosition) - } -} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/helpers/CustomStickyRecyclerHeadersDecoration.kt b/app/src/main/java/com/mikepenz/fastadapter/app/helpers/CustomStickyRecyclerHeadersDecoration.kt deleted file mode 100644 index aa870f790..000000000 --- a/app/src/main/java/com/mikepenz/fastadapter/app/helpers/CustomStickyRecyclerHeadersDecoration.kt +++ /dev/null @@ -1,133 +0,0 @@ -package com.mikepenz.fastadapter.app.helpers - -import android.graphics.Canvas -import android.graphics.Rect -import android.util.SparseArray -import android.view.View -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.mopub.nativeads.MoPubRecyclerAdapter -import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter -import com.timehop.stickyheadersrecyclerview.caching.HeaderProvider -import com.timehop.stickyheadersrecyclerview.calculation.DimensionCalculator -import com.timehop.stickyheadersrecyclerview.rendering.HeaderRenderer -import com.timehop.stickyheadersrecyclerview.util.LinearLayoutOrientationProvider -import com.timehop.stickyheadersrecyclerview.util.OrientationProvider - -/** - * Created by Gagan on 5/3/2017. - */ -class CustomStickyRecyclerHeadersDecoration private constructor(private val mAdapter: StickyRecyclerHeadersAdapter<*>, private val mRenderer: HeaderRenderer, - private val mOrientationProvider: OrientationProvider, private val mDimensionCalculator: DimensionCalculator, private val mHeaderProvider: HeaderProvider, - private val mHeaderPositionCalculator: HeaderPositionCalculator) : RecyclerView.ItemDecoration() { - private val mHeaderRects = SparseArray() - - /** - * The following field is used as a buffer for internal calculations. Its sole purpose is to avoid - * allocating new Rect every time we need one. - */ - private val mTempRect = Rect() - - // TODO Consider passing in orientation to simplify orientation accounting within calculation - constructor(adapter: StickyRecyclerHeadersAdapter<*>, moPubRecyclerAdapter: MoPubRecyclerAdapter) : this(adapter, moPubRecyclerAdapter, LinearLayoutOrientationProvider(), DimensionCalculator()) - - private constructor(adapter: StickyRecyclerHeadersAdapter<*>, moPubRecyclerAdapter: MoPubRecyclerAdapter, orientationProvider: OrientationProvider, - dimensionCalculator: DimensionCalculator, headerRenderer: HeaderRenderer = HeaderRenderer(orientationProvider), headerProvider: HeaderProvider = CustomHeaderViewCache(adapter, moPubRecyclerAdapter, orientationProvider)) : this(adapter, headerRenderer, orientationProvider, dimensionCalculator, headerProvider, - HeaderPositionCalculator(adapter, moPubRecyclerAdapter, headerProvider, orientationProvider, - dimensionCalculator)) - - override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) { - super.getItemOffsets(outRect, view, parent, state) - val itemPosition = parent.getChildAdapterPosition(view) - if (itemPosition == RecyclerView.NO_POSITION) { - return - } - if (mHeaderPositionCalculator.hasNewHeader(itemPosition, mOrientationProvider.isReverseLayout(parent))) { - val header = getHeaderView(parent, itemPosition) - setItemOffsetsForHeader(outRect, header, mOrientationProvider.getOrientation(parent)) - } - } - - /** - * Sets the offsets for the first item in a section to make room for the header view - * - * @param itemOffsets rectangle to define offsets for the item - * @param header view used to calculate offset for the item - * @param orientation used to calculate offset for the item - */ - private fun setItemOffsetsForHeader(itemOffsets: Rect, header: View, orientation: Int) { - mDimensionCalculator.initMargins(mTempRect, header) - if (orientation == LinearLayoutManager.VERTICAL) { - itemOffsets.top = header.height + mTempRect.top + mTempRect.bottom - } else { - itemOffsets.left = header.width + mTempRect.left + mTempRect.right - } - } - - override fun onDrawOver(canvas: Canvas, parent: RecyclerView, state: RecyclerView.State) { - super.onDrawOver(canvas, parent, state) - - val childCount = parent.childCount - if (childCount <= 0 || mAdapter.itemCount <= 0) { - return - } - - for (i in 0 until childCount) { - val itemView = parent.getChildAt(i) - val position = parent.getChildAdapterPosition(itemView) - if (position == RecyclerView.NO_POSITION) { - continue - } - - val hasStickyHeader = mHeaderPositionCalculator.hasStickyHeader(itemView, mOrientationProvider.getOrientation(parent), position) - if (hasStickyHeader || mHeaderPositionCalculator.hasNewHeader(position, mOrientationProvider.isReverseLayout(parent))) { - val header = mHeaderProvider.getHeader(parent, position) - //re-use existing Rect, if any. - var headerOffset: Rect? = mHeaderRects.get(position) - if (headerOffset == null) { - headerOffset = Rect() - mHeaderRects.put(position, headerOffset) - } - mHeaderPositionCalculator.initHeaderBounds(headerOffset, parent, header, itemView, hasStickyHeader) - mRenderer.drawHeader(parent, canvas, header, headerOffset) - } - } - } - - /** - * Gets the position of the header under the specified (x, y) coordinates. - * - * @param x x-coordinate - * @param y y-coordinate - * @return position of header, or [androidx.recyclerview.widget.RecyclerView.NO_POSITION] (-1) if not found - */ - fun findHeaderPositionUnder(x: Int, y: Int): Int { - for (i in 0 until mHeaderRects.size()) { - val rect = mHeaderRects.get(mHeaderRects.keyAt(i)) - if (rect.contains(x, y)) { - return mHeaderRects.keyAt(i) - } - } - return RecyclerView.NO_POSITION - } - - /** - * Gets the header view for the associated position. If it doesn't exist yet, it will be - * created, measured, and laid out. - * - * @param parent - * @param position - * @return Header view - */ - fun getHeaderView(parent: RecyclerView, position: Int): View { - return mHeaderProvider.getHeader(parent, position) - } - - /** - * Invalidates cached headers. This does not invalidate the recyclerview, you should do that manually after - * calling this method. - */ - fun invalidateHeaders() { - mHeaderProvider.invalidate() - } -} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/helpers/HeaderPositionCalculator.kt b/app/src/main/java/com/mikepenz/fastadapter/app/helpers/HeaderPositionCalculator.kt deleted file mode 100644 index 2769de7ed..000000000 --- a/app/src/main/java/com/mikepenz/fastadapter/app/helpers/HeaderPositionCalculator.kt +++ /dev/null @@ -1,260 +0,0 @@ -package com.mikepenz.fastadapter.app.helpers - -import android.graphics.Rect -import android.view.View -import android.view.ViewGroup -import android.widget.LinearLayout -import androidx.recyclerview.widget.LinearLayoutManager -import androidx.recyclerview.widget.RecyclerView -import com.mopub.nativeads.MoPubRecyclerAdapter -import com.timehop.stickyheadersrecyclerview.StickyRecyclerHeadersAdapter -import com.timehop.stickyheadersrecyclerview.caching.HeaderProvider -import com.timehop.stickyheadersrecyclerview.calculation.DimensionCalculator -import com.timehop.stickyheadersrecyclerview.util.OrientationProvider -import kotlin.math.max - -/** - * Created by Gagan on 5/3/2017. - */ - -class HeaderPositionCalculator(private val mAdapter: StickyRecyclerHeadersAdapter<*>, private val moPubRecyclerAdapter: MoPubRecyclerAdapter, private val mHeaderProvider: HeaderProvider, - private val mOrientationProvider: OrientationProvider, private val mDimensionCalculator: DimensionCalculator) { - - /** - * The following fields are used as buffers for internal calculations. Their sole purpose is to avoid - * allocating new Rect every time we need one. - */ - private val mTempRect1 = Rect() - private val mTempRect2 = Rect() - - /** - * Determines if a view should have a sticky header. - * The view has a sticky header if: - * 1. It is the first element in the recycler view - * 2. It has a valid ID associated to its position - * - * @param itemView given by the RecyclerView - * @param orientation of the Recyclerview - * @param position of the list item in question - * @return True if the view should have a sticky header - */ - fun hasStickyHeader(itemView: View, orientation: Int, position: Int): Boolean { - val offset: Int - val margin: Int - mDimensionCalculator.initMargins(mTempRect1, itemView) - if (orientation == LinearLayout.VERTICAL) { - offset = itemView.top - margin = mTempRect1.top - } else { - offset = itemView.left - margin = mTempRect1.left - } - var originalPosition = moPubRecyclerAdapter.getOriginalPosition(position) - if (originalPosition < 0) { - originalPosition = moPubRecyclerAdapter.getOriginalPosition(position - 1) - } - return offset <= margin && mAdapter.getHeaderId(originalPosition) >= 0 - } - - /** - * Determines if an item in the list should have a header that is different than the item in the - * list that immediately precedes it. Items with no headers will always return false. - * - * @param position of the list item in questions - * @param isReverseLayout TRUE if layout manager has flag isReverseLayout - * @return true if this item has a different header than the previous item in the list - * @see {@link StickyRecyclerHeadersAdapter.getHeaderId - */ - fun hasNewHeader(position: Int, isReverseLayout: Boolean): Boolean { - if (indexOutOfBounds(position)) { - return false - } - - val originalPosition = moPubRecyclerAdapter.getOriginalPosition(position) - if (originalPosition < 0) { - return false - } - - val headerId = mAdapter.getHeaderId(originalPosition) - - if (headerId < 0) { - return false - } - - var nextItemHeaderId = -1L - val nextItemPosition = originalPosition + if (isReverseLayout) 1 else -1 - if (!indexOutOfBounds(nextItemPosition)) { - nextItemHeaderId = mAdapter.getHeaderId(nextItemPosition) - } - val firstItemPosition = if (isReverseLayout) moPubRecyclerAdapter.itemCount - 1 else 0 - - return originalPosition == firstItemPosition || headerId != nextItemHeaderId - } - - private fun indexOutOfBounds(position: Int): Boolean { - return position < 0 || position >= moPubRecyclerAdapter.itemCount - } - - fun initHeaderBounds(bounds: Rect, recyclerView: RecyclerView, header: View, firstView: View, firstHeader: Boolean) { - val orientation = mOrientationProvider.getOrientation(recyclerView) - initDefaultHeaderOffset(bounds, recyclerView, header, firstView, orientation) - - if (firstHeader && isStickyHeaderBeingPushedOffscreen(recyclerView, header)) { - getFirstViewUnobscuredByHeader(recyclerView, header)?.let { - val firstViewUnderHeaderPosition = recyclerView.getChildAdapterPosition(it) - val secondHeader = mHeaderProvider.getHeader(recyclerView, firstViewUnderHeaderPosition) - translateHeaderWithNextHeader(recyclerView, mOrientationProvider.getOrientation(recyclerView), bounds, header, it, secondHeader) - } - } - } - - private fun initDefaultHeaderOffset(headerMargins: Rect, recyclerView: RecyclerView, header: View, firstView: View, orientation: Int) { - val translationX: Int - val translationY: Int - mDimensionCalculator.initMargins(mTempRect1, header) - - val layoutParams = firstView.layoutParams - var leftMargin = 0 - var topMargin = 0 - if (layoutParams is ViewGroup.MarginLayoutParams) { - leftMargin = layoutParams.leftMargin - topMargin = layoutParams.topMargin - } - - if (orientation == LinearLayoutManager.VERTICAL) { - translationX = firstView.left - leftMargin + mTempRect1.left - translationY = max(firstView.top - topMargin - header.height - mTempRect1.bottom, getListTop(recyclerView) + mTempRect1.top) - } else { - translationY = firstView.top - topMargin + mTempRect1.top - translationX = max(firstView.left - leftMargin - header.width - mTempRect1.right, getListLeft(recyclerView) + mTempRect1.left) - } - - headerMargins.set(translationX, translationY, translationX + header.width, - translationY + header.height) - } - - private fun isStickyHeaderBeingPushedOffscreen(recyclerView: RecyclerView, stickyHeader: View): Boolean { - getFirstViewUnobscuredByHeader(recyclerView, stickyHeader)?.let { - val firstViewUnderHeaderPosition = recyclerView.getChildAdapterPosition(it) - if (firstViewUnderHeaderPosition == RecyclerView.NO_POSITION) { - return false - } - - val isReverseLayout = mOrientationProvider.isReverseLayout(recyclerView) - if (firstViewUnderHeaderPosition > 0 && hasNewHeader(firstViewUnderHeaderPosition, isReverseLayout)) { - val nextHeader = mHeaderProvider.getHeader(recyclerView, firstViewUnderHeaderPosition) - mDimensionCalculator.initMargins(mTempRect1, nextHeader) - mDimensionCalculator.initMargins(mTempRect2, stickyHeader) - - if (mOrientationProvider.getOrientation(recyclerView) == LinearLayoutManager.VERTICAL) { - val topOfNextHeader = it.top - mTempRect1.bottom - nextHeader.height - mTempRect1.top - val bottomOfThisHeader = recyclerView.paddingTop + stickyHeader.bottom + mTempRect2.top + mTempRect2.bottom - if (topOfNextHeader < bottomOfThisHeader) { - return true - } - } else { - val leftOfNextHeader = it.left - mTempRect1.right - nextHeader.width - mTempRect1.left - val rightOfThisHeader = recyclerView.paddingLeft + stickyHeader.right + mTempRect2.left + mTempRect2.right - if (leftOfNextHeader < rightOfThisHeader) { - return true - } - } - } - } - - return false - } - - private fun translateHeaderWithNextHeader(recyclerView: RecyclerView, orientation: Int, translation: Rect, - currentHeader: View, viewAfterNextHeader: View, nextHeader: View) { - mDimensionCalculator.initMargins(mTempRect1, nextHeader) - mDimensionCalculator.initMargins(mTempRect2, currentHeader) - if (orientation == LinearLayoutManager.VERTICAL) { - val topOfStickyHeader = getListTop(recyclerView) + mTempRect2.top + mTempRect2.bottom - val shiftFromNextHeader = viewAfterNextHeader.top - nextHeader.height - mTempRect1.bottom - mTempRect1.top - currentHeader.height - topOfStickyHeader - if (shiftFromNextHeader < topOfStickyHeader) { - translation.top += shiftFromNextHeader - } - } else { - val leftOfStickyHeader = getListLeft(recyclerView) + mTempRect2.left + mTempRect2.right - val shiftFromNextHeader = viewAfterNextHeader.left - nextHeader.width - mTempRect1.right - mTempRect1.left - currentHeader.width - leftOfStickyHeader - if (shiftFromNextHeader < leftOfStickyHeader) { - translation.left += shiftFromNextHeader - } - } - } - - /** - * Returns the first item currently in the RecyclerView that is not obscured by a header. - * - * @param parent Recyclerview containing all the list items - * @return first item that is fully beneath a header - */ - private fun getFirstViewUnobscuredByHeader(parent: RecyclerView, firstHeader: View): View? { - val isReverseLayout = mOrientationProvider.isReverseLayout(parent) - val step = if (isReverseLayout) -1 else 1 - val from = if (isReverseLayout) parent.childCount - 1 else 0 - var i = from - while (i >= 0 && i <= parent.childCount - 1) { - val child = parent.getChildAt(i) - if (!itemIsObscuredByHeader(parent, child, firstHeader, mOrientationProvider.getOrientation(parent))) { - return child - } - i += step - } - return null - } - - /** - * Determines if an item is obscured by a header - * - * @param parent - * @param item to determine if obscured by header - * @param header that might be obscuring the item - * @param orientation of the [RecyclerView] - * @return true if the item view is obscured by the header view - */ - private fun itemIsObscuredByHeader(parent: RecyclerView, item: View, header: View, orientation: Int): Boolean { - val layoutParams = item.layoutParams as RecyclerView.LayoutParams - mDimensionCalculator.initMargins(mTempRect1, header) - - val adapterPosition = parent.getChildAdapterPosition(item) - if (adapterPosition == RecyclerView.NO_POSITION || mHeaderProvider.getHeader(parent, adapterPosition) !== header) { - // Resolves https://github.com/timehop/sticky-headers-recyclerview/issues/36 - // Handles an edge case where a trailing header is smaller than the current sticky header. - return false - } - - if (orientation == LinearLayoutManager.VERTICAL) { - val itemTop = item.top - layoutParams.topMargin - val headerBottom = header.bottom + mTempRect1.bottom + mTempRect1.top - if (itemTop > headerBottom) { - return false - } - } else { - val itemLeft = item.left - layoutParams.leftMargin - val headerRight = header.right + mTempRect1.right + mTempRect1.left - if (itemLeft > headerRight) { - return false - } - } - - return true - } - - private fun getListTop(view: RecyclerView): Int { - return if (view.layoutManager?.clipToPadding == true) { - view.paddingTop - } else { - 0 - } - } - - private fun getListLeft(view: RecyclerView): Int { - return if (view.layoutManager?.clipToPadding == true) { - view.paddingLeft - } else { - 0 - } - } -} diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/items/ImageItem.kt b/app/src/main/java/com/mikepenz/fastadapter/app/items/ImageItem.kt index 7d62c6ac2..a0fedf91c 100644 --- a/app/src/main/java/com/mikepenz/fastadapter/app/items/ImageItem.kt +++ b/app/src/main/java/com/mikepenz/fastadapter/app/items/ImageItem.kt @@ -6,7 +6,7 @@ import android.view.ViewGroup import android.view.ViewPropertyAnimator import android.widget.* import androidx.recyclerview.widget.RecyclerView -import coil.clear +import coil.dispose import coil.load import com.mikepenz.fastadapter.FastAdapter import com.mikepenz.fastadapter.app.R @@ -93,7 +93,7 @@ class ImageItem : AbstractItem() { override fun unbindView(holder: ViewHolder) { super.unbindView(holder) - holder.imageView.clear() + holder.imageView.dispose() holder.imageView.setImageDrawable(null) } diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/items/SimpleImageItem.kt b/app/src/main/java/com/mikepenz/fastadapter/app/items/SimpleImageItem.kt index 7bed45654..5abbc817a 100644 --- a/app/src/main/java/com/mikepenz/fastadapter/app/items/SimpleImageItem.kt +++ b/app/src/main/java/com/mikepenz/fastadapter/app/items/SimpleImageItem.kt @@ -6,7 +6,7 @@ import android.widget.ImageView import android.widget.TextView import androidx.core.content.ContextCompat import androidx.recyclerview.widget.RecyclerView -import coil.clear +import coil.dispose import coil.load import com.mikepenz.fastadapter.IItemVHFactory import com.mikepenz.fastadapter.app.R @@ -107,7 +107,7 @@ class SimpleImageItem : BaseItem() { override fun unbindView(holder: ViewHolder) { super.unbindView(holder) - holder.imageView.clear() + holder.imageView.dispose() holder.imageView.setImageDrawable(null) holder.imageDescription.text = null } diff --git a/app/src/main/java/com/mikepenz/fastadapter/app/items/expandable/SimpleSubExpandableItem.kt b/app/src/main/java/com/mikepenz/fastadapter/app/items/expandable/SimpleSubExpandableItem.kt index 95f4f2131..93078a318 100644 --- a/app/src/main/java/com/mikepenz/fastadapter/app/items/expandable/SimpleSubExpandableItem.kt +++ b/app/src/main/java/com/mikepenz/fastadapter/app/items/expandable/SimpleSubExpandableItem.kt @@ -7,11 +7,9 @@ import android.widget.TextView import androidx.annotation.StringRes import androidx.core.view.ViewCompat import androidx.recyclerview.widget.RecyclerView -import com.mikepenz.fastadapter.ClickListener -import com.mikepenz.fastadapter.IAdapter -import com.mikepenz.fastadapter.IClickable import com.mikepenz.fastadapter.ISubItem import com.mikepenz.fastadapter.app.R +import com.mikepenz.fastadapter.expandable.ExpandableExtension import com.mikepenz.fastadapter.expandable.items.AbstractExpandableItem import com.mikepenz.fastadapter.ui.utils.FastAdapterUIUtils import com.mikepenz.materialdrawer.holder.StringHolder @@ -19,41 +17,12 @@ import com.mikepenz.materialdrawer.holder.StringHolder /** * Created by mikepenz on 28.12.15. */ -open class SimpleSubExpandableItem : AbstractExpandableItem(), IClickable, ISubItem { +open class SimpleSubExpandableItem : AbstractExpandableItem(), ISubItem { var header: String? = null var name: StringHolder? = null var description: StringHolder? = null - private var mOnClickListener: ClickListener? = null - - //we define a clickListener in here so we can directly animate - /** - * we overwrite the item specific click listener so we can automatically animate within the item - * - * @return - */ - @Suppress("SetterBackingFieldAssignment") - override var onItemClickListener: ClickListener? = { v: View?, adapter: IAdapter, item: SimpleSubExpandableItem, position: Int -> - if (item.subItems.isNotEmpty()) { - v?.findViewById(R.id.material_drawer_icon)?.let { - if (!item.isExpanded) { - ViewCompat.animate(it).rotation(180f).start() - } else { - ViewCompat.animate(it).rotation(0f).start() - } - } - } - mOnClickListener?.invoke(v, adapter, item, position) ?: true - } - set(onClickListener) { - this.mOnClickListener = onClickListener // on purpose - } - - override var onPreItemClickListener: ClickListener? - get() = null - set(_) {} - //this might not be true for your application override var isSelectable: Boolean get() = subItems.isEmpty() @@ -110,6 +79,19 @@ open class SimpleSubExpandableItem : AbstractExpandableItem) { super.bindView(holder, payloads) + val p = payloads.mapNotNull { it as? String }.lastOrNull() + if (p != null) { + // Check if this was an expanding or collapsing action by checking the payload. + // If it is we need to animate the changes + if (p == ExpandableExtension.PAYLOAD_EXPAND) { + ViewCompat.animate(holder.icon).rotation(0f).start() + return + } else if (p == ExpandableExtension.PAYLOAD_COLLAPSE) { + ViewCompat.animate(holder.icon).rotation(180f).start() + return + } + } + //get the context val ctx = holder.itemView.context @@ -121,17 +103,8 @@ open class SimpleSubExpandableItem : AbstractExpandableItemEndlessScroll, Progress Sort Sample Simply sort your items by providing a Comparator - Mopub Ads Sample - StickyHeader Mopub Ads Sample - Simply mopub adapter usage example - Simple sticky header mopub adapter usage example Realm Sample Realm, Implement IItem interface Diff Util Sample diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 1d4a983ca..c75cd390f 100644 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -1,7 +1,7 @@ -