簡體   English   中英

在Kivy中使用refresh_from_data()時,RecycleView更改索引

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM