在Android中创build一个locking的ScrollView

我试图在Android中实现一个ScrollView ,在当前滚动位置上方添加一个项目时不滚动。

ScrollView的默认实现行为如下:

在当前滚动位置上添加一个项目: 在这里输入图像说明

在当前滚动位置添加一个项目: 在这里输入图像说明

如何在添加当前滚动位置之上的项目之前“locking” ScrollView

这是我的布局文件,我目前覆盖了ScrollViewLinearLayout ,但还没有做任何改动。

 <LinearLayout android:layout_height="fill_parent" android:orientation="vertical" android:layout_width="fill_parent"> <LinearLayout android:id="@+id/LinearLayout02" android:layout_height="wrap_content" android:layout_width="fill_parent" android:layout_alignParentBottom="true"> <Button android:id="@+id/Button02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Add To Top" android:onClick="addToStart"> </Button> <Button android:id="@+id/Button03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_weight="1" android:text="Add to End" android:onClick="addToEnd"> </Button> </LinearLayout> <com.poc.scroller.locable.lockablescrollerpoc.LockedScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:fillViewport="true" android:scrollbarAlwaysDrawVerticalTrack="true" android:verticalScrollbarPosition="right" android:fadeScrollbars="false" android:background="@color/scrollColor"> <com.poc.scroller.locable.lockablescrollerpoc.LockedLinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:id="@+id/Container"> </com.poc.scroller.locable.lockablescrollerpoc.LockedLinearLayout> </com.poc.scroller.locable.lockablescrollerpoc.LockedScrollView> </LinearLayout> </android.support.constraint.ConstraintLayout> 

示例源代码: https //github.com/Amaros90/android-lockable-scroller-poc

谢谢!

Solutions Collecting From Web of "在Android中创build一个locking的ScrollView"

通过使用LinearLayoutScrollY并重置ScrollViewaddOnLayoutChangeListener ,可以轻松获得相反的行为。 这是你的ScrollViewActivity.onCreate的实现

 protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.scrollview); _linearLayout = (LockedLinearLayout)findViewById(R.id.Container); _scrollView = (LockedScrollView)findViewById(R.id.ScrollView); _layoutInflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); _linearLayout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { _scrollView.scrollTo(0, _scrollView.getScrollY() + (bottom - oldBottom )); } }); addExampleImage(10, _linearLayout); } 

然后,您可以轻松标记addToEnd函数或检查添加子项的位置,以避免在将某个子项添加到底部时更改滚动项。

您可以尝试使用RecyclerView并实现onDataSetChanged() 。 然后检测是否add to TOPadd to ENDbutton。 然后使用scrollToPositionWithOffset(int, int)来pipe理滚动。

例如:

 //Scroll item 3 to 20 pixels from the top linearLayoutManager.scrollToPositionWithOffset(3, 20); 

为了恢复RecyclerView的滚动位置,这是如何保存滚动位置(方法scrollToPositionWithOffset(int, int)的两个参数):

 int index = linearLayoutManager.findFirstVisibleItemPosition(); View v = linearLayoutManager.getChildAt(0); int top = (v == null) ? 0 : (v.getTop() - linearLayoutManager.getPaddingTop()) 

实施这个为我工作。 您可以查看我在原始问题中添加的示例应用程序。

 public class LockableScrollView extends ScrollView { private boolean _enabled = true; public LockableScrollView(Context context, AttributeSet attrs) { super(context, attrs); super.setFillViewport(true); } @Override public void addView(View layout, ViewGroup.LayoutParams params) { super.addView(layout, params); ((ViewGroup)layout).setOnHierarchyChangeListener(new OnHierarchyChangeListener() { @Override public void onChildViewAdded(View layout, View item) { if (_enabled) { item.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View item, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { item.removeOnLayoutChangeListener(this); int scrollViewY = ((LockableScrollView)item.getParent().getParent()).getScrollY(); int layoutPosition = ((View)item.getParent()).getTop(); boolean shouldScroll = item.getTop() + layoutPosition <= scrollViewY || item.getBottom() + getTop() <= scrollViewY; if (shouldScroll) { final int childViewHeight = item.getHeight(); ((View)item.getParent()).addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View layout, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { layout.removeOnLayoutChangeListener(this); LockableScrollView scrollView = ((LockableScrollView)layout.getParent()); scrollView.scrollTo(scrollView.getScrollX(), scrollView.getScrollY() + childViewHeight); } }); } } }); } } @Override public void onChildViewRemoved(View layout, View item) { if (_enabled) { int scrollViewY = ((LockableScrollView)layout.getParent()).getScrollY(); int layoutPosition = layout.getTop(); boolean shouldScroll = item.getTop() + layoutPosition <= scrollViewY || item.getBottom() + getTop() <= scrollViewY; if (shouldScroll) { final int childViewHeight = item.getHeight(); layout.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View layout, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) { layout.removeOnLayoutChangeListener(this); LockableScrollView scrollView = ((LockableScrollView)layout.getParent()); scrollView.scrollTo(scrollView.getScrollX(), scrollView.getScrollY() - childViewHeight); } }); } } } }); } } 

你可以轻松做到这一点..

首先在onclick事件中使用getFirstVisiblePosition()存储int值

例。

添加元素buttononclick做这个—

int currentpos = recycleview.getFirstVisiblePosition();

现在插入elment到list / recyclerview后

recyclerview.scrolltoposition(currentpos);

多数民众赞成在尝试,如果你想这样做没有错误..

祝你好运 :)