![](/img/trans.png)
[英]Update kivy recycleview self.data from textinput change
[英]RecycleView change index when using refresh_from_data() in Kivy
我正在嘗試創建一個簡單的表,在其中選擇RecycleView中的一項將選擇整行。 通過更改被單擊的行上每個索引按鈕的索引狀態,可以解決此問題。 但是,如果我想手動將一些數據添加到我的recycleview中,然后使用refresh_from_data()方法更新該表,則會導致一些奇怪的行為。 refresh_from_data()方法更改recycleview中按鈕的索引。
通過使用index = 0更改切換按鈕的狀態,可以觀察index [0]如何在位於RecycleView的左上角和RecycleView的右下角之間切換。 我的以下代碼說明了這一點。 一旦按下任何按鈕,我就將index [0]設置為等於“ down”。
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.recycleview import RecycleView
from kivy.uix.togglebutton import ToggleButton
from kivy.uix.recycleview.views import RecycleDataViewBehavior
class MyButton(RecycleDataViewBehavior, ToggleButton):
index = None
def refresh_view_attrs(self, rv, index, data):
""" Catch and handle the view changes """
self.index = index
return super(MyButton, self).refresh_view_attrs(
rv, index, data)
class TestRecycleView(RecycleView):
items_per_row = 3
selected_data = None
selected_row = None
def find_row(self, instance):
rgl = self.ids.gl
num_buttons = len(rgl.children)
num_rows = num_buttons // self.items_per_row
self.selected_row = instance.index // self.items_per_row + 1
print('Row: ', self.selected_row)
self.selected_data = self.data[(self.selected_row - 1) * self.items_per_row: self.items_per_row
* self.selected_row]
print('Data: ', self.selected_data)
index1 = (num_rows - self.selected_row + 1) * self.items_per_row - 1
index2 = index1 - self.items_per_row
state = instance.state
for index in range(index1, index2, -1):
rgl.children[index].state = state
print('======================')
print(' Add some data ')
print('======================')
# See how index[0] changes between the refresh()
rgl.children[0].state = "down"
root = App.get_running_app().root
root.refresh_from_data()
KV = '''
<MyButton>:
on_release:
app.root.find_row(self)
TestRecycleView:
data: [{'text': str(x)} if x not in range(9,12) else {'text': 'Press here'} for x in range(21)]
viewclass: 'MyButton'
id: rv_controller
target_id: None
RecycleGridLayout:
id: gl
cols: 3
default_size_hint: 1, None
orientation: 'vertical'
key_selection: 'selectable'
default_size: None, dp(26)
size_hint_y: None
height: self.minimum_height
multiselect: True
touch_multiselect: True
'''
class Test(App):
def build(self):
root = Builder.load_string(KV)
# root.data = items
return root
Test().run()
我得出的結論是,索引在0、1、2、3 ....和end,end-1,end-2,...之間切換。這意味着所選行在每個按鈕之間的中間行上“鏡像”按。
但是,為什么RecycleView表現為這種方式,我該怎么辦? 我要做的就是能夠一鍵選擇整行,手動添加/更改數據,而且我也只希望在任何給定時間選擇一行。
但是refresh_from_data()方法使我很難做。
我認為稍微不同的方法會更好。 而不是設置特定按鈕的state
,而是將state
屬性添加到數據中,然后更改數據中的state
。 這樣, RecycleView
將根據數據設置狀態,並且按鈕的交換也將無關緊要。 因此,在kv
,將數據更改為:
TestRecycleView:
data: [{'text': str(x), 'state': 'normal'} for x in range(21)]
並將find_row()
更改為:
def find_row(self, instance):
self.selected_row = instance.index // self.items_per_row + 1
start_index = (self.selected_row - 1) * self.items_per_row
for index in range(start_index, start_index + self.items_per_row):
self.data[index]['state'] = 'down' # change data, not button state
self.refresh_from_data()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.