Wiem, że może być za późno na lepszą odpowiedź, ale pożądanym idealnym rozwiązaniem musi być systemowy pozycjoner. Mam na myśli, że gdy system dokonuje pozycjonowania dla pola edytora, umieszcza to pole tylko do klawiatury, więc zgodnie z regułami UI / UX jest on idealny.
Poniższy kod sprawia, że pozycjonowanie w systemie Android przebiega płynnie. Przede wszystkim utrzymujemy bieżący punkt przewijania jako punkt odniesienia. Po drugie, znajdź najlepszy punkt pozycjonowania przewijania dla edytora, w tym celu przewijamy do góry, a następnie żądamy od pól edytora, aby komponent ScrollView wykonał najlepsze pozycjonowanie. Gatcha! Nauczyliśmy się najlepszej pozycji. Teraz będziemy płynnie przewijać od poprzedniego punktu do punktu, który niedawno odnaleźliśmy. Jeśli chcesz, możesz pominąć płynne przewijanie za pomocą scrollTo zamiast tylko smoothScrollTo .
UWAGA: Główny kontener ScrollView jest polem członkowskim o nazwie scrollViewSignup, ponieważ mój przykład był ekranem rejestracyjnym, jak można się wiele domyślić.
view.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(final View view, boolean b) {
if (b) {
scrollViewSignup.post(new Runnable() {
@Override
public void run() {
int scrollY = scrollViewSignup.getScrollY();
scrollViewSignup.scrollTo(0, 0);
final Rect rect = new Rect(0, 0, view.getWidth(), view.getHeight());
view.requestRectangleOnScreen(rect, true);
int new_scrollY = scrollViewSignup.getScrollY();
scrollViewSignup.scrollTo(0, scrollY);
scrollViewSignup.smoothScrollTo(0, new_scrollY);
}
});
}
}
});
Jeśli chcesz użyć tego bloku dla wszystkich instancji EditText i szybko zintegruj go ze swoim kodem ekranowym. Możesz po prostu zrobić trawers jak poniżej. Aby to zrobić, uczyniłem z głównego OnFocusChangeListener pole członka o nazwie focusChangeListenerToScrollEditor i wywołałem go podczas onCreate, jak poniżej.
traverseEditTextChildren(scrollViewSignup, focusChangeListenerToScrollEditor);
A implementacja metody jest następująca.
private void traverseEditTextChildren(ViewGroup viewGroup, View.OnFocusChangeListener focusChangeListenerToScrollEditor) {
int childCount = viewGroup.getChildCount();
for (int i = 0; i < childCount; i++) {
View view = viewGroup.getChildAt(i);
if (view instanceof EditText)
{
((EditText) view).setOnFocusChangeListener(focusChangeListenerToScrollEditor);
}
else if (view instanceof ViewGroup)
{
traverseEditTextChildren((ViewGroup) view, focusChangeListenerToScrollEditor);
}
}
}
To, co zrobiliśmy tutaj, sprawia, że wszystkie dzieci instancji EditText są w stanie wywoływać nasłuchiwanie.
Aby osiągnąć to rozwiązanie, sprawdziłem wszystkie rozwiązania tutaj i wygenerowałem nowe rozwiązanie dla lepszego wyniku UI / UX.
Ogromne podziękowania dla wszystkich innych odpowiedzi, które mnie bardzo inspirują.
the form may changed from user to user
ale możesz po prostu użyćmEditView.getTop();