Skip to content

Commit 52a19de

Browse files
authored
Merge pull request #1186 from paulproteus/detailed-list-allow-insert-row
Fix crash on adding new row to DetailedList
2 parents 8734389 + 0da80fd commit 52a19de

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

src/android/toga_android/widgets/base.py

+21-3
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,36 @@
11
from ..libs.activity import MainActivity
22
from ..libs.android_widgets import Gravity
33

4+
from rubicon.java.jni import java
5+
46
from toga.constants import CENTER, JUSTIFY, LEFT, RIGHT
57

68

9+
def _get_activity(_cache=[]):
10+
"""
11+
Android Toga widgets need a reference to the current activity to pass it as `context` when creating
12+
Android native widgets. This may be useful at any time, so we retain a global JNI ref.
13+
14+
:param _cache: List that is either empty or contains 1 item, the cached global JNI ref
15+
"""
16+
if _cache:
17+
return _cache[0]
18+
# See MainActivity.onCreate() for initialization of .singletonThis:
19+
# https://github.com/beeware/briefcase-android-gradle-template/blob/3.7/%7B%7B%20cookiecutter.formal_name%20%7D%7D/app/src/main/java/org/beeware/android/MainActivity.java
20+
if MainActivity.singletonThis is None:
21+
raise ValueError("Unable to find MainActivity.singletonThis from Python. This is typically set by "
22+
"org.beeware.android.MainActivity.onCreate().")
23+
_cache.append(MainActivity(__jni__=java.NewGlobalRef(MainActivity.singletonThis)))
24+
return _cache[0]
25+
26+
727
class Widget:
828
def __init__(self, interface):
929
self.interface = interface
1030
self.interface._impl = self
1131
self._container = None
1232
self.native = None
13-
# Capture a reference to the Java `MainActivity` instance, so that subclasses
14-
# can pass it as `context` when creating native Android widgets.
15-
self._native_activity = MainActivity.singletonThis
33+
self._native_activity = _get_activity()
1634
self.create()
1735
# Immediately re-apply styles. Some widgets may defer style application until
1836
# they have been added to a container.

src/android/toga_android/widgets/detailedlist.py

+12-7
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@ class DetailedList(Widget):
3333
def create(self):
3434
# DetailedList is not a specific widget on Android, so we build it out
3535
# of a few pieces.
36-
parent = android_widgets.LinearLayout(self._native_activity)
37-
parent.setOrientation(android_widgets.LinearLayout.VERTICAL)
38-
self.native = parent
36+
37+
if self.native is None:
38+
self.native = android_widgets.LinearLayout(self._native_activity)
39+
self.native.setOrientation(android_widgets.LinearLayout.VERTICAL)
40+
else:
41+
# If create() is called a second time, clear the widget and regenerate it.
42+
self.native.removeAllViews()
43+
3944
scroll_view = android_widgets.ScrollView(self._native_activity)
4045
scroll_view_layout_params = android_widgets.LinearLayout__LayoutParams(
4146
android_widgets.LinearLayout__LayoutParams.MATCH_PARENT,
@@ -47,7 +52,7 @@ def create(self):
4752
self._android_swipe_refresh_layout = android_widgets.SwipeRefreshLayout(
4853
__jni__=java.NewGlobalRef(swipe_refresh_wrapper))
4954
swipe_refresh_wrapper.addView(scroll_view)
50-
parent.addView(swipe_refresh_wrapper, scroll_view_layout_params)
55+
self.native.addView(swipe_refresh_wrapper, scroll_view_layout_params)
5156
dismissable_container = android_widgets.LinearLayout(self._native_activity)
5257
dismissable_container.setOrientation(android_widgets.LinearLayout.VERTICAL)
5358
dismissable_container_params = android_widgets.LinearLayout__LayoutParams(
@@ -70,9 +75,9 @@ def _make_row(self, container, i):
7075
# Add user-provided icon to layout.
7176
icon_image_view = android_widgets.ImageView(self._native_activity)
7277
icon = self.interface.data[i].icon
73-
icon.bind(self.interface.factory)
74-
bitmap = android_widgets.BitmapFactory.decodeFile(str(icon._impl.path))
75-
if bitmap is not None:
78+
if icon is not None:
79+
icon.bind(self.interface.factory)
80+
bitmap = android_widgets.BitmapFactory.decodeFile(str(icon._impl.path))
7681
icon_image_view.setImageBitmap(bitmap)
7782
icon_layout_params = android_widgets.RelativeLayout__LayoutParams(
7883
android_widgets.RelativeLayout__LayoutParams.WRAP_CONTENT,

0 commit comments

Comments
 (0)