Control like Android Chip created as Container not working

8 views
Skip to first unread message

P5music

unread,
Aug 18, 2020, 8:09:08 AM8/18/20
to CodenameOne Discussions
I created a Container that resembles the Chip Android control.
In fact I just need that a button acts like a CheckBox or ToggleButton.

In my implementation the button has rounded corners and it has a check symbol when it is checked (checked=true).
That symbols is put at the beginning of the label of the button.

I tried by just changing the text of the button, but it was not updated, then in the code below the button is removed and then recreated.
But it does not work yet: what I experience is that the control gets updated only if I enter a TextField and click on the button again. Calling invalidate() is of no help.
Note that this is similar to what happened with the BrowserComponent. Is it something related to UI refresh?
However, what's wrong with this code?

import com.codename1.ui.Button;
import com.codename1.ui.Container;
import com.codename1.ui.events.ActionEvent;
import com.codename1.ui.events.ActionListener;
import com.codename1.ui.layouts.BoxLayout;
import com.codename1.ui.plaf.RoundBorder;

public class MyChip extends Container {

    boolean checked;

    Button button;
    String label;


    public void setAppearance()
    {
        String labelText=label;
        if (button!=null) button.remove();

       
        if (checked) labelText="✓ "+label;
        button=new Button(labelText);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent evt) {
                setChecked(!checked);
            }
        });

        button.getAllStyles().setBorder(RoundBorder.create()
                .rectangle(true)
                .color(0xaaaaaa));

        add(button);
      
    }
    public MyChip(String labelParam)
    {
        this.label=labelParam;
        setLayout(BoxLayout.x());
         setChecked(false);

    }
    public void setChecked(boolean state)
    {

        checked=state;
            setAppearance();


    }

    public boolean isChecked()
    {
        return checked;
    }


}


Shai Almog

unread,
Aug 19, 2020, 2:14:53 AM8/19/20
to CodenameOne Discussions
When you change the UI in a way that impacts size you need to call animateLayout() or revalidate().
When you don't impact size calling repaint() is enough.

I would suggest using setMaterialIcon() instead of coding the check into the text.

P5music

unread,
Aug 19, 2020, 5:20:26 AM8/19/20
to CodenameOne Discussions
Thank you.
I noticed that checking/unchecking the button (that is, creating it with/without the material icon) the layout width can change. If I use many buttons like a ChipGroup that breaks the line sometimes the last button goes to the next line.
I would like that the button has a reserved space for the icon also when it has not the icon, I mean the button width does not change.
How can this be achieved?

Shai Almog

unread,
Aug 19, 2020, 9:50:42 PM8/19/20
to CodenameOne Discussions
You can set a blank icon of the same size to take up the space. E.g.

if(placeholder == null) {
     Image icon = buttonWithIcon.getIcon();
     placeholder = Image.create(icon.getWidth(), icon.getHeight(), 0);
}
// this will leave setPressedIcon with the checked value
buttonWithIcon.setIcon(placeholder);
Reply all
Reply to author
Forward
0 new messages