1
votes

Ajouter des coins arrondis avec Android: drawableLeft avec png

Pour faire court, voici ce que je voudrais ajouter un bouton personnalisé qui ressemble à ceci:

Button_On

IMG est un fichier .png dans mes dossiers mipmap et CERTAINS TEXTE sont juste une valeur de chaîne. Qu'est-ce que la ligne en pointillé est ajoutée juste comme un séparateur dans l'image, pas dans le bouton. Le problème est que les bords arrondis n'apparaissent pas là où l'image est ajoutée. Cela ressemble à ceci:

 Button_have

Mes questions sont les suivantes:

  1. Est-ce possible?
  2. Existe-t-il un moyen de remplacer l'attribut dans ? Je vais devoir créer 10 de ces boutons chacun avec des couleurs différentes et si j'ajoute android: color avec une valeur différente, la couleur ne change pas
  3. Lors de l'ajout de l'image, cela me fait en choisir une seule (par exemple celle mdpi). Si cela doit être affiché sur des écrans plus grands, prendra-t-il une image .png différente en fonction de la taille?
  4. Dois-je utiliser un type de bouton spécifique? Je voudrais inverser les couleurs lorsque le bouton est enfoncé et rester enfoncé. J'ai une vague idée de la façon dont cela peut être réalisé, mais y a-t-il un moyen de le faire pour les fichiers .png également ou dois-je en importer d'autres avec les couleurs déjà inversées et simplement les changer? Li >

<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">

<Button
    style="@style/CategoryToggle.History"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="8dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent" />


</android.support.constraint.ConstraintLayout>

<resources>

<style name="CategoryToggle">
    <item name="android:background">@drawable/custom_button</item>
    <item name="android:textAllCaps">true</item>
</style>

<style name="CategoryToggle.First">
    <item name="android:color">@color/bluePrimary</item> // Does not override <solid>
    <item name="android:drawableLeft">@mipmap/icon_48mdpi</item>
    <item name="android:text">@string/first_cat</item>
</style>
</resources>

<shape 
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">

<corners
    android:topLeftRadius="250px"
    android:bottomLeftRadius="250px"
    android:topRightRadius="50px"
    android:bottomRightRadius="50px" />
<solid
    android:color="@color/YellowPrimary"/>
</shape>

Je n'ai pas de code java pour le moment car je viens de commencer et j'essaye d'implémenter ce bizarre format du bouton.

Voici à quoi ça ressemble à ma fin: my_end


10 commentaires

Il est difficile de comprendre ce qui ne va pas sans un code.


@Bryan Je n'ai pas beaucoup de code à utiliser car je viens de commencer à travailler. J'ai seulement ajouté les couleurs, les chaînes, les png. Rien d'autre pour le moment.


Pas beaucoup de code vaut mieux que pas de code, publiez le XML que vous utilisez pour créer la forme et tout code Java que vous utilisez pour l'afficher.


@Bryan Comme je l'ai dit, rien de bien. Ajout de ce que j'ai. Pas de java pour le moment car j'essaie juste de créer cette forme pour le moment.


Le mipmap icon_48mdpi a-t-il un fond jaune?


Oui. Je devrais l'avoir transparent, non?


Probablement. C'est pourquoi vous obtenez la forme carrée sur le côté gauche du bouton. Il existe façons de masquer le dessinable , mais cela prend un peu de code.


Que voulez-vous dire par "y a-t-il un moyen de faire cela pour les fichiers .png également"? Vous souhaitez modifier le dessin en fonction de l'état du bouton?


Oui, donnez au PNG un arrière-plan transparent et le dessin du coin arrondi doit avoir l'air correct (non couvert).


@Bryan Oui, je veux changer les couleurs du png lorsque le bouton est enfoncé. Quelque chose pour imiter le fait qu'il est sélectionné


4 Réponses :


0
votes

Sur 4 ", y a-t-il un moyen de (inverser les couleurs lorsque vous appuyez dessus) pour les fichiers .png" .. oui, il y a des moyens.

L'option par le livre consiste à utiliser des styles xml pour spécifier différents dessinables pour différents états de bouton. Considérez ImageButton qui en a un exemple dans sa documentation: https: // developer. android.com/reference/android/widget/ImageButton.html

Une autre option consiste à appliquer des teintes ou d'autres filtres au dessinable dans votre propre code dans les rappels d'interaction de bouton. Par rapport à l'utilisation de différents drawables, dans cette approche, vous ajoutez du code personnalisé au lieu de tirer parti des ressources intégrées, de sorte que vous pouvez finir de tester et de déboguer davantage sur différents appareils, et vous obtenez un contrôle total afin que vous puissiez faire des animations personnalisées et d'autres choses élaborées qui peuvent ne pas s'intègre parfaitement dans les outils de ressources Android. Peut commander setColorFilter pour les débutants: https: // developer.android.com/reference/android/widget/ImageView.html#setColorFilter(int,%20android.graphics.PorterDuff.Mode)

Merci d'avoir ajouté du code et des images ou votre problème, aide à le comprendre.


0 commentaires

1
votes
  1. Absolument. Comme je l'ai mentionné dans les commentaires, assurez-vous que votre dessin a un arrière-plan transparent, ou créez un bouton personnalisé pour masquer le dessinable.
  2. Vous souhaiterez utiliser un attribut de style appliquer un style différent à chaque bouton. J'entends par là que la couleur définie dans votre custom_button.xml doit faire référence à un attribut de couleur (quelque chose comme colorAccent devrait fonctionner dans votre cas), au lieu d'une couleur statique. li>
    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="@color/button_color_selector"/>
    </shape>
    

    Puis changez cette couleur dans vos styles de boutons au lieu de android:color.

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
        <item android:color="@color/pressed_color" android:state_pressed="true"/>
        <item android:color="@color/focused_color" android:state_focused="true"/>
        <item android:color="@color/state_hovered" android:state_hovered="true"/>
        <item android:color="?attr/colorAccent"/>
    </selector>
    

    Assurez-vous de faire ajouter la dépendance bibliothèque de support ou colorAccent ne sera pas disponible.

    Utilisez l'attribut android: theme au lieu de l'attribut style pour appliquer le thème du bouton. p>

    res/
    |-- drawable/
    |   +-- custom_button.xml
    |-- drawable-hdpi/
    |   +-- icon_48dp.png
    |-- drawable-mdpi/
    |   +-- icon_48dp.png
    |-- drawable-xhdpi/
    |   +-- icon_48dp.png
    |-- drawable-xxhdpi/
    |   +-- icon_48dp.png
    |-- drawable-xxxhpdi/
    |   +-- icon_48dp.png
    ~
    
    1. Il semble que vos tableaux n'utilisent pas les qualificatifs de ressources a >. Vous devrez vous assurer que chaque ressource alternative a exactement le même nom que l'original (c'est-à-dire que votre icon_48mdpi.png devrait plutôt être appelé icon_48dp.png pour toutes les configurations) et est placé dans le dossier dessinable correspondant pour sa densité. Vos ressources dessinables doivent ressembler à ce qui suit (dans la structure de vue Projet , pas la structure de vue Android ).
    <Button
        android:width="wrap_content"
        android:height="wrap_content"
        android:theme="@style/CategoryToggle"/>
    
    1. Pour changer la couleur d'un dessin en fonction de l'état, vous devrez abstraire votre couleur un peu plus loin et créer un liste des états de couleur .

    res/color/button_color_selector.xml final

    <style name="CategoryToggle">
        <item name="colorAccent">@color/YellowPrimary</item>
    </style>
    

    Ensuite, vous pouvez utiliser cette ressource de couleur dans votre forme dessinable au lieu de colorAccent .

    <shape xmlns:android="http://schemas.android.com/apk/res/android"
        android:shape="rectangle">
        <solid android:color="?attr/colorAccent"/>
    </shape>
    

    Vous pouvez également faire de chacune des couleurs de votre liste d’états de couleurs un attribut stylable par définissant des attributs personnalisés et référençant ces attributs dans vos styles. Je n'entrerai pas dans cela plus loin par souci de brièveté.

    Vous pouvez faire cela pour les drawables de la même manière en créant un state list drawable .


    Enfin, vous voudrez prendre l'habitude d'utiliser dp au lieu de px , sauf si vous êtes absolument certain de vouloir utiliser px . Cela évitera les apparences étranges à différentes densités d'écran.


12 commentaires

Bon conseil. Je vais essayer de vous dire comment cela s'est passé. Quelques petites questions et clarifications avant: 1. Je suppose que le codage prendra moins de place que d'importer un nouvel ensemble de png? 2. Puis-je utiliser n'importe quel attribut? Par exemple un moins pertinent ici comme colorEdgeEffect? 3. Je m'en suis souvenu d'un projet précédent, mais j'ai oublié de mettre à jour la question. 4. J'ai utilisé px pour tester s'il y avait une différence. J'ai oublié de le modifier avant de coller le code.


@Andy 1. C'est vrai. Vous pouvez même utiliser des ressources vectorielles au lieu de fichiers png, et appliquer un attribut de couleur à la couleur du vecteur pour prendre encore moins de place. 2. Oui, n'importe quel attribut fonctionnerait. J'essaierais de m'en tenir à ceux qui ont du sens pour le cas d'utilisation.


Après beaucoup d'essais et d'erreurs, j'ai réussi à faire le numéro 1, mais je suis plutôt coincé au n ° 2. Le remplacement d'une couleur? Attr ne se produit pas même si j'ai suivi les étapes exactes. Pourriez-vous identifier la bibliothèque? J'ai ajouté environ 7 en gradle, ce qui semblait pertinent, mais je ne peux pas remplacer la couleur.


@Andy Est-ce que ? Attr / colorAccent est mis en évidence comme une erreur? (Il doit apparaître en rouge, et lorsque vous le survolez, une boîte de dialogue apparaîtra indiquant quelque chose comme "Impossible de résoudre le symbole '? Attr / colorAccent'")


Il n'y a pas d'erreur. Dans ma forme, j'ai qui définit la bonne couleur, et dans mon style appliqué à mon bouton, j'ai @ color / histYellowPrimary qui ne le change pas en jaune. Je reçois toujours celui initialement défini pour l'accent (une couleur rose). J'ai la dernière dépendance de compatibilité d'application ainsi que d'autres ajoutées à partir de la liste, y compris implémentation 'com.android.support:palette-v7:28.0.0' qui est liée aux couleurs.


J'ai également essayé avec le sélecteur de # 4 et il ne remplace toujours pas le colorAccent


@Andy Alors vous avez la bonne bibliothèque (la bibliothèque Palette, bien qu'utile, n'a rien à voir avec colorAccent ). Je m'excuse, je n'ai pas mentionné dans la réponse; assurez-vous que vous définissez le style à l'aide de android: theme = "@ style / CategoryToggle" (et non de style = "..." ). En outre, le changement de couleur n'apparaîtra pas dans l'aperçu XML, vous devrez donc créer l'application pour voir les modifications.


Si je le configure comme android: theme , ma forme disparaît. Ce que j'obtiens est un bouton gris avec une image et du texte. Rien de ma forme et de mes couleurs personnalisées. Si je le définis comme style = alors j'obtiens la forme mais la couleur ne remplace pas


@Andy Hm, lors de mes tests, la forme a été conservée lors de l'utilisation de android: theme . Ajoutez votre code actuel à la question pour que je puisse voir ce qui ne va pas?


J'ai réussi à résoudre la situation en créant un dans le dossier dessinable et un élément pour chaque état contenant la forme et les couleurs dont j'ai besoin De cette façon, je me débarrasse également d'un fichier pour les formes nécessaires pour chaque bouton.


@Andy Cela ressemble à beaucoup de code en double, j'essaierais quand même de voir si je pouvais le séparer. Mais tant que ça marche.


Je sais qu'il y a beaucoup de code en double, mais si j'ajoute également la couleur du texte dans la section d'arrière-plan, il ignore simplement la forme. Pour l'instant, je vais l'utiliser car cela fonctionne et peut-être que je tomberai sur quelque chose lors de la mise en œuvre de l'application.



0
votes

Un grand merci à Bryan pour sa perspicacité à ce sujet. Cela m'a conduit aux chemins que je devais suivre pour résoudre ce problème. Je poste cette réponse afin que d'autres personnes ayant des cas similaires connaissent les étapes. Bien que j'aie un certain nombre de fichiers, cette procédure a parfaitement fonctionné.

  1. J'ai mon bouton personnalisé comme décrit dans le lien fourni par Bryan.

Pour le reste, j'ai ce qui suit:

Changer la couleur du texte: button_text_color.xml

<packagename.MyCustomButton xmlns:app="http://schemas.android.com/apk/res-auto"
            android:id="@+id/myButton"
            style="@style/MyBUttonStyle"
            android:layout_marginBottom="8dp" />

Changer l'arrière-plan: button_background.xml

<style name="MyButtonStyle">
        <item name="android:background">@drawable/button_background</item>
        <item name="android:drawableLeft">@drawable/button_drawable</item>
    <item name="android:text">@string/button_text</item>
    <item name="android:textColor">@color/button_text_color</item>
</style>

Changer le dessinable: button_drawable.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/ic_button_inverted" android:state_pressed="true" />
    <item android:drawable="@drawable/ic_button"/>
</selector>

button_style.xml

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true">
        <shape android:shape="rectangle">
            <corners android:bottomLeftRadius="400dp" android:radius="100dp" android:topLeftRadius="400dp" />
            <solid android:color="@color/redDark" />
        </shape>
    </item>
    <item android:state_enabled="true">
        <shape android:shape="rectangle">
            <corners android:bottomLeftRadius="400dp" android:radius="100dp" android:topLeftRadius="400dp" />
            <solid android:color="@color/redPrimary" />
        </shape>
    </item>
</selector>

Implémentation dans main_layout.xml ^^

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="@color/redPrimary" android:state_pressed="true"/>
    <item android:color="@color/redDark"/>
</selector>

p >


0 commentaires

0
votes

Utilisez simplement la bibliothèque officielle.
Ajoutez le MaterialButton utilisant ces attributs:

  • app: icon pour ajouter l'icône
  • app: iconGravity pour décider de la position de l'icône
  • app: iconPadding pour augmenter / diminuer l'espace entre l'icône et le texte
  • android: paddingLeft le remplissage entre le bord et l'icône
  <style name="ShapeAppearanceOverlay.Button.RoundedRight" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSizeTopRight">4dp</item>
    <item name="cornerSizeBottomRight">4dp</item>
    <item name="cornerSizeTopLeft">16dp</item>
    <item name="cornerSizeBottomLeft">16dp</item>
  </style>

Avec app:shapeAppearanceOverlay , vous pouvez personnaliser la forme du composant.

<com.google.android.material.button.MaterialButton
    android:paddingLeft="2dp"
    app:icon="@drawable/ic_add_24px"
    app:iconGravity="start"
    app:iconPadding="4dp"
    app:shapeAppearanceOverlay="@style/ShapeAppearanceOverlay.Button.RoundedRight"
    .../>


0 commentaires