我在布局中使用的是一个 < code> HorizontalScrollView , 我需要确认用户已到达滚动的起始点和终点 。
对于 ListView
,我尝试了 onScrollListener
,并找到了滚动的起始点和终点。
我试图在我的 < code> scrollview 中也这样做,但似乎是不可能的。 有没有其他可能的方法实现我所需要的。
我在布局中使用的是一个 < code> HorizontalScrollView , 我需要确认用户已到达滚动的起始点和终点 。
对于 ListView
,我尝试了 onScrollListener
,并找到了滚动的起始点和终点。
我试图在我的 < code> scrollview 中也这样做,但似乎是不可能的。 有没有其他可能的方法实现我所需要的。
每个查看实例都呼叫 getViewTreeviser ()
。 现在, 当持有 ViewTreeviser
实例时, 您可以使用 addonScroll- changedListener ()
的方法, 向它添加一个 onScroll- changedListener ()
。
您可查看有关此类的更多信息
This might be very useful.
Use 这里的导出水平鼠标浏览器是我为处理滚动和滚动结束的通知而写的。 当用户停止主动滚动 和 时, 当用户放行后完全减速时, 它会正确处理 : 您可以使用 < code> NestedScrollView 而不是 在接受的答案之外, 您需要持有听众的引用, 并在不需要时删除。 否则, 您将获得对您的滚动视图和内存泄漏的无效指针例外( 被接受的回答的评论中提及 ) < / em > 。 您可以在活动/分裂中执行 OnScroll ChangedListener 。 您的视图准备好后添加到滚动View 中 。 不再需要时删除收听器( 即Pause ()) ) 如果您想知道视图的滚动位置,那么您可以在视图类中使用以下扩展功能: 别忘了,在Android 实际中,你想把一切都变回DP: 复制粘贴 : Doco: 音乐家: 您可以定义一个自定义的滚动滚动类, 并在此滚动时添加一个界面 : Kotlin 用户在寻找普通 < code> scrollView 执行的解决方案 : 作为的延伸至 视图( 创建一个新的 Kotlin 文件, 将您的软件包引用维持在第1行) : XML 视图执行 : 活动/分散执行:
I m relatively new to Android development. I m developing an app with a ListView. I ve followed the info in #1338475 and have my app recognizing the fling gesture, but after the gesture is complete, ...
I m converting my code from using Handler to AsyncTask. The latter is great at what it does - asynchronous updates and handling of results in the main UI thread. What s unclear to me is how to handle ...
I want to be able to download a file with a particular extension from the net, and have it passed to my application to deal with it, but I haven t been able to figure out the intent filter. The ...
I am quite impressed by the workflow I follow when developing Android applications: Define a layout in an xml file and then write all the code in a code-behind style. Is there an equivalent style for ...
To draw landscapes, backgrounds with patterns etc, we used TiledLayer in J2ME. Is there an android counterpart for that. Does android provide an option to set such tiled patterns in the layout XML?
When following the Android Open Source Project instructions on installing repo for use with Git, after running the repo init command, I run into this error:
/c/Users/Andrew Rabon/bin/repo: line
...
I read in the Android documentation that by setting my Activity s launchMode property to singleTop OR by adding the FLAG_ACTIVITY_SINGLE_TOP flag to my Intent, that calling startActivity(intent) would ...
I have pretty good skills in PHP , Mysql and Javascript for a junior developer. If I wanted to try my hand as Android Development do you think I might find it tough ?
Also what new languages would I ...
NestedScrollView
instead of ScrollView
. Support Library 23.1 introduced an OnScrollChangeListener
to NestedScrollView
.
So you can do something like this. myScrollView.setOnScrollChangeListener(new NestedScrollView.OnScrollChangeListener() {
@Override
public void onScrollChange(NestedScrollView v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {
Log.d("ScrollView","scrollX_"+scrollX+"_scrollY_"+scrollY+"_oldScrollX_"+oldScrollX+"_oldScrollY_"+oldScrollY);
//Do something
}
});
public class ObservableHorizontalScrollView extends HorizontalScrollView {
public interface OnScrollListener {
public void onScrollChanged(ObservableHorizontalScrollView scrollView, int x, int y, int oldX, int oldY);
public void onEndScroll(ObservableHorizontalScrollView scrollView);
}
private boolean mIsScrolling;
private boolean mIsTouching;
private Runnable mScrollingRunnable;
private OnScrollListener mOnScrollListener;
public ObservableHorizontalScrollView(Context context) {
this(context, null, 0);
}
public ObservableHorizontalScrollView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public ObservableHorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
public boolean onTouchEvent(MotionEvent ev) {
int action = ev.getAction();
if (action == MotionEvent.ACTION_MOVE) {
mIsTouching = true;
mIsScrolling = true;
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (mIsTouching && !mIsScrolling) {
if (mOnScrollListener != null) {
mOnScrollListener.onEndScroll(this);
}
}
mIsTouching = false;
}
return super.onTouchEvent(ev);
}
@Override
protected void onScrollChanged(int x, int y, int oldX, int oldY) {
super.onScrollChanged(x, y, oldX, oldY);
if (Math.abs(oldX - x) > 0) {
if (mScrollingRunnable != null) {
removeCallbacks(mScrollingRunnable);
}
mScrollingRunnable = new Runnable() {
public void run() {
if (mIsScrolling && !mIsTouching) {
if (mOnScrollListener != null) {
mOnScrollListener.onEndScroll(ObservableHorizontalScrollView.this);
}
}
mIsScrolling = false;
mScrollingRunnable = null;
}
};
postDelayed(mScrollingRunnable, 200);
}
if (mOnScrollListener != null) {
mOnScrollListener.onScrollChanged(this, x, y, oldX, oldY);
}
}
public OnScrollListener getOnScrollListener() {
return mOnScrollListener;
}
public void setOnScrollListener(OnScrollListener mOnEndScrollListener) {
this.mOnScrollListener = mOnEndScrollListener;
}
}
scrollView
。 但是, 当使用 Kotlin Lambda 时, 它不会知道您想要 NestedScrollView s < code> s < code> s < set> OnScrollChangeListener 而不是在 View 的参数( 这是 API 级别 23) 。 您可以将第一个参数指定为 NestedScrollView 。nestedScrollView.setOnScrollChangeListener { _: NestedScrollView, scrollX: Int, scrollY: Int, _: Int, _: Int ->
Log.d("ScrollView", "Scrolled to $scrollX, $scrollY")
}
MyFragment : ViewTreeObserver.OnScrollChangedListener
scrollView.viewTreeObserver.addOnScrollChangedListener(this)
scrollView.viewTreeObserver.removeOnScrollChangedListener(this)
fun View?.onScroll(callback: (x: Int, y: Int) -> Unit) {
var oldX = 0
var oldY = 0
this?.viewTreeObserver?.addOnScrollChangedListener {
if (oldX != scrollX || oldY != scrollY) {
callback(scrollX, scrollY)
oldX = scrollX
oldY = scrollY
}
}
}
2022 answer - it s now trivial:
ScrollView anyScrollView;
...
anyScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
@Override
public void onScrollChange(View view, int x, int y, int oldX, int oldY) {
Log.d("yo", "it works " + y + " " + x);
}
});
public void onScrollChange(View view, int x, int y, int oldX, int oldY) {
float ydp =
y / getBaseContext().getResources().getDisplayMetrics().density;
Log.d("yo", "it works " + ydp);
}
anyScrollView.setOnScrollChangeListener(new View.OnScrollChangeListener() {
float dsy = getBaseContext().getResources().getDisplayMetrics().density;
@Override
public void onScrollChange(View view, int x, int y, int oldX, int oldY) {
float ydp = y / dsy;
Log.d("yo", "offset " + ydp);
}
});
public class ScrollChangeListenerScrollView extends HorizontalScrollView {
private MyScrollListener mMyScrollListener;
public ScrollChangeListenerScrollView(Context context) {
super(context);
}
public ScrollChangeListenerScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public ScrollChangeListenerScrollView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public void setOnMyScrollListener(MyScrollListener myScrollListener){
this.mMyScrollListener = myScrollListener;
}
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if(mMyScrollListener!=null){
mMyScrollListener.onScrollChange(this,l,t,oldl,oldt);
}
}
public interface MyScrollListener {
void onScrollChange(View view,int scrollX,int scrollY,int oldScrollX, int oldScrollY);
}
}
// --------Start Scroll Bar Slide--------
final HorizontalScrollView xHorizontalScrollViewHeader = (HorizontalScrollView) findViewById(R.id.HorizontalScrollViewHeader);
final HorizontalScrollView xHorizontalScrollViewData = (HorizontalScrollView) findViewById(R.id.HorizontalScrollViewData);
xHorizontalScrollViewData.getViewTreeObserver().addOnScrollChangedListener(new ViewTreeObserver.OnScrollChangedListener() {
@Override
public void onScrollChanged() {
int scrollX; int scrollY;
scrollX=xHorizontalScrollViewData.getScrollX();
scrollY=xHorizontalScrollViewData.getScrollY();
xHorizontalScrollViewHeader.scrollTo(scrollX, scrollY);
}
});
// ---------End Scroll Bar Slide---------
import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.view.MotionEvent
import android.widget.ScrollView
import kotlin.math.abs
class ScrollViewWithEndFunc (
context: Context?,
attrs: AttributeSet?,
defStyle: Int
) : ScrollView(context, attrs, defStyle) {
constructor(context: Context?) : this(context, null, 0) {}
constructor(context: Context?, attrs: AttributeSet?) : this(context, attrs, 0) {}
interface OnScrollListener {
fun onScrollChanged(scrollView: ScrollViewWithEndFunc?, x: Int, y: Int, oldX: Int, oldY: Int)
fun onEndScroll(scrollView: ScrollViewWithEndFunc?)
}
private var isScrolling = false
private var isTouching = false
private var scrollingRunnable: Runnable? = null
private var onScrollListener: OnScrollListener? = null
fun setOnScrollListener(onScrollListener: OnScrollListener) {
this.onScrollListener = onScrollListener
}
fun removeOnScrollListener() {
this.onScrollListener = null
}
@SuppressLint("ClickableViewAccessibility")
override fun onTouchEvent(ev: MotionEvent): Boolean {
val action = ev.action
if (action == MotionEvent.ACTION_MOVE) {
isTouching = true; isScrolling = true
} else if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
if (isTouching && !isScrolling) {
onScrollListener?.onEndScroll(this)
}
isTouching = false
}
return super.onTouchEvent(ev)
}
override fun onScrollChanged(x: Int, y: Int, oldX: Int, oldY: Int) {
super.onScrollChanged(x, y, oldX, oldY)
if (abs(oldY - y) > 0) {
scrollingRunnable?.let { removeCallbacks(it) }
scrollingRunnable = Runnable {
if (isScrolling && !isTouching) {
onScrollListener?.onEndScroll(this@ScrollViewWithEndFunc)
}
isScrolling = false
scrollingRunnable = null
}
postDelayed(scrollingRunnable, 200)
}
onScrollListener?.onScrollChanged(this, x, y, oldX, oldY)
}
}
<your.package.here.ScrollViewWithEndFunc
android:id="@+id/scrollview_main_dashboard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fillViewport="true">
scrollviewMainDashboard.setOnScrollListener(object : ScrollViewWithEndFunc.OnScrollListener {
override fun onScrollChanged(scrollView: ScrollViewWithEndFunc?, x: Int, y: Int, oldX: Int, oldY: Int) { }
override fun onEndScroll(scrollView: ScrollViewWithEndFunc?) {
/* Scroll ended, handle here */
})