3

So I have this chatting app like structure I have made using Kivy's RecycleView to instantiate a custom widget (named 'Row') and I pass it values however I wish.

It works fine if the Row custom widget only contains a Label child, the moment I add an Image and a Button (I'll explain why in a sec), there are weird spacing and positioning problems which shouldn't exist because I am using a BoxLayout and have tried proper size_hint: and height: techniques to get them to look right.

Relevant KV code:

<Row@BoxLayout>:
    orientation: 'vertical'
    text: ''
    source: 'res/icon.png'
    buttontext: ''
    Label:
        markup: True
        text_size: self.size
        text: root.text
    Image:
        size: self.size
        source: root.source
        allow_stretch: True
    Button:
        text: root.buttontext #contains a link
        on_press: app.root.stuff(self.text) #opens that link

# Relevant Screen where I am using the RecycleView
<ChatBotScreen>
    BoxLayout:
        ti_userinput: ti_userinput
        orientation: 'vertical'
        ScrollView:
            size_hint_y: 85
            RecycleView:
                id: chatbase_list
                viewclass: 'Row'
                data: []
                RecycleBoxLayout:
                    padding: "15dp", "45dp", "15dp", "15dp"
                    default_size: None, dp(25)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    orientation: 'vertical'

        TextInput:
            size_hint_y: None
            height: "40dp"
            id: ti_userinput
            multiline: False
            on_text_validate: root.on_user_enter_text()

Since my custom widget Row is extending BoxLayout and I am using a vertical orientation, why aren't the child widgets (Label, Image and Button) overlapping?

This is the class & function via which I am calling to pass the data inside the RecycleView

    class ChatBotScreen(Screen):
        nickname = StringProperty()
        rvList = []

        def display_bot_output(self, botOutput):
            # Initialize an empty dictionary
            tempDict = {}
            textToDisplay = '' + botOutput

            # Update the dictionary with properties:values and then pass it as a list to RecycleView's data
            tempDict.update({'text':textToDisplay, 'buttontext':'https://google.com'})
            self.rvList.append(tempDict)
            self.ids.chatbase_list.data = self.rvList

What I want to be visible on screen is:

  • The text I send through the textToDisplay variable in the Label

  • Underneath the Label, Image should be displayed the source of which I can pass, if no source passed, no image displayed

  • Underneath the Image, a button with a link should be displayed which I pass through buttontext, if not passed, no button should be displayed.

I am able to render all that but the spacing and all is all messed up.

Screenshot below:

Here I first sent data with only Label text info and Image, thus the Button text is empty (it still shows up), then I send another data (2nd Row widget) with Label text info, Image as well as a Button text (which is google link).

all comes on top of each other

Any help is greatly appreciated. Thanks!

RhinoFreak
  • 99
  • 7

1 Answers1

0
<ChatBotScreen>
    BoxLayout:
       ti_userinput: ti_userinput
       orientation: 'vertical'
       ScrollView:
       # to have the screen get bigger not lliek what you have
           size: root.size
           RecycleView:
               id: chatbase_list
               viewclass: 'Row'
               data: []
               RecycleBoxLayout:
                    padding: "15dp", "45dp", "15dp", "15dp"
                    default_size: None, dp(25)
                    default_size_hint: 1, None
                    size_hint_y: None
                    height: self.minimum_height
                    # add this so you can scroll
                    row_default_height: 60
                    orientation: 'vertical'

    TextInput:
        size_hint_y: None
        height: "40dp"
        id: ti_userinput
        multiline: False
        on_text_validate: root.on_user_enter_text()