如何在Kivy中实现RecycleView选中项填充TextInput?
解决Kivy中RecycleView选项点击后填充TextInput的问题
我看了你的代码,核心问题出在你在SelectableLabel的apply_selection方法里新建了一个MatchedStops实例——这个新实例和你界面上已经渲染的MatchedStops完全是两个独立的对象,所以修改它的输入框文本自然不会反映到实际UI上。下面是具体的修复步骤:
1. 给RecycleView添加ID(KV文件修改)
首先在你的search_trip.kv里,给RecycleView加个唯一ID,方便后续控制显示/隐藏:
<MatchedStops>: orientation: "vertical" DepartureStopName: id: departure_stop hint_text: "Departure stop" multiline: False on_text: root.find_stop(departure_stop.text) # 可选:点击输入框时也显示候选列表 on_focus: if self.focus: root.find_stop(self.text) RecycleView: id: recycle_view # 新增这个ID viewclass: 'SelectableLabel' data: [{'text': str(x["stop_name"])} for x in root.stops_data] SelectableRecycleGridLayout: cols: 1 default_size: None, dp(26) default_size_hint: 1, None size_hint_y: None height: self.minimum_height
2. 修改SelectableLabel的apply_selection方法(Python代码修改)
把原来新建MatchedStops的逻辑,改成获取当前界面上已存在的MatchedStops实例,同时添加隐藏RecycleView的逻辑:
class SelectableLabel(RecycleDataViewBehavior, Label): """Add selection support to the Label""" index = None selected = BooleanProperty(False) selectable = BooleanProperty(True) def refresh_view_attrs(self, rv, index, data): """Catch and handle the view changes""" self.index = index return super(SelectableLabel, self).refresh_view_attrs( rv, index, data) def on_touch_down(self, touch): """Add selection on touch down""" if super(SelectableLabel, self).on_touch_down(touch): return True if self.collide_point(*touch.pos) and self.selectable: return self.parent.select_with_touch(self.index, touch) def apply_selection(self, rv, index, is_selected): """Respond to the selection of items in the view.""" self.selected = is_selected if is_selected and rv.data[index]["text"] != "None": # 获取界面上真实的MatchedStops实例(RecycleView的父容器) matched_stops = rv.parent # 填充输入框文本 matched_stops.fill_departure_stop_name(rv.data[index]["text"]) # 选中后隐藏RecycleView rv.opacity = 0 rv.disabled = True
3. 修改MatchedStops的find_stop方法(Python代码修改)
当用户输入新内容时,要重新显示RecycleView:
class MatchedStops(BoxLayout): stops_data = ListProperty([]) departure_stop_name = ObjectProperty() def find_stop(self, stop: str) -> None: matched_stops = match_stop(stop) self.stops_data = matched_stops # 输入时显示RecycleView self.ids.recycle_view.opacity = 1 self.ids.recycle_view.disabled = False def fill_departure_stop_name(self, dept_stop_name): self.ids.departure_stop.text = dept_stop_name
为什么原来的方法无效?
你之前新建MatchedStops()相当于创建了一个完全脱离当前UI的组件,它的ids.departure_stop和界面上用户看到的输入框没有任何关联,所以修改文本不会有任何视觉变化。而通过rv.parent获取的是当前界面中已经渲染的MatchedStops实例,修改它的输入框文本才会同步到用户看到的界面上。
现在测试一下:用户输入站点名称→RecycleView显示候选列表→点击候选项→输入框自动填充文本,同时RecycleView隐藏;再次输入或点击输入框时,RecycleView会重新显示。
内容的提问来源于stack exchange,提问作者evelyn9191
相关产品推荐
相关产品推荐

