Round list avatar

Viewed 43

I'm trying simple list app with avatar. While I added my own picture it had been rectangle. I checked enternet but I didn't solved my problem.

Rectangle avatars

enter image description here

This is code:

from kivy.lang import Builder

from kivymd.app import MDApp
from kivymd.uix.list import OneLineListItem, ImageLeftWidget, OneLineAvatarIconListItem

KV = '''
MDBoxLayout:
    orientation: "vertical"
    MDTopAppBar:
        title: "Telegram"
    MDScrollView:
        MDList:
            id: container
'''


class Example(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Light"
        return Builder.load_string(KV)

    def on_start(self):
        for i in range(20):
            def pr(self):
                print(self.id)
            self.root.ids.container.add_widget(
                OneLineAvatarIconListItem(ImageLeftWidget(
        source="sniper.jpg", on_release=pr), id=str(i), text=f"Single-line item {i}", on_release=pr))#.add_widget()

Example().run()
1 Answers

You can use FitImage form kivymd to create your Rounded avatar and make your own avatar list. Here is how you can achieve this.

Py File:-

class Card(RoundedRectangularElevationBehavior, MDFloatLayout):
    pass

class DisplayPic(CircularElevationBehavior, ButtonBehavior, FitImage):
    pass
    
class ButtonLayout(RectangularRippleBehavior, ButtonBehavior, MDFloatLayout):
    pass
    
class UserCard(ButtonBehavior, Card):
        def __init__(self, name, dp, **kwargs):
            super().__init__(**kwargs)
            self.name = name
            self.dp = dp

KV File:-

<UserCard>
    size_hint: .9, None
    height: dp(80)
    elevation: dp(6)
    md_bg_color: 1,1,1,1
    soft_shadow_cl: [0, 0, 0, .05]
    radius: dp(20)
    name: ""
    dp: ""

                
    MDLabel:
        text: root.name
        bold:  True
        pos_hint: {'center_x': .75, 'center_y': .65}
    
    ButtonLayout:
        pos_hint: {'center_x': .5, 'center_y': .5}
        radius: root.radius

    DisplayPic:
        source: root.dp
        elevation: dp(3)
        size_hint: None, None
        size: dp(45), dp(45)
        radius: dp(360)
        pos_hint: {'center_x': .12, 'center_y': .5}
        on_release: print("clicked")

Now You have your own avatar list element just Use for loop to add your UserCard (avatar list element) to add it into a scroll view.

How to use this element:-

usercard = UserCard(u.display_name, u.photo_url)

Now add it to the ScrollView

Full Code With your example:-

from kivy.lang import Builder
from kivymd.uix.behaviors import RoundedRectangularElevationBehavior, CircularElevationBehavior, RectangularRippleBehavior, CircularRippleBehavior
from kivy.uix.behaviors import ButtonBehavior
from kivymd.uix.floatlayout import MDFloatLayout
from kivymd.uix.fitimage.fitimage import FitImage
from kivymd.app import MDApp
from kivymd.uix.list import OneLineListItem, ImageLeftWidget, OneLineAvatarIconListItem

KV = '''

<UserCard>
    size_hint: .9, None
    height: dp(80)
    elevation: dp(6)
    md_bg_color: 1,1,1,1
    soft_shadow_cl: [0, 0, 0, .05]
    radius: dp(20)
    name: ""
    dp: ""

                
    MDLabel:
        text: root.name
        bold:  True
        pos_hint: {'center_x': .75, 'center_y': .65}
    
    ButtonLayout:
        pos_hint: {'center_x': .5, 'center_y': .5}
        radius: root.radius

    DisplayPic:
        source: root.dp
        elevation: dp(3)
        size_hint: None, None
        size: dp(45), dp(45)
        radius: dp(360)
        pos_hint: {'center_x': .12, 'center_y': .5}
        on_release: print("clicked")


MDBoxLayout:
    orientation: "vertical"
    MDTopAppBar:
        title: "Telegram"
    ScrollView:
        MDGridLayout:
            id: container
            cols: 1
            col_force_default: False
            spacing: dp(6)
            size_hint: 1, .8
            adaptive_height: True
            pos_hint: {'center_x': .5}
        
'''

class Card(RoundedRectangularElevationBehavior, MDFloatLayout):
    pass

class DisplayPic(CircularElevationBehavior, ButtonBehavior, FitImage):
    pass

class ButtonLayout(RectangularRippleBehavior, ButtonBehavior, MDFloatLayout):
    pass

class UserCard(ButtonBehavior, Card):
    def __init__(self, name, dp, **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.dp = dp

class Example(MDApp):
    def build(self):
        self.theme_cls.theme_style = "Light"
        return Builder.load_string(KV)

    def change_screen(self, screen, receiver_name, receiver_uid, *args):
        receiver.name = receiver_name
        receiver.uid = receiver_uid
        self.manager.current = screen


    def on_start(self):
        for i in range(20):
            scrn_change = partial(self.change_screen, "Chat", u.display_name, u.uid)
            usercard = UserCard(u.display_name, u.photo_url)
            btn_layout = usercard.children[1]
            btn_layout.bind(on_release = scrn_change)
            self.root.ids.container.add_widget(usercard)
            

Example().run()

Output:-

enter image description here

Related