diff --git a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/PivotLayoutManagerTest.kt b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/PivotLayoutManagerTest.kt index 5a283aad..1963008d 100644 --- a/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/PivotLayoutManagerTest.kt +++ b/dpadrecyclerview/src/androidTest/kotlin/com/rubensousa/dpadrecyclerview/test/tests/PivotLayoutManagerTest.kt @@ -16,9 +16,13 @@ package com.rubensousa.dpadrecyclerview.test.tests +import androidx.fragment.app.Fragment +import androidx.fragment.app.testing.launchFragment import androidx.recyclerview.widget.RecyclerView.LayoutManager.Properties import com.google.common.truth.Truth.assertThat +import com.rubensousa.dpadrecyclerview.DpadRecyclerView import com.rubensousa.dpadrecyclerview.layoutmanager.PivotLayoutManager +import com.rubensousa.dpadrecyclerview.test.R import org.junit.Test class PivotLayoutManagerTest { @@ -41,4 +45,21 @@ class PivotLayoutManagerTest { assertThat(config.focusOutSideBack).isTrue() } + @Test + fun testPivotLayoutManagerFromXML() { + // given + val fragment = launchFragment() + var recyclerView: DpadRecyclerView? = null + + // when + fragment.onFragment { + recyclerView = it.requireView() as DpadRecyclerView + } + + // then + assertThat(recyclerView).isNotNull() + } + + class XMLFragment : Fragment(R.layout.dpadrecyclerview_layout_name) + } diff --git a/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_layout_name.xml b/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_layout_name.xml new file mode 100644 index 00000000..2c021ffb --- /dev/null +++ b/dpadrecyclerview/src/androidTest/res/layout/dpadrecyclerview_layout_name.xml @@ -0,0 +1,7 @@ + + \ No newline at end of file diff --git a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/DpadRecyclerView.kt b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/DpadRecyclerView.kt index 5da1f627..a2f4333b 100644 --- a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/DpadRecyclerView.kt +++ b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/DpadRecyclerView.kt @@ -64,7 +64,7 @@ open class DpadRecyclerView @JvmOverloads constructor( internal val DEBUG = BuildConfig.DEBUG } - private val viewHolderTaskExecutor = ViewHolderTaskExecutor() + private var viewHolderTaskExecutor: ViewHolderTaskExecutor? = null private val focusableChildDrawingCallback = FocusableChildDrawingCallback() private val fadingEdge = FadingEdge() @@ -212,7 +212,9 @@ open class DpadRecyclerView @JvmOverloads constructor( final override fun setLayoutManager(layout: LayoutManager?) { super.setLayoutManager(layout) - pivotLayoutManager?.removeOnViewHolderSelectedListener(viewHolderTaskExecutor) + viewHolderTaskExecutor?.let { + pivotLayoutManager?.removeOnViewHolderSelectedListener(it) + } pivotLayoutManager?.updateRecyclerView(null) if (pivotLayoutManager !== layout) { pivotLayoutManager?.layoutCompletedListener = null @@ -223,7 +225,8 @@ open class DpadRecyclerView @JvmOverloads constructor( if (layout != null && layout !is PivotLayoutManager) { throw IllegalArgumentException( - "Only PivotLayoutManager is supported, but got $layout" + "Only com.rubensousa.dpadrecyclerview.layoutmanager.PivotLayoutManager" + + ".PivotLayoutManager is supported, but got $layout" ) } if (layout is PivotLayoutManager) { @@ -233,7 +236,7 @@ open class DpadRecyclerView @JvmOverloads constructor( hasPendingLayout = false } } - layout.addOnViewHolderSelectedListener(viewHolderTaskExecutor) + viewHolderTaskExecutor?.let { layout.addOnViewHolderSelectedListener(it) } pivotLayoutManager = layout } } @@ -1022,7 +1025,7 @@ open class DpadRecyclerView @JvmOverloads constructor( * @param task Task to executed on the ViewHolder at the given position */ fun setSelectedPosition(position: Int, task: ViewHolderTask) { - viewHolderTaskExecutor.schedule(position, task) + viewHolderTaskExecutor?.schedule(position, task) requireLayout().selectPosition(position, subPosition = 0, smooth = false) } @@ -1041,7 +1044,7 @@ open class DpadRecyclerView @JvmOverloads constructor( * @param task Task to executed on the ViewHolder at the given position */ fun setSelectedPositionSmooth(position: Int, task: ViewHolderTask) { - viewHolderTaskExecutor.schedule(position, task) + viewHolderTaskExecutor?.schedule(position, task) requireLayout().selectPosition(position, subPosition = 0, smooth = true) } @@ -1062,7 +1065,7 @@ open class DpadRecyclerView @JvmOverloads constructor( * @param task Task to executed on the ViewHolder at the given position */ fun setSelectedSubPosition(position: Int, subPosition: Int, task: ViewHolderTask) { - viewHolderTaskExecutor.schedule(position, subPosition, task) + viewHolderTaskExecutor?.schedule(position, subPosition, task) requireLayout().selectPosition(position, subPosition, smooth = false) } @@ -1099,7 +1102,7 @@ open class DpadRecyclerView @JvmOverloads constructor( * @param task Task to executed on the ViewHolder at the given position */ fun setSelectedSubPositionSmooth(position: Int, subPosition: Int, task: ViewHolderTask) { - viewHolderTaskExecutor.schedule(position, subPosition, task) + viewHolderTaskExecutor?.schedule(position, subPosition, task) requireLayout().selectPosition(position, subPosition, smooth = true) } diff --git a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt index 81c79618..1924589d 100644 --- a/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt +++ b/dpadrecyclerview/src/main/java/com/rubensousa/dpadrecyclerview/layoutmanager/PivotLayoutManager.kt @@ -79,6 +79,12 @@ class PivotLayoutManager(properties: Properties) : RecyclerView.LayoutManager(), private var isScrollingFromTouchEvent = false internal var layoutCompletedListener: DpadRecyclerView.OnLayoutCompletedListener? = null + // This is required for XML usage + @Suppress("unused", "UNUSED_PARAMETER") + constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) : this( + Properties() + ) + override fun checkLayoutParams(layoutParams: RecyclerView.LayoutParams?): Boolean { return layoutParams is DpadLayoutParams }