From 14eae1517828ce4315ed69ca5010b81711080fde Mon Sep 17 00:00:00 2001 From: Julian Winkler Date: Tue, 3 Sep 2024 17:51:25 +0200 Subject: [PATCH] ListView: implement setSelection() and scrollTo() --- .../android_widget_AbsListView.h | 8 ++++++ .../widgets/android_widget_AbsListView.c | 9 +++++++ src/api-impl/android/widget/AbsListView.java | 25 +++++++++++++++++++ src/api-impl/android/widget/AdapterView.java | 1 + src/api-impl/android/widget/ListView.java | 5 ++++ 5 files changed, 48 insertions(+) diff --git a/src/api-impl-jni/generated_headers/android_widget_AbsListView.h b/src/api-impl-jni/generated_headers/android_widget_AbsListView.h index 5643f12c..5554ae98 100644 --- a/src/api-impl-jni/generated_headers/android_widget_AbsListView.h +++ b/src/api-impl-jni/generated_headers/android_widget_AbsListView.h @@ -215,6 +215,14 @@ JNIEXPORT jlong JNICALL Java_android_widget_AbsListView_native_1constructor JNIEXPORT void JNICALL Java_android_widget_AbsListView_native_1setAdapter (JNIEnv *, jobject, jlong, jobject); +/* + * Class: android_widget_AbsListView + * Method: native_scrollTo + * Signature: (JI)V + */ +JNIEXPORT void JNICALL Java_android_widget_AbsListView_native_1scrollTo + (JNIEnv *, jobject, jlong, jint); + /* * Class: android_widget_AbsListView * Method: setItemChecked diff --git a/src/api-impl-jni/widgets/android_widget_AbsListView.c b/src/api-impl-jni/widgets/android_widget_AbsListView.c index 71bde73d..fcb526f1 100644 --- a/src/api-impl-jni/widgets/android_widget_AbsListView.c +++ b/src/api-impl-jni/widgets/android_widget_AbsListView.c @@ -171,3 +171,12 @@ JNIEXPORT jint JNICALL Java_android_widget_AbsListView_getCheckedItemPosition(JN return gtk_single_selection_get_selected(single_selection); } + +JNIEXPORT void JNICALL Java_android_widget_AbsListView_native_1scrollTo(JNIEnv *env, jobject this, jlong widget_ptr, jint position) +{ + GtkScrolledWindow *scrolled_window = GTK_SCROLLED_WINDOW(_PTR(widget_ptr)); + GtkListView *list_view = GTK_LIST_VIEW(gtk_scrolled_window_get_child(scrolled_window)); +#if GTK_CHECK_VERSION(4, 12, 0) + gtk_list_view_scroll_to(list_view, position, GTK_LIST_SCROLL_NONE, NULL); +#endif +} diff --git a/src/api-impl/android/widget/AbsListView.java b/src/api-impl/android/widget/AbsListView.java index ac0523d4..9f525f19 100644 --- a/src/api-impl/android/widget/AbsListView.java +++ b/src/api-impl/android/widget/AbsListView.java @@ -25,6 +25,7 @@ public abstract class AbsListView extends AdapterView { @Override protected native long native_constructor(Context context, AttributeSet attrs); protected native void native_setAdapter(long widget, ListAdapter adapter); + protected native void native_scrollTo(long widget, int position); public void setChoiceMode(int choiceMode) {} @@ -73,6 +74,30 @@ public abstract class AbsListView extends AdapterView { public void smoothScrollBy(int position, int duration) {} + public void smoothScrollToPositionFromTop(int position, int offset) { + native_scrollTo(this.widget, position); + } + + private int pendingSelection = -1; + @Override + public void setSelection(int position, boolean animate) { + super.setSelection(position, animate); + native_scrollTo(this.widget, position); + if (getWidth() > 0 && getHeight() > 0) + native_scrollTo(AbsListView.this.widget, position); + else + pendingSelection = position; + } + + @Override + public void layout(int l, int t, int r, int b) { + super.layout(l, t, r, b); + if (pendingSelection != -1) { + native_scrollTo(AbsListView.this.widget, pendingSelection); + pendingSelection = -1; + } + } + @Override public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) { return new LayoutParams(getContext(), attrs); diff --git a/src/api-impl/android/widget/AdapterView.java b/src/api-impl/android/widget/AdapterView.java index 42a019b0..160f4ab0 100644 --- a/src/api-impl/android/widget/AdapterView.java +++ b/src/api-impl/android/widget/AdapterView.java @@ -36,6 +36,7 @@ public abstract class AdapterView extends ViewGroup { } public void setSelection(int i) { + setSelection(i, false); } public void setOnItemSelectedListener(AdapterView.OnItemSelectedListener listener) {} diff --git a/src/api-impl/android/widget/ListView.java b/src/api-impl/android/widget/ListView.java index 6975e6b2..f2348008 100644 --- a/src/api-impl/android/widget/ListView.java +++ b/src/api-impl/android/widget/ListView.java @@ -99,4 +99,9 @@ public class ListView extends AbsListView { } public void setDividerHeight(int height) {} + + @Override + public void setSelection(int position, boolean animate) { + super.setSelection(position + getHeaderViewsCount(), animate); + } }