我可以在 Android 中以编程方式滚动 ScrollView 吗?

有没有办法以编程方式将 ScrollView滚动到某个位置?

我已经创建了动态 TableLayout,这是放置在一个 ScrollView。因此,我希望在一个特定的操作(如点击按钮等) ,特定的行应该自动滚动到顶部的位置。

有可能吗?

187445 次浏览

尝试使用 scrollTo方法 更多信息

使用这样的东西:

mScrollView.scrollBy(10, 10);

或者

mScrollView.scrollTo(10, 10);
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());

或者

sv.scrollTo(5, 10);

来自 Pragna 的答案并不总是奏效,试试这个:

mScrollView.post(new Runnable() {
public void run() {
mScrollView.scrollTo(0, mScrollView.getBottom());
}
});

或者

mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
}
});

如果你想滚动开始

mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_UP);
}
});

我希望 scrollView 在 onCreateView ()之后直接滚动(而不是在按钮点击之后)。为了让它工作,我需要使用 ViewTreeObserver:

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
});

但是要注意,每次布局时都会调用这个监听器(例如,如果你设置了一个不可见或类似的视图) ,所以如果你不再需要这个监听器,不要忘记删除它:

SDK 上的 public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) LVl < 16

或者

SDK 中的 public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim) Lvl > = 16

注意: 如果你已经在一个线程,你必须作出一个新的帖子线程,否则它不滚动新的长高度,直到完全结束(对我来说)。 例如:

void LogMe(final String s){
runOnUiThread(new Runnable() {
public void run() {
connectionLog.setText(connectionLog.getText() + "\n" + s);
final ScrollView sv = (ScrollView)connectLayout.findViewById(R.id.scrollView);
sv.post(new Runnable() {
public void run() {
sv.fullScroll(sv.FOCUS_DOWN);
/*
sv.scrollTo(0,sv.getBottom());
sv.scrollBy(0,sv.getHeight());*/
}
});
}
});
}

如果你想立即滚动,你可以使用:

ScrollView scroll= (ScrollView)findViewById(R.id.scroll);
scroll.scrollTo(0, scroll.getBottom());


OR


scroll.fullScroll(View.FOCUS_DOWN);


OR


scroll.post(new Runnable() {
@Override
public void run() {
scroll.fullScroll(View.FOCUS_DOWN);
}
});

或者,如果你想平滑而缓慢地滚动,那么你可以使用以下方法:

private void sendScroll(){
final Handler handler = new Handler();
new Thread(new Runnable() {
@Override
public void run() {
try {Thread.sleep(100);} catch (InterruptedException e) {}
handler.post(new Runnable() {
@Override
public void run() {
scrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
}).start();
}

我使用带 sv.fullScroll 的 Runnable (View.FOCUS _ DOWN) ; 这个方法可以很好的解决当前的问题,但是这个方法使得 ScrollView 从整个屏幕上获取焦点,如果你每次都使用自动滚动,那么没有 EditText 能够从用户那里接收信息,我的解决方案是在 runnable 下使用一个不同的代码:

ScrollTo (0,sv.getBottom () + sv.getScrollY ()) ;

在不失重要观点的前提下做出相同的决定

你好。

我用这个工具滚动到 ScrollView 的底部(里面有一个 TextView) :

(我把它放在一个更新 TextView 的方法上)

final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
myScrollView.post(new Runnable() {
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});

添加另一个不涉及坐标的答案。

这会使你想要的视角集中起来(但不是到顶部) :

  yourView.getParent().requestChildFocus(yourView,yourView);

Public void RequestChildFocus (View child,View focus)

Child -此 ViewParent 的需要焦点的子级。此视图将包含焦点视图。真正有焦点的不一定是观点。

焦点 -实际上有焦点的孩子的后代的观点

每个人都在发布这么复杂的答案。

我找到了一个简单的答案,可以很好地滚动到底部:

final ScrollView myScroller = (ScrollView) findViewById(R.id.myScrollerView);


// Scroll views can only have 1 child, so get the first child's bottom,
// which should be the full size of the whole content inside the ScrollView
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );

如果有必要,您可以将上面的第二行代码放入一个可运行代码中:

myScroller.post( new Runnable() {
@Override
public void run() {
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
}
}

为了找到这个简单的解决方案,我做了大量的研究和尝试。我希望它也能帮到你! :)

我想到了一个好办法

                scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.scrollBy(0, childView.getHeight());
}
}, 100);

这里有很多好的答案,但我只想补充一点。有时候,您希望将 ScrollView 滚动到布局的特定视图,而不是完全滚动到顶部或底部。

一个简单的例子: 在注册表单中,如果用户在表单的编辑文本未被填充时点击“注册”按钮,那么您需要滚动到该特定的编辑文本,以告诉用户他必须填充该字段。

在这种情况下,你可以这样做:

scrollView.post(new Runnable() {
public void run() {
scrollView.scrollTo(0, editText.getBottom());
}
});

或者,如果你想要一个平滑的卷轴,而不是一个即时的卷轴:

scrollView.post(new Runnable() {
public void run() {
scrollView.smoothScrollTo(0, editText.getBottom());
}
});

显然,您可以使用任何类型的视图而不是 EditText。注意,getBottom ()根据视图的父布局返回视图的坐标,因此 ScrollView 中使用的所有视图应该只有一个父视图(例如,一个线性布局)。

如果在 ScrollView 的子元素中有多个父元素,我找到的唯一解决方案是在父元素视图中调用 requestChildFocus:

editText.getParent().requestChildFocus(editText, editText);

但在这种情况下,你不能有一个平滑的滚动。

我希望这个答案能帮助有同样问题的人。

翻页:

ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);

你可以的。

假设你有一个 Layout在里面,你有很多个 Views。因此,如果您想以编程方式滚动到任何 View,您必须编写以下代码片段:

例如:

Content _ main. xml

<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="wrap_content">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">


<Button
android:id="@+id/btn"
android:layout_width="match_parent"
android:layout_height="wrap_content" />


<TextView
android:id="@+id/txtView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />


</LinearLayout>
</ScrollView>

MainActivity.java

ScrollView scrollView = (ScrollView) findViewById(R.id.scrollView);
Button btn = (Button) findViewById(R.id.ivEventBanner);
TextView txtView = (TextView) findViewById(R.id.ivEditBannerImage);

如果你想滚动到一个特定的 View,假设是 Txtview,在这种情况下,只需写:

scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());

你完蛋了。

对我有用

mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
});
private int totalHeight = 0;


ViewTreeObserver ScrollTr = loutMain.getViewTreeObserver();
ScrollTr.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
loutMain.getViewTreeObserver().removeGlobalOnLayoutListener(this);
} else {
loutMain.getViewTreeObserver().removeOnGlobalLayoutListener(this);
}
TotalHeight = loutMain.getMeasuredHeight();


}
});


scrollMain.smoothScrollTo(0, totalHeight);
I had to create Interface


public interface ScrollViewListener {
void onScrollChanged(ScrollViewExt scrollView,
int x, int y, int oldx, int oldy);
}


import android.content.Context;
import android.util.AttributeSet;
import android.widget.ScrollView;


public class CustomScrollView extends ScrollView {
private ScrollViewListener scrollViewListener = null;
public ScrollViewExt(Context context) {
super(context);
}


public CustomScrollView (Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}


public CustomScrollView (Context context, AttributeSet attrs) {
super(context, attrs);
}


public void setScrollViewListener(ScrollViewListener scrollViewListener) {
this.scrollViewListener = scrollViewListener;
}


@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (scrollViewListener != null) {
scrollViewListener.onScrollChanged(this, l, t, oldl, oldt);
}
}
}








<"Your Package name ".CustomScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusableInTouchMode="true"
android:scrollbars="vertical">


private CustomScrollView scrollView;


scrollView = (CustomScrollView)mView.findViewById(R.id.scrollView);
scrollView.setScrollViewListener(this);




@Override
public void onScrollChanged(ScrollViewExt scrollView, int x, int y, int oldx, int oldy) {
// We take the last son in the scrollview
View view = (View) scrollView.getChildAt(scrollView.getChildCount() - 1);
int diff = (view.getBottom() - (scrollView.getHeight() + scrollView.getScrollY()));


// if diff is zero, then the bottom has been reached
if (diff == 0) {
// do stuff
//TODO keshav gers
pausePlayer();
videoFullScreenPlayer.setVisibility(View.GONE);


}
}