Est-il possible de faire défiler un ScrollView
par programme jusqu'à une certaine position?
J'ai créé un TableLayout
dynamique qui est placé dans un ScrollView
. Je souhaite donc que pour une action spécifique (comme cliquer sur un bouton, etc.), la ligne en question défile automatiquement vers la première position.
C'est possible?
ScrollView sv = (ScrollView)findViewById(R.id.scrl);
sv.scrollTo(0, sv.getBottom());
ou
sv.scrollTo(5, 10);
La réponse de Pragna ne fonctionne pas toujours, essayez ceci:
mScrollView.post(new Runnable() {
public void run() {
mScrollView.scrollTo(0, mScrollView.getBottom());
}
});
ou
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_DOWN);
}
});
si vous voulez faire défiler pour commencer
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(mScrollView.FOCUS_UP);
}
});
Je voulais que le scrollView défile directement après onCreateView () (pas après, par exemple, un clic de bouton). Pour que cela fonctionne, je devais utiliser un ViewTreeObserver:
mScrollView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
mScrollView.post(new Runnable() {
public void run() {
mScrollView.fullScroll(View.FOCUS_DOWN);
}
});
}
});
Mais attention, cela sera appelé à chaque fois que quelque chose sera mis en page (par exemple, si vous définissez une vue invisible ou similaire), alors n'oubliez pas de supprimer cet écouteur si vous n'en avez plus besoin avec:
public void removeGlobalOnLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
sur SDK Lvl <16
ou
public void removeOnGlobalLayoutListener (ViewTreeObserver.OnGlobalLayoutListener victim)
in SDK Lvl> = 16
Utilisez quelque chose comme ceci:
mScrollView.scrollBy(10, 10);
ou
mScrollView.scrollTo(10, 10);
Il y a beaucoup de bonnes réponses ici, mais je veux seulement ajouter une chose. Il arrive parfois que vous souhaitiez faire défiler votre ScrollView vers une vue spécifique de la présentation, au lieu d'un défilement complet vers le haut ou le bas.
Un exemple simple: dans un formulaire d'inscription, si l'utilisateur clique sur le bouton "Inscription" lorsqu'un texte d'édition du formulaire n'est pas rempli, vous souhaitez accéder à ce texte d'édition spécifique pour indiquer à l'utilisateur qu'il doit remplir ce champ.
Dans ce cas, vous pouvez faire quelque chose comme ça:
scrollView.post(new Runnable() {
public void run() {
scrollView.scrollTo(0, editText.getBottom());
}
});
ou, si vous voulez un défilement régulier au lieu d’un défilement instantané:
scrollView.post(new Runnable() {
public void run() {
scrollView.smoothScrollTo(0, editText.getBottom());
}
});
Évidemment, vous pouvez utiliser n’importe quel type de vue au lieu de Modifier le texte. Notez que getBottom () renvoie les coordonnées de la vue en fonction de la disposition parent, de sorte que toutes les vues utilisées dans ScrollView doivent avoir uniquement un parent (par exemple, une disposition linéaire).
Si vous avez plusieurs parents dans l'enfant de ScrollView, la seule solution que j'ai trouvée consiste à appeler requestChildFocus sur la vue parent:
editText.getParent().requestChildFocus(editText, editText);
mais dans ce cas, vous ne pouvez pas avoir un défilement lisse.
J'espère que cette réponse peut aider quelqu'un avec le même problème.
Essayez d’utiliser la méthode scrollTo
Plus d’informations
Si vous voulez faire défiler instantanément, vous pouvez utiliser:
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);
}
});
Ou si vous voulez faire défiler en douceur et lentement afin que vous puissiez utiliser ceci:
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();
}
Je dois faire ceci pour faire défiler au bas d'un ScrollView (avec un TextView à l'intérieur):
(Je mets ceci sur une méthode qui met à jour le TextView)
final ScrollView myScrollView = (ScrollView) findViewById(R.id.myScroller);
myScrollView.post(new Runnable() {
public void run() {
myScrollView.fullScroll(View.FOCUS_DOWN);
}
});
Oui, vous pouvez.
Disons que vous avez un Layout
et à l'intérieur de celui-ci, vous avez beaucoup de Views
. Donc, si vous voulez faire défiler jusqu'à n'importe quel View
par programme, vous devez écrire l'extrait de code suivant:
Par exemple.
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);
Si vous voulez faire défiler jusqu'à View
spécifique, disons txtview dans ce cas, écrivez simplement:
scrollView.smoothScrollTo(txtView.getScrollX(),txtView.getScrollY());
Et vous êtes fait..
** pour faire défiler à la hauteur désirée. J'ai trouvé une bonne solution **
scrollView.postDelayed(new Runnable() {
@Override
public void run() {
scrollView.scrollBy(0, childView.getHeight());
}
}, 100);
Ajouter une autre réponse qui n'implique pas de coordonnées.
Cela amènera la vue souhaitée à se concentrer (mais pas à la position la plus haute):
yourView.getParent().requestChildFocus(yourView,yourView);
public void RequestChildFocus (Afficher un enfant, Voir ciblé)
enfant - Enfant de ce ViewParent qui veut se concentrer. Cette vue contiendra la vue focalisée. Ce n'est pas nécessairement la vue qui a réellement le focus.
concentré - La vue qui est un descendant d'enfant qui a réellement le focus
juste page défiler:
ScrollView sv = (ScrollView) findViewById(your_scroll_view);
sv.pageScroll(View.FOCUS_DOWN);
Remarque: si vous êtes déjà dans un fil de discussion, vous devez créer un nouveau fil de discussion ou ne pas faire défiler la nouvelle hauteur jusqu'à la fin complète (pour moi). Pour ex:
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());*/
}
});
}
});
}
Tout le monde publie des réponses aussi compliquées.
J'ai trouvé une réponse facile, pour faire défiler vers le bas, bien:
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() );
Et, si nécessaire, vous pouvez mettre la deuxième ligne de code, ci-dessus, dans un exécutable:
myScroller.post( new Runnable() {
@Override
public void run() {
myScroller.smoothScrollTo( 0, myScroller.getChildAt( 0 ).getBottom() );
}
}
Il m'a fallu beaucoup de recherches et de jeux pour trouver cette solution simple. J'espère que ça vous aide aussi! :)
J'utilisais le Runnable avec sv.fullScroll (View.FOCUS_DOWN); Cela fonctionne parfaitement pour le problème immédiat, mais cette méthode fait en sorte que ScrollView prenne le focus de tout l'écran, si vous faites qu'AutoScroll se produise à chaque fois, aucun EditText ne pourra recevoir d'informations de l'utilisateur, ma solution a été d'utiliser un code différent sous le runnable:
sv.scrollTo (0, sv.getBottom () + sv.getScrollY ());
faire la même chose sans perdre de vue les points de vue importants
salutations.
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);
}
}
ça marche pour moi
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);