Réponses:
Voici une façon de le faire (grâce à la documentation Android!):
Ajoutez ce qui suit dans un fichier (par exemple, customshape.xml), puis placez-le dans (res / drawable / customshape.xml)
<?xml version="1.0" encoding="UTF-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:startColor="#SomeGradientBeginColor"
android:endColor="#SomeGradientEndColor"
android:angle="270"/>
<corners
android:bottomRightRadius="7dp"
android:bottomLeftRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp"/>
</shape>
Une fois que vous avez terminé de créer ce fichier, définissez simplement l'arrière-plan de l'une des manières suivantes:
Par code:
listView.setBackgroundResource(R.drawable.customshape);
Via XML , ajoutez simplement l'attribut suivant au conteneur (ex: LinearLayout ou à n'importe quel champ):
android:background="@drawable/customshape"
J'espère que quelqu'un le trouvera utile ...
Bien que cela ait fonctionné, cela a également supprimé toute la couleur d'arrière-plan. Je cherchais un moyen de faire juste la bordure et de remplacer simplement ce code de mise en page XML par celui-ci et j'étais prêt à partir!
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke android:width="4dp" android:color="#FF00FF00" />
<padding android:left="7dp" android:top="7dp"
android:right="7dp" android:bottom="7dp" />
<corners android:radius="4dp" />
</shape>
@ kris-van-bael
Pour ceux qui rencontrent des problèmes avec la sélection, mettez en surbrillance la ligne du haut et du bas où le rectangle d'arrière-plan apparaît lors de la sélection, vous devez définir le sélecteur de votre vue de liste sur une couleur transparente.
listView.setSelector(R.color.transparent);
Dans color.xml, ajoutez simplement ce qui suit -
<color name="transparent">#00000000</color>
android:cacheColorHint="@android:color/transparent"
Les autres réponses sont très utiles, merci aux auteurs!
Mais je ne voyais pas comment personnaliser le rectangle lors de la mise en évidence d'un élément lors de la sélection plutôt que de désactiver la mise en évidence @alvins @bharat dojeha.
Ce qui suit fonctionne pour moi pour créer un conteneur d'éléments de vue de liste arrondis sans contour et d'un gris plus clair lorsqu'il est sélectionné de la même forme:
Votre xml doit contenir un sélecteur tel que par exemple (dans res / drawable / customshape.xml):
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true" >
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="8dp" android:color="@android:color/transparent" />
<padding android:left="14dp" android:top="14dp"
android:right="14dp" android:bottom="14dp" />
<corners android:radius="10dp" />
<gradient
android:startColor="@android:color/background_light"
android:endColor="@android:color/transparent"
android:angle="225"/>
</shape>
</item>
<item android:state_pressed="false">
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<stroke android:width="8dp" android:color="@android:color/transparent" />
<padding android:left="14dp" android:top="14dp"
android:right="14dp" android:bottom="14dp" />
<corners android:radius="10dp" />
<gradient
android:startColor="@android:color/darker_gray"
android:endColor="@android:color/transparent"
android:angle="225"/>
</shape>
</item>
Ensuite, vous devez implémenter un adaptateur de liste et remplacer la méthode getView pour définir le sélecteur personnalisé comme arrière-plan
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//snip
convertView.setBackgroundResource(R.drawable.customshape);
//snip
}
et il faut également `` masquer '' le rectangle de sélection par défaut, par exemple dans onCreate (je cache également ma fine ligne de séparation grise entre les éléments):
listView.setSelector(android.R.color.transparent);
listview.setDivider(null);
Cette approche résout une solution générale pour les drawables, pas seulement ListViewItem avec différents états de sélection.
Mettre à jour
La solution de nos jours est d'utiliser un CardView
avec support pour les coins arrondis intégré.
Réponse originale *
Une autre façon que j'ai trouvée était de masquer votre mise en page en dessinant une image au-dessus de la mise en page. Cela pourrait vous aider. Découvrez les coins arrondis arrondis d'Android XML
Encore une autre solution à la sélection met en évidence les problèmes avec le premier et le dernier élément de la liste:
Ajoutez un remplissage en haut et en bas de l'arrière-plan de votre liste égal ou supérieur au rayon. Cela garantit que la mise en évidence de la sélection ne chevauche pas vos courbes d'angle.
C'est la solution la plus simple lorsque vous avez besoin d'une mise en surbrillance non transparente de la sélection.
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="@color/listbg" />
<stroke
android:width="2dip"
android:color="#D5D5D5" />
<corners android:radius="10dip" />
<!-- Make sure bottom and top padding match corner radius -->
<padding
android:bottom="10dip"
android:left="2dip"
android:right="2dip"
android:top="10dip" />
</shape>
en fait, je pense que la meilleure solution est décrite sur ce lien:
http://blog.synyx.de/2011/11/android-listview-with-rounded-corners/
en bref, il utilise un arrière-plan différent pour les éléments du haut, du milieu et du bas, de sorte que ceux du haut et du bas soient arrondis.
Cela m'a été incroyablement utile. Je voudrais suggérer une autre solution de contournement pour mettre parfaitement en évidence les coins arrondis si vous utilisez le vôtreCustomAdapter
.
Tout d'abord, allez dans votre dossier dessinable et créez 4 formes différentes:
shape_top
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
shape_normal
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"/>
shape_bottom
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:bottomRightRadius="10dp"
android:bottomRightRadius="10dp"/>
shape_round
<gradient
android:startColor="#ffffff"
android:endColor="#ffffff"
android:angle="270"/>
<corners
android:topLeftRadius="10dp"
android:topRightRadius="10dp"
android:bottomRightRadius="10dp"
android:bottomRightRadius="10dp"/>
Maintenant, créez une disposition de ligne différente pour chaque forme, c'est-à-dire pour shape_top
:
Vous pouvez également effectuer cette opération en modifiant l'arrière-plan par programme.
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:layout_marginRight="10dp"
android:fontFamily="sans-serif-light"
android:text="TextView"
android:textSize="22dp" />
<TextView
android:id="@+id/txtValue1"
android:layout_width="match_parent"
android:layout_height="48dp"
android:textSize="22dp"
android:layout_gravity="right|center"
android:gravity="center|right"
android:layout_marginLeft="20dp"
android:layout_marginRight="35dp"
android:text="Fix"
android:scaleType="fitEnd" />
Et définissez un sélecteur pour chaque liste de formes, c'est-à-dire pour shape_top
:
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Selected Item -->
<item android:state_selected="true"
android:drawable="@drawable/shape_top" />
<item android:state_activated="true"
android:drawable="@drawable/shape_top" />
<!-- Default Item -->
<item android:state_selected="false"
android:drawable="@android:color/transparent" />
</selector>
Enfin, définissez les options de mise en page dans votre CustomAdapter
:
if(position==0)
{
convertView = mInflater.inflate(R.layout.list_layout_top, null);
}
else
{
convertView = mInflater.inflate(R.layout.list_layout_normal, null);
}
if(position==getCount()-1)
{
convertView = mInflater.inflate(R.layout.list_layout_bottom, null);
}
if(getCount()==1)
{
convertView = mInflater.inflate(R.layout.list_layout_unique, null);
}
Et c'est fait!
pour créer une bordure, vous devez créer un autre fichier xml avec la propriété de solide et de coins dans le dossier pouvant être dessiné et l'appeler en arrière-plan
J'utilise une vue personnalisée que je dispose au-dessus des autres et qui dessine simplement les 4 petits coins de la même couleur que l'arrière-plan. Cela fonctionne quel que soit le contenu de la vue et n'alloue pas beaucoup de mémoire.
public class RoundedCornersView extends View {
private float mRadius;
private int mColor = Color.WHITE;
private Paint mPaint;
private Path mPath;
public RoundedCornersView(Context context) {
super(context);
init();
}
public RoundedCornersView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.RoundedCornersView,
0, 0);
try {
setRadius(a.getDimension(R.styleable.RoundedCornersView_radius, 0));
setColor(a.getColor(R.styleable.RoundedCornersView_cornersColor, Color.WHITE));
} finally {
a.recycle();
}
}
private void init() {
setColor(mColor);
setRadius(mRadius);
}
private void setColor(int color) {
mColor = color;
mPaint = new Paint();
mPaint.setColor(mColor);
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
invalidate();
}
private void setRadius(float radius) {
mRadius = radius;
RectF r = new RectF(0, 0, 2 * mRadius, 2 * mRadius);
mPath = new Path();
mPath.moveTo(0,0);
mPath.lineTo(0, mRadius);
mPath.arcTo(r, 180, 90);
mPath.lineTo(0,0);
invalidate();
}
@Override
protected void onDraw(Canvas canvas) {
/*Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawRect(0, 0, mRadius, mRadius, paint);*/
int w = getWidth();
int h = getHeight();
canvas.drawPath(mPath, mPaint);
canvas.save();
canvas.translate(w, 0);
canvas.rotate(90);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.save();
canvas.translate(w, h);
canvas.rotate(180);
canvas.drawPath(mPath, mPaint);
canvas.restore();
canvas.translate(0, h);
canvas.rotate(270);
canvas.drawPath(mPath, mPaint);
}
}