add ItemChangedListener

增加位置改变时候的回调
This commit is contained in:
Little Mango
2018-08-07 17:18:41 +08:00
parent 85de0bac5c
commit 8434f97789
7 changed files with 85 additions and 92 deletions

View File

@@ -1,47 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="WizardSettings">
<option name="children">
<map>
<entry key="vectorWizard">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="vectorAssetStep">
<value>
<PersistentState>
<option name="children">
<map>
<entry key="clipartAsset">
<value>
<PersistentState>
<option name="values">
<map>
<entry key="url" value="jar:file:/Applications/Android%20Studio.app/Contents/plugins/android/lib/android.jar!/images/material_design_icons/toggle/ic_star_black_24dp.xml" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
<option name="values">
<map>
<entry key="color" value="ffffff" />
<entry key="outputName" value="ic_star_black_24dp" />
<entry key="sourceFile" value="$USER_HOME$" />
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</PersistentState>
</value>
</entry>
</map>
</option>
</component>
</project>

Binary file not shown.

View File

@@ -1,17 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="BUNDLED:(bundled):Google Checks" />
<entry key="checkstyle-version" value="8.7" />
<entry key="copy-libs" value="false" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnly" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
</project>

14
.idea/misc.xml generated
View File

@@ -1,5 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="CheckStyle-IDEA">
<option name="configuration">
<map>
<entry key="active-configuration" value="BUNDLED:(bundled):Google Checks" />
<entry key="checkstyle-version" value="8.7" />
<entry key="copy-libs" value="false" />
<entry key="location-0" value="BUNDLED:(bundled):Sun Checks" />
<entry key="location-1" value="BUNDLED:(bundled):Google Checks" />
<entry key="scan-before-checkin" value="false" />
<entry key="scanscope" value="JavaOnly" />
<entry key="suppress-errors" value="false" />
</map>
</option>
</component>
<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" />

4
.idea/modules.xml generated
View File

@@ -2,8 +2,8 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/StackLayoutManager/StackLayoutManager.iml" filepath="$PROJECT_DIR$/StackLayoutManager/StackLayoutManager.iml" /> <module fileurl="file://$PROJECT_DIR$/StackLayoutManager.iml" filepath="$PROJECT_DIR$/StackLayoutManager.iml" />
<module fileurl="file://$PROJECT_DIR$/StackLayoutManagerMaster.iml" filepath="$PROJECT_DIR$/StackLayoutManagerMaster.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" /> <module fileurl="file://$PROJECT_DIR$/sample/sample.iml" filepath="$PROJECT_DIR$/sample/sample.iml" />
</modules> </modules>
</component> </component>

View File

@@ -2,8 +2,7 @@ package com.littlemango.stacklayoutmanager
import android.support.annotation.IntRange import android.support.annotation.IntRange
import android.support.v7.widget.RecyclerView import android.support.v7.widget.RecyclerView
import android.support.v7.widget.RecyclerView.SCROLL_STATE_DRAGGING import android.support.v7.widget.RecyclerView.*
import android.support.v7.widget.RecyclerView.SCROLL_STATE_IDLE
import android.view.View import android.view.View
import android.view.ViewGroup import android.view.ViewGroup
@@ -41,28 +40,17 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
//fling的方向用来判断是前翻还是后翻 //fling的方向用来判断是前翻还是后翻
private var mFlingOrientation = FlingOrientation.NONE private var mFlingOrientation = FlingOrientation.NONE
init { //当前所处item对应的位置
mScrollOffset = when(mScrollOrientation) { private var itemPosition = 0
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.BOTTOM_TO_TOP -> 0
else -> Int.MAX_VALUE
}
if (StackAnimation::class.java.isAssignableFrom(animation)) { //判断item位置是否发生了改变
try { private var isItemPositionChanged = false
val cla = animation.getDeclaredConstructor(ScrollOrientation::class.java, Int::class.javaPrimitiveType)
mAnimation = cla.newInstance(scrollOrientation, visibleCount) as StackAnimation //item 位置发生改变的回调
} catch (e: Exception) { private var itemChangedListener: ItemChangedListener? = null
e.printStackTrace()
} interface ItemChangedListener {
} fun onItemChanged(position: Int)
if (StackLayout::class.java.isAssignableFrom(layout)) {
try {
val cla = layout.getDeclaredConstructor(ScrollOrientation::class.java, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType)
mLayout = cla.newInstance(scrollOrientation, visibleCount, 30) as StackLayout
} catch (e: Exception) {
e.printStackTrace()
}
}
} }
/** /**
@@ -173,12 +161,43 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
} }
} }
/**
* 设置 item 位置改变时触发的回调
*/
fun setItemChangedListener(listener: ItemChangedListener) {
itemChangedListener = listener
}
constructor(scrollOrientation: ScrollOrientation) : this(scrollOrientation, 3, DefaultAnimation::class.java, DefaultLayout::class.java) constructor(scrollOrientation: ScrollOrientation) : this(scrollOrientation, 3, DefaultAnimation::class.java, DefaultLayout::class.java)
constructor(scrollOrientation: ScrollOrientation, visibleCount: Int) : this(scrollOrientation, visibleCount, DefaultAnimation::class.java, DefaultLayout::class.java) constructor(scrollOrientation: ScrollOrientation, visibleCount: Int) : this(scrollOrientation, visibleCount, DefaultAnimation::class.java, DefaultLayout::class.java)
constructor() : this(ScrollOrientation.RIGHT_TO_LEFT) constructor() : this(ScrollOrientation.RIGHT_TO_LEFT)
init {
mScrollOffset = when(mScrollOrientation) {
ScrollOrientation.RIGHT_TO_LEFT, ScrollOrientation.BOTTOM_TO_TOP -> 0
else -> Int.MAX_VALUE
}
if (StackAnimation::class.java.isAssignableFrom(animation)) {
try {
val cla = animation.getDeclaredConstructor(ScrollOrientation::class.java, Int::class.javaPrimitiveType)
mAnimation = cla.newInstance(scrollOrientation, visibleCount) as StackAnimation
} catch (e: Exception) {
e.printStackTrace()
}
}
if (StackLayout::class.java.isAssignableFrom(layout)) {
try {
val cla = layout.getDeclaredConstructor(ScrollOrientation::class.java, Int::class.javaPrimitiveType, Int::class.javaPrimitiveType)
mLayout = cla.newInstance(scrollOrientation, visibleCount, 30) as StackLayout
} catch (e: Exception) {
e.printStackTrace()
}
}
}
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)
@@ -211,7 +230,6 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
} }
} }
} }
calculateAndScrollToTarget(view) calculateAndScrollToTarget(view)
} }
return mPagerMode return mPagerMode
@@ -293,6 +311,19 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
scrollToCenter(position, recyclerView, true) scrollToCenter(position, recyclerView, true)
} }
private fun updatePositionRecordAndNotify(position: Int) {
if (itemChangedListener == null) {
return
}
if (position != itemPosition) {
isItemPositionChanged = true
itemPosition = position
itemChangedListener?.onItemChanged(itemPosition)
} else {
isItemPositionChanged = false
}
}
private fun handleScrollBy(offset: Int, recycler: RecyclerView.Recycler): Int { private fun handleScrollBy(offset: Int, recycler: RecyclerView.Recycler): Int {
//期望值,不得超过最大最小值,所以期望值不一定等于实际值 //期望值,不得超过最大最小值,所以期望值不一定等于实际值
val expectOffset = mScrollOffset + offset val expectOffset = mScrollOffset + offset
@@ -333,6 +364,9 @@ class StackLayoutManager(scrollOrientation: ScrollOrientation,
mAnimation?.doAnimation(movePercent, view, i - firstVisiblePosition) mAnimation?.doAnimation(movePercent, view, i - firstVisiblePosition)
} }
//尝试更新当前item的位置并通知外界
updatePositionRecordAndNotify(firstVisiblePosition)
//重用 //重用
if (firstVisiblePosition - 1 >= 0) { if (firstVisiblePosition - 1 >= 0) {
val view = recycler.getViewForPosition(firstVisiblePosition - 1) val view = recycler.getViewForPosition(firstVisiblePosition - 1)

View File

@@ -31,10 +31,13 @@ public class MainActivity extends AppCompatActivity {
private String[] selectItems; private String[] selectItems;
private Toast mToast;
@Override @Override
protected void onCreate(@Nullable Bundle savedInstanceState) { protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); setContentView(R.layout.activity_main);
mToast = Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT);
mRecyclerView = findViewById(R.id.recycleView); mRecyclerView = findViewById(R.id.recycleView);
mStackLayoutManager = new StackLayoutManager(); mStackLayoutManager = new StackLayoutManager();
@@ -114,12 +117,18 @@ public class MainActivity extends AppCompatActivity {
.show(); .show();
} }
}); });
mStackLayoutManager.setItemChangedListener(new StackLayoutManager.ItemChangedListener() {
@Override
public void onItemChanged(int position) {
mToast.setText("first visible item position is " + position);
mToast.show();
}
});
} }
class StackLayoutAdapter extends RecyclerView.Adapter<StackLayoutAdapter.StackHolder> { class StackLayoutAdapter extends RecyclerView.Adapter<StackLayoutAdapter.StackHolder> {
Toast mToast = Toast.makeText(MainActivity.this, "", Toast.LENGTH_SHORT);
@NonNull @NonNull
@Override @Override
public StackHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) { public StackHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {