mirror of
https://github.com/leaf-wai/StackLayoutManager.git
synced 2026-07-12 02:41:17 +08:00
1.迁移到AndroidX
2.修改支持无限循环滑动
This commit is contained in:
3
.idea/misc.xml
generated
3
.idea/misc.xml
generated
@@ -1,5 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
<component name="NullableNotNullManager">
|
<component name="NullableNotNullManager">
|
||||||
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
|
||||||
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
|
||||||
@@ -25,7 +26,7 @@
|
|||||||
</value>
|
</value>
|
||||||
</option>
|
</option>
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
<output url="file://$PROJECT_DIR$/build/classes" />
|
<output url="file://$PROJECT_DIR$/build/classes" />
|
||||||
</component>
|
</component>
|
||||||
<component name="ProjectType">
|
<component name="ProjectType">
|
||||||
|
|||||||
10
.idea/modules.xml
generated
10
.idea/modules.xml
generated
@@ -1,10 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="ProjectModuleManager">
|
|
||||||
<modules>
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/StackLayoutManager.iml" filepath="$PROJECT_DIR$/StackLayoutManager.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/StackLayoutManager/StackLayoutManager-StackLayoutManager.iml" filepath="$PROJECT_DIR$/StackLayoutManager/StackLayoutManager-StackLayoutManager.iml" />
|
|
||||||
<module fileurl="file://$PROJECT_DIR$/sample/sample.iml" filepath="$PROJECT_DIR$/sample/sample.iml" />
|
|
||||||
</modules>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
12
.idea/runConfigurations.xml
generated
12
.idea/runConfigurations.xml
generated
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RunConfigurationProducerService">
|
|
||||||
<option name="ignoredProducers">
|
|
||||||
<set>
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
|
|
||||||
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
|
|
||||||
</set>
|
|
||||||
</option>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -3,15 +3,15 @@ apply plugin: 'kotlin-android'
|
|||||||
apply plugin: 'com.novoda.bintray-release'
|
apply plugin: 'com.novoda.bintray-release'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 31
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 14
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 31
|
||||||
versionCode 6
|
versionCode 6
|
||||||
versionName "1.0.5"
|
versionName "1.0.5"
|
||||||
|
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +30,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
}
|
}
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.littlemango.stacklayoutmanager
|
|||||||
|
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.littlemango.stacklayoutmanager.StackLayoutManager.ScrollOrientation
|
import com.littlemango.stacklayoutmanager.StackLayoutManager.ScrollOrientation
|
||||||
|
import kotlin.math.pow
|
||||||
|
|
||||||
class DefaultAnimation(scrollOrientation: ScrollOrientation, visibleCount: Int) : StackAnimation(scrollOrientation, visibleCount) {
|
class DefaultAnimation(scrollOrientation: ScrollOrientation, visibleCount: Int) : StackAnimation(scrollOrientation, visibleCount) {
|
||||||
|
|
||||||
@@ -72,8 +73,8 @@ class DefaultAnimation(scrollOrientation: ScrollOrientation, visibleCount: Int)
|
|||||||
scale = 1 - ((1 - mOutScale) * firstMovePercent)
|
scale = 1 - ((1 - mOutScale) * firstMovePercent)
|
||||||
rotation = mOutRotation * firstMovePercent
|
rotation = mOutRotation * firstMovePercent
|
||||||
} else {
|
} else {
|
||||||
val minScale = (Math.pow(mScale.toDouble(), position.toDouble())).toFloat()
|
val minScale = (mScale.toDouble().pow(position.toDouble())).toFloat()
|
||||||
val maxScale = (Math.pow(mScale.toDouble(), (position - 1).toDouble())).toFloat()
|
val maxScale = (mScale.toDouble().pow((position - 1).toDouble())).toFloat()
|
||||||
scale = minScale + (maxScale - minScale) * firstMovePercent
|
scale = minScale + (maxScale - minScale) * firstMovePercent
|
||||||
//只对最后一个 item 做透明度变化
|
//只对最后一个 item 做透明度变化
|
||||||
if (position == mVisibleCount) {
|
if (position == mVisibleCount) {
|
||||||
|
|||||||
@@ -47,12 +47,18 @@ class DefaultLayout(scrollOrientation: StackLayoutManager.ScrollOrientation,
|
|||||||
|
|
||||||
private fun getFirstVisibleItemLeft(): Int {
|
private fun getFirstVisibleItemLeft(): Int {
|
||||||
return when(mScrollOrientation) {
|
return when(mScrollOrientation) {
|
||||||
StackLayoutManager.ScrollOrientation.RIGHT_TO_LEFT -> mStartMargin - mScrollOffset % mWidth
|
StackLayoutManager.ScrollOrientation.RIGHT_TO_LEFT -> {
|
||||||
|
var offset = mScrollOffset % mWidth
|
||||||
|
if (offset < 0) offset += mWidth
|
||||||
|
mStartMargin - offset
|
||||||
|
}
|
||||||
StackLayoutManager.ScrollOrientation.LEFT_TO_RIGHT -> {
|
StackLayoutManager.ScrollOrientation.LEFT_TO_RIGHT -> {
|
||||||
return if (mScrollOffset % mWidth == 0) {
|
return if (mScrollOffset % mWidth == 0) {
|
||||||
mStartMargin
|
mStartMargin
|
||||||
} else {
|
} else {
|
||||||
mStartMargin + (mWidth - mScrollOffset % mWidth)
|
var offset = mScrollOffset % mWidth
|
||||||
|
if (offset < 0) offset += mWidth
|
||||||
|
mStartMargin + (mWidth - offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> mWidthSpace / 2
|
else -> mWidthSpace / 2
|
||||||
@@ -61,12 +67,18 @@ class DefaultLayout(scrollOrientation: StackLayoutManager.ScrollOrientation,
|
|||||||
|
|
||||||
private fun getFirstVisibleItemTop(): Int {
|
private fun getFirstVisibleItemTop(): Int {
|
||||||
return when(mScrollOrientation) {
|
return when(mScrollOrientation) {
|
||||||
StackLayoutManager.ScrollOrientation.BOTTOM_TO_TOP -> mStartMargin - mScrollOffset % mHeight
|
StackLayoutManager.ScrollOrientation.BOTTOM_TO_TOP -> {
|
||||||
|
var offset = mScrollOffset % mHeight
|
||||||
|
if (offset < 0) offset += mHeight
|
||||||
|
mStartMargin - offset
|
||||||
|
}
|
||||||
StackLayoutManager.ScrollOrientation.TOP_TO_BOTTOM -> {
|
StackLayoutManager.ScrollOrientation.TOP_TO_BOTTOM -> {
|
||||||
return if (mScrollOffset % mHeight == 0) {
|
return if (mScrollOffset % mHeight == 0) {
|
||||||
mStartMargin
|
mStartMargin
|
||||||
} else {
|
} else {
|
||||||
mStartMargin + (mHeight - mScrollOffset % mHeight)
|
var offset = mScrollOffset % mHeight
|
||||||
|
if (offset < 0) offset += mHeight
|
||||||
|
mStartMargin + (mHeight - offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> mHeightSpace / 2
|
else -> mHeightSpace / 2
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
package com.littlemango.stacklayoutmanager
|
package com.littlemango.stacklayoutmanager
|
||||||
|
|
||||||
import android.support.annotation.IntRange
|
import androidx.annotation.IntRange
|
||||||
import android.support.v7.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING
|
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_DRAGGING
|
||||||
import android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE
|
import androidx.recyclerview.widget.RecyclerView.SCROLL_STATE_IDLE
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
class StackLayoutManager(
|
||||||
visibleCount: Int,
|
scrollOrientation: ScrollOrientation,
|
||||||
animation: Class<out StackAnimation>,
|
visibleCount: Int,
|
||||||
layout: Class<out StackLayout>) : RecyclerView.LayoutManager() {
|
animation: Class<out StackAnimation>,
|
||||||
private enum class FlingOrientation{NONE, LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}
|
layout: Class<out StackLayout>
|
||||||
|
) : RecyclerView.LayoutManager() {
|
||||||
|
private enum class FlingOrientation { NONE, LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP }
|
||||||
|
|
||||||
enum class ScrollOrientation{LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP}
|
enum class ScrollOrientation { LEFT_TO_RIGHT, RIGHT_TO_LEFT, TOP_TO_BOTTOM, BOTTOM_TO_TOP }
|
||||||
|
|
||||||
private var mVisibleItemCount = visibleCount
|
private var mVisibleItemCount = visibleCount
|
||||||
|
|
||||||
@@ -26,6 +30,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
|
|
||||||
//做动画的组件,支持自定义
|
//做动画的组件,支持自定义
|
||||||
private var mAnimation: StackAnimation? = null
|
private var mAnimation: StackAnimation? = null
|
||||||
|
|
||||||
//做布局的组件,支持自定义
|
//做布局的组件,支持自定义
|
||||||
private var mLayout: StackLayout? = null
|
private var mLayout: StackLayout? = null
|
||||||
|
|
||||||
@@ -78,7 +83,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
* @param velocity 默认值是2000.
|
* @param velocity 默认值是2000.
|
||||||
*/
|
*/
|
||||||
fun setPagerFlingVelocity(@IntRange(from = 0, to = Int.MAX_VALUE.toLong()) velocity: Int) {
|
fun setPagerFlingVelocity(@IntRange(from = 0, to = Int.MAX_VALUE.toLong()) velocity: Int) {
|
||||||
mPagerFlingVelocity = Math.min(Int.MAX_VALUE, Math.max(0, velocity))
|
mPagerFlingVelocity = Int.MAX_VALUE.coerceAtMost(0.coerceAtLeast(velocity))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -92,8 +97,8 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
* 设置recyclerView 静止时候可见的itemView 个数.
|
* 设置recyclerView 静止时候可见的itemView 个数.
|
||||||
* @param count 可见 itemView,默认为3
|
* @param count 可见 itemView,默认为3
|
||||||
*/
|
*/
|
||||||
fun setVisibleItemCount(@IntRange(from = 1, to = Long.MAX_VALUE)count: Int) {
|
fun setVisibleItemCount(@IntRange(from = 1, to = Long.MAX_VALUE) count: Int) {
|
||||||
mVisibleItemCount = Math.min(itemCount - 1, Math.max(1, count))
|
mVisibleItemCount = (itemCount - 1).coerceAtMost(1.coerceAtLeast(count))
|
||||||
mAnimation?.setVisibleCount(mVisibleItemCount)
|
mAnimation?.setVisibleCount(mVisibleItemCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -157,11 +162,11 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
if (width == 0 || height == 0) {
|
if (width == 0 || height == 0) {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
return when(mScrollOrientation) {
|
return when (mScrollOrientation) {
|
||||||
ScrollOrientation.RIGHT_TO_LEFT -> Math.floor((mScrollOffset * 1.0 / width)).toInt()
|
ScrollOrientation.RIGHT_TO_LEFT -> floor((mScrollOffset * 1.0 / width)).toInt()
|
||||||
ScrollOrientation.LEFT_TO_RIGHT -> itemCount - 1 - Math.ceil((mScrollOffset * 1.0 / width)).toInt()
|
ScrollOrientation.LEFT_TO_RIGHT -> itemCount - 1 - ceil((mScrollOffset * 1.0 / width)).toInt()
|
||||||
ScrollOrientation.BOTTOM_TO_TOP -> Math.floor((mScrollOffset * 1.0 / height)).toInt()
|
ScrollOrientation.BOTTOM_TO_TOP -> floor((mScrollOffset * 1.0 / height)).toInt()
|
||||||
ScrollOrientation.TOP_TO_BOTTOM -> itemCount - 1 - Math.ceil((mScrollOffset * 1.0 / height)).toInt()
|
ScrollOrientation.TOP_TO_BOTTOM -> itemCount - 1 - ceil((mScrollOffset * 1.0 / height)).toInt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -179,14 +184,17 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
constructor() : this(ScrollOrientation.RIGHT_TO_LEFT)
|
constructor() : this(ScrollOrientation.RIGHT_TO_LEFT)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mScrollOffset = when(mScrollOrientation) {
|
mScrollOffset = when (mScrollOrientation) {
|
||||||
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.BOTTOM_TO_TOP -> 0
|
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.BOTTOM_TO_TOP -> 0
|
||||||
else -> Int.MAX_VALUE
|
else -> Int.MAX_VALUE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (StackAnimation::class.java.isAssignableFrom(animation)) {
|
if (StackAnimation::class.java.isAssignableFrom(animation)) {
|
||||||
try {
|
try {
|
||||||
val cla = animation.getDeclaredConstructor(ScrollOrientation::class.java, Int::class.javaPrimitiveType)
|
val cla = animation.getDeclaredConstructor(
|
||||||
|
ScrollOrientation::class.java,
|
||||||
|
Int::class.javaPrimitiveType
|
||||||
|
)
|
||||||
mAnimation = cla.newInstance(scrollOrientation, visibleCount) as StackAnimation
|
mAnimation = cla.newInstance(scrollOrientation, visibleCount) as StackAnimation
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@@ -194,7 +202,11 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
}
|
}
|
||||||
if (StackLayout::class.java.isAssignableFrom(layout)) {
|
if (StackLayout::class.java.isAssignableFrom(layout)) {
|
||||||
try {
|
try {
|
||||||
val cla = layout.getDeclaredConstructor(ScrollOrientation::class.java, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType)
|
val cla = layout.getDeclaredConstructor(
|
||||||
|
ScrollOrientation::class.java,
|
||||||
|
Int::class.javaPrimitiveType,
|
||||||
|
Int::class.javaPrimitiveType
|
||||||
|
)
|
||||||
mLayout = cla.newInstance(scrollOrientation, visibleCount, 30) as StackLayout
|
mLayout = cla.newInstance(scrollOrientation, visibleCount, 30) as StackLayout
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@@ -203,8 +215,10 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
|
override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
|
||||||
return RecyclerView.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
|
return RecyclerView.LayoutParams(
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onAttachedToWindow(view: RecyclerView) {
|
override fun onAttachedToWindow(view: RecyclerView) {
|
||||||
@@ -212,7 +226,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
mOnFlingListener = object : RecyclerView.OnFlingListener() {
|
mOnFlingListener = object : RecyclerView.OnFlingListener() {
|
||||||
override fun onFling(velocityX: Int, velocityY: Int): Boolean {
|
override fun onFling(velocityX: Int, velocityY: Int): Boolean {
|
||||||
if (mPagerMode) {
|
if (mPagerMode) {
|
||||||
when(mScrollOrientation) {
|
when (mScrollOrientation) {
|
||||||
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.LEFT_TO_RIGHT -> {
|
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.LEFT_TO_RIGHT -> {
|
||||||
mFlingOrientation = when {
|
mFlingOrientation = when {
|
||||||
velocityX > mPagerFlingVelocity -> FlingOrientation.RIGHT_TO_LEFT
|
velocityX > mPagerFlingVelocity -> FlingOrientation.RIGHT_TO_LEFT
|
||||||
@@ -299,11 +313,19 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun scrollHorizontallyBy(dx: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State): Int {
|
override fun scrollHorizontallyBy(
|
||||||
|
dx: Int,
|
||||||
|
recycler: RecyclerView.Recycler,
|
||||||
|
state: RecyclerView.State
|
||||||
|
): Int {
|
||||||
return handleScrollBy(dx, recycler)
|
return handleScrollBy(dx, recycler)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun scrollVerticallyBy(dy: Int, recycler: RecyclerView.Recycler, state: RecyclerView.State?): Int {
|
override fun scrollVerticallyBy(
|
||||||
|
dy: Int,
|
||||||
|
recycler: RecyclerView.Recycler,
|
||||||
|
state: RecyclerView.State?
|
||||||
|
): Int {
|
||||||
return handleScrollBy(dy, recycler)
|
return handleScrollBy(dy, recycler)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +337,11 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
requestLayout()
|
requestLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) {
|
override fun smoothScrollToPosition(
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
state: RecyclerView.State?,
|
||||||
|
position: Int
|
||||||
|
) {
|
||||||
if (position < 0 || position >= itemCount) {
|
if (position < 0 || position >= itemCount) {
|
||||||
throw ArrayIndexOutOfBoundsException("$position is out of bound [0..$itemCount-1]")
|
throw ArrayIndexOutOfBoundsException("$position is out of bound [0..$itemCount-1]")
|
||||||
}
|
}
|
||||||
@@ -337,59 +363,51 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun handleScrollBy(offset: Int, recycler: RecyclerView.Recycler): Int {
|
private fun handleScrollBy(offset: Int, recycler: RecyclerView.Recycler): Int {
|
||||||
//期望值,不得超过最大最小值,所以期望值不一定等于实际值
|
mScrollOffset += offset
|
||||||
val expectOffset = mScrollOffset + offset
|
|
||||||
|
|
||||||
//实际值
|
|
||||||
mScrollOffset = getValidOffset(expectOffset)
|
|
||||||
|
|
||||||
//实际偏移,超过最大最小值之后的偏移都应该是0,该值作为返回值,否则在极限位置进行滚动的时候不会出现弹性阴影
|
|
||||||
val exactMove = mScrollOffset - expectOffset + offset
|
|
||||||
|
|
||||||
if (exactMove == 0) {
|
|
||||||
//itemViews 位置都不会改变,直接 return
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
detachAndScrapAttachedViews(recycler)
|
detachAndScrapAttachedViews(recycler)
|
||||||
|
|
||||||
loadItemView(recycler)
|
loadItemView(recycler)
|
||||||
return exactMove
|
|
||||||
|
return offset
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadItemView(recycler: RecyclerView.Recycler) {
|
private fun loadItemView(recycler: RecyclerView.Recycler) {
|
||||||
val firstVisiblePosition = getFirstVisibleItemPosition()
|
val firstVisiblePosition = getFirstVisibleItemPosition()
|
||||||
val lastVisiblePosition = getLastVisibleItemPosition()
|
val lastVisiblePosition = getFirstVisibleItemPosition() + mVisibleItemCount - 1
|
||||||
|
|
||||||
//位移百分比
|
//位移百分比
|
||||||
val movePercent = getFirstVisibleItemMovePercent()
|
var movePercent = getFirstVisibleItemMovePercent()
|
||||||
|
if (movePercent < 0) movePercent += 1
|
||||||
|
|
||||||
for (i in lastVisiblePosition downTo firstVisiblePosition) {
|
for (i in (mVisibleItemCount - 1) downTo 0) {
|
||||||
val view = recycler.getViewForPosition(i)
|
var position = (firstVisiblePosition + i) % itemCount
|
||||||
|
if (position < 0) {
|
||||||
|
position += itemCount
|
||||||
|
}
|
||||||
|
val view = recycler.getViewForPosition(position)
|
||||||
//添加到recycleView 中
|
//添加到recycleView 中
|
||||||
addView(view)
|
addView(view)
|
||||||
//测量
|
//测量
|
||||||
measureChild(view, 0, 0)
|
measureChild(view, 0, 0)
|
||||||
//布局
|
//布局
|
||||||
mLayout?.doLayout(this, mScrollOffset, movePercent, view, i - firstVisiblePosition)
|
mLayout?.doLayout(this, mScrollOffset, movePercent, view, i)
|
||||||
//做动画
|
//做动画
|
||||||
mAnimation?.doAnimation(movePercent, view, i - firstVisiblePosition)
|
mAnimation?.doAnimation(movePercent, view, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
//尝试更新当前item的位置并通知外界
|
//尝试更新当前item的位置并通知外界
|
||||||
updatePositionRecordAndNotify(firstVisiblePosition)
|
updatePositionRecordAndNotify(firstVisiblePosition)
|
||||||
|
|
||||||
//重用
|
//重用
|
||||||
if (firstVisiblePosition - 1 >= 0) {
|
val lastPosition = firstVisiblePosition - 1
|
||||||
val view = recycler.getViewForPosition(firstVisiblePosition - 1)
|
val lastView =
|
||||||
resetViewAnimateProperty(view)
|
recycler.getViewForPosition(if (lastPosition >= 0 || lastPosition % itemCount == 0) lastPosition % itemCount else lastPosition % itemCount + itemCount)
|
||||||
removeAndRecycleView(view, recycler)
|
resetViewAnimateProperty(lastView)
|
||||||
}
|
removeAndRecycleView(lastView, recycler)
|
||||||
if (lastVisiblePosition + 1 < itemCount) {
|
|
||||||
val view = recycler.getViewForPosition(lastVisiblePosition + 1)
|
val nextPosition = lastVisiblePosition + 1
|
||||||
resetViewAnimateProperty(view)
|
val nextView =
|
||||||
removeAndRecycleView(view, recycler)
|
recycler.getViewForPosition(if (nextPosition >= 0 || nextPosition % itemCount == 0) nextPosition % itemCount else nextPosition % itemCount + itemCount)
|
||||||
}
|
resetViewAnimateProperty(nextView)
|
||||||
|
removeAndRecycleView(nextView, recycler)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun resetViewAnimateProperty(view: View) {
|
private fun resetViewAnimateProperty(view: View) {
|
||||||
@@ -405,9 +423,13 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
scrollToCenter(targetPosition, view, true)
|
scrollToCenter(targetPosition, view, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun scrollToCenter(targetPosition: Int, recyclerView: RecyclerView, animation: Boolean) {
|
private fun scrollToCenter(
|
||||||
|
targetPosition: Int,
|
||||||
|
recyclerView: RecyclerView,
|
||||||
|
animation: Boolean
|
||||||
|
) {
|
||||||
val targetOffset = getPositionOffset(targetPosition)
|
val targetOffset = getPositionOffset(targetPosition)
|
||||||
when(mScrollOrientation) {
|
when (mScrollOrientation) {
|
||||||
ScrollOrientation.LEFT_TO_RIGHT, ScrollOrientation.RIGHT_TO_LEFT -> {
|
ScrollOrientation.LEFT_TO_RIGHT, ScrollOrientation.RIGHT_TO_LEFT -> {
|
||||||
if (animation) {
|
if (animation) {
|
||||||
recyclerView.smoothScrollBy(targetOffset - mScrollOffset, 0)
|
recyclerView.smoothScrollBy(targetOffset - mScrollOffset, 0)
|
||||||
@@ -426,14 +448,15 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getValidOffset(expectOffset: Int): Int {
|
private fun getValidOffset(expectOffset: Int): Int {
|
||||||
return when(mScrollOrientation) {
|
return when (mScrollOrientation) {
|
||||||
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.LEFT_TO_RIGHT -> Math.max(Math.min(width * (itemCount - 1), expectOffset), 0)
|
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.LEFT_TO_RIGHT ->
|
||||||
else -> Math.max(Math.min(height * (itemCount - 1), expectOffset), 0)
|
(width * (itemCount - 1)).coerceAtMost(expectOffset).coerceAtLeast(0)
|
||||||
|
else -> (height * (itemCount - 1)).coerceAtMost(expectOffset).coerceAtLeast(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getPositionOffset(position: Int): Int {
|
private fun getPositionOffset(position: Int): Int {
|
||||||
return when(mScrollOrientation) {
|
return when (mScrollOrientation) {
|
||||||
ScrollOrientation.RIGHT_TO_LEFT -> position * width
|
ScrollOrientation.RIGHT_TO_LEFT -> position * width
|
||||||
ScrollOrientation.LEFT_TO_RIGHT -> (itemCount - 1 - position) * width
|
ScrollOrientation.LEFT_TO_RIGHT -> (itemCount - 1 - position) * width
|
||||||
ScrollOrientation.BOTTOM_TO_TOP -> position * height
|
ScrollOrientation.BOTTOM_TO_TOP -> position * height
|
||||||
@@ -441,15 +464,6 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLastVisibleItemPosition(): Int {
|
|
||||||
val firstVisiblePosition = getFirstVisibleItemPosition()
|
|
||||||
return if (firstVisiblePosition + mVisibleItemCount > itemCount - 1) {
|
|
||||||
itemCount - 1
|
|
||||||
} else {
|
|
||||||
firstVisiblePosition + mVisibleItemCount
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getFirstVisibleItemMovePercent(): Float {
|
private fun getFirstVisibleItemMovePercent(): Float {
|
||||||
if (width == 0 || height == 0) {
|
if (width == 0 || height == 0) {
|
||||||
return 0f
|
return 0f
|
||||||
@@ -480,7 +494,7 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
|
|||||||
//当是 Fling 触发的时候
|
//当是 Fling 触发的时候
|
||||||
val triggerOrientation = mFlingOrientation
|
val triggerOrientation = mFlingOrientation
|
||||||
mFlingOrientation = FlingOrientation.NONE
|
mFlingOrientation = FlingOrientation.NONE
|
||||||
when(mScrollOrientation) {
|
when (mScrollOrientation) {
|
||||||
ScrollOrientation.RIGHT_TO_LEFT -> {
|
ScrollOrientation.RIGHT_TO_LEFT -> {
|
||||||
if (triggerOrientation == FlingOrientation.RIGHT_TO_LEFT) {
|
if (triggerOrientation == FlingOrientation.RIGHT_TO_LEFT) {
|
||||||
return position + 1
|
return position + 1
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
ext.kotlin_version = '1.2.60'
|
ext.kotlin_version = '1.6.10'
|
||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
jcenter()
|
jcenter()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.1.4'
|
classpath 'com.android.tools.build:gradle:4.2.2'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
classpath 'com.novoda:bintray-release:0.8.1'
|
classpath 'com.novoda:bintray-release:0.8.1'
|
||||||
}
|
}
|
||||||
@@ -29,4 +29,4 @@ allprojects {
|
|||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
tasks.getByPath(":StackLayoutManager:releaseAndroidJavadocs").enabled = false
|
//tasks.getByPath(":StackLayoutManager:releaseAndroidJavadocs").enabled = false
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
# http://www.gradle.org/docs/current/userguide/build_environment.html
|
||||||
# Specifies the JVM arguments used for the daemon process.
|
# Specifies the JVM arguments used for the daemon process.
|
||||||
# The setting is particularly useful for tweaking memory settings.
|
# The setting is particularly useful for tweaking memory settings.
|
||||||
|
android.enableJetifier=true
|
||||||
|
android.useAndroidX=true
|
||||||
org.gradle.jvmargs=-Xmx1536m
|
org.gradle.jvmargs=-Xmx1536m
|
||||||
# When configured, Gradle will run in incubating parallel mode.
|
# When configured, Gradle will run in incubating parallel mode.
|
||||||
# This option should only be used with decoupled projects. More details, visit
|
# This option should only be used with decoupled projects. More details, visit
|
||||||
|
|||||||
6
gradle/wrapper/gradle-wrapper.properties
vendored
6
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
|||||||
#Thu Jun 28 17:28:50 CST 2018
|
#Thu Feb 17 14:43:36 CST 2022
|
||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ apply plugin: 'kotlin-android'
|
|||||||
apply plugin: 'kotlin-android-extensions'
|
apply plugin: 'kotlin-android-extensions'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 31
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.littlemango.stacklayoutmanagermaster"
|
applicationId "com.littlemango.stacklayoutmanagermaster"
|
||||||
minSdkVersion 19
|
minSdkVersion 21
|
||||||
targetSdkVersion 27
|
targetSdkVersion 31
|
||||||
versionCode 6
|
versionCode 6
|
||||||
versionName "1.0.5"
|
versionName "1.0.5"
|
||||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
|
||||||
}
|
}
|
||||||
buildTypes {
|
buildTypes {
|
||||||
release {
|
release {
|
||||||
@@ -22,19 +22,19 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.kotlin_version = '1.2.60'
|
ext.kotlin_version = '1.6.10'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'com.android.support:appcompat-v7:27.1.1'
|
implementation 'androidx.appcompat:appcompat:1.4.1'
|
||||||
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'com.android.support.test:runner:1.0.2'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||||
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||||
implementation 'com.android.support:recyclerview-v7:27.1.1'
|
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||||
implementation 'com.android.support:cardview-v7:27.1.1'
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation project(':StackLayoutManager')
|
implementation project(':StackLayoutManager')
|
||||||
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
|
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
|
||||||
implementation 'com.android.support:design:27.1.1'
|
implementation 'com.google.android.material:material:1.5.0'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,11 @@
|
|||||||
package com.littlemango.stacklayoutmanagermaster
|
package com.littlemango.stacklayoutmanagermaster
|
||||||
|
|
||||||
import android.support.test.InstrumentationRegistry
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import android.support.test.runner.AndroidJUnit4
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
|
|
||||||
import org.junit.Assert.*
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Instrumented test, which will execute on an Android device.
|
* Instrumented test, which will execute on an Android device.
|
||||||
*
|
*
|
||||||
@@ -18,7 +16,7 @@ class ExampleInstrumentedTest {
|
|||||||
@Test
|
@Test
|
||||||
fun useAppContext() {
|
fun useAppContext() {
|
||||||
// Context of the app under test.
|
// Context of the app under test.
|
||||||
val appContext = InstrumentationRegistry.getTargetContext()
|
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
|
||||||
assertEquals("com.littlemango.stacklayoutmanagermaster", appContext.packageName)
|
assertEquals("com.littlemango.stacklayoutmanagermaster", appContext.packageName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,8 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
<activity android:name=".MainActivity">
|
<activity android:name=".MainActivity"
|
||||||
|
android:exported="true">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN" />
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package com.littlemango.stacklayoutmanagermaster;
|
package com.littlemango.stacklayoutmanagermaster;
|
||||||
|
|
||||||
import android.support.v7.widget.LinearLayoutManager;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
import com.littlemango.stacklayoutmanager.StackAnimation;
|
import com.littlemango.stacklayoutmanager.StackAnimation;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.littlemango.stacklayoutmanagermaster;
|
package com.littlemango.stacklayoutmanagermaster;
|
||||||
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
import android.support.v7.widget.RecyclerView;
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
import android.util.Log;
|
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
@@ -15,7 +15,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import com.afollestad.materialdialogs.MaterialDialog;
|
import com.afollestad.materialdialogs.MaterialDialog;
|
||||||
import com.littlemango.stacklayoutmanager.StackLayoutManager;
|
import com.littlemango.stacklayoutmanager.StackLayoutManager;
|
||||||
import com.littlemango.stacklayoutmanager.StackLayoutManager.ScrollOrientation;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
@@ -66,22 +66,22 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
resetRandom();
|
resetRandom();
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
mStackLayoutManager = new StackLayoutManager(ScrollOrientation.LEFT_TO_RIGHT);
|
mStackLayoutManager = new StackLayoutManager(StackLayoutManager.ScrollOrientation.LEFT_TO_RIGHT);
|
||||||
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
||||||
getSupportActionBar().setTitle("Picture 0");
|
getSupportActionBar().setTitle("Picture 0");
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
mStackLayoutManager = new StackLayoutManager(ScrollOrientation.RIGHT_TO_LEFT);
|
mStackLayoutManager = new StackLayoutManager(StackLayoutManager.ScrollOrientation.RIGHT_TO_LEFT);
|
||||||
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
||||||
getSupportActionBar().setTitle("Picture 0");
|
getSupportActionBar().setTitle("Picture 0");
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
mStackLayoutManager = new StackLayoutManager(ScrollOrientation.TOP_TO_BOTTOM);
|
mStackLayoutManager = new StackLayoutManager(StackLayoutManager.ScrollOrientation.TOP_TO_BOTTOM);
|
||||||
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
||||||
getSupportActionBar().setTitle("Picture 0");
|
getSupportActionBar().setTitle("Picture 0");
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
mStackLayoutManager = new StackLayoutManager(ScrollOrientation.BOTTOM_TO_TOP);
|
mStackLayoutManager = new StackLayoutManager(StackLayoutManager.ScrollOrientation.BOTTOM_TO_TOP);
|
||||||
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
mRecyclerView.setLayoutManager(mStackLayoutManager);
|
||||||
getSupportActionBar().setTitle("Picture 0");
|
getSupportActionBar().setTitle("Picture 0");
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<androidx.recyclerview.widget.RecyclerView
|
||||||
android:id="@+id/recycleView"
|
android:id="@+id/recycleView"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"/>
|
android:layout_height="match_parent"/>
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||||
android:id="@+id/floatButton"
|
android:id="@+id/floatButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -22,4 +22,4 @@
|
|||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent" />
|
app:layout_constraintEnd_toEndOf="parent" />
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:layout_width="270dp"
|
android:layout_width="270dp"
|
||||||
android:layout_height="400dp"
|
android:layout_height="400dp"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
@@ -17,4 +17,4 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:textSize="50sp"/>
|
android:textSize="50sp"/>
|
||||||
</android.support.v7.widget.CardView>
|
</androidx.cardview.widget.CardView>
|
||||||
|
|||||||
Reference in New Issue
Block a user