web-dev-qa-db-fra.com

android: ajuster la hauteur de DrawableLeft dans un textView

J'essaie d'afficher une ligne bleue à côté d'un bloc de texte, un peu comme ceci:

enter image description here

Voici mon code:

<TextView
            Android:id="@+id/textView1"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:drawableLeft="@drawable/blue_line" />

blue_line est un fichier jpg. un rectangle bleu. il affiche dans sa taille d'origine quel que soit le texte dans la vue texte. Comment puis-je ajuster sa hauteur dynamiquement en fonction de la hauteur du texte? comme le rendre plus court quand il y a peu de texte et plus quand il y a plus de texte ....

25
user1659274

Vous pouvez essayer de le faire dans le code en définissant des limites pour l'image

textView1.getViewTreeObserver()
        .addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Drawable img = ActivityName.this.getContext().getResources().getDrawable(
                R.drawable.blue_line);
            img.setBounds(0, 0, img.getIntrinsicWidth() * textView1.getMeasuredHeight() / img.getIntrinsicHeight(), textView1.getMeasuredHeight());
            textView1.setCompoundDrawables(img, null, null, null);
            textView1.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        }
    });
28
vipul mittal

La meilleure façon de procéder consiste à envelopper votre dessin dans un fichier xml et de le définir comme dessin dans votre affichage texte comme suit:

Fichier XML dessinable:

<?xml version="1.0" encoding="utf-8"?>
<bitmap 
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:scaleType="fitXY"
    Android:src="@drawable/total_calories"/>

TextView en XML:

<TextView 
    Android:id="@+id/title_total_cal"
    style="@style/title_stats_textview"
    Android:drawableLeft="@drawable/total_calories_drawable"/>
6
Droid Chris

Essayez comme ci-dessous ...

<RelativeLayout
    Android:layout_width="wrap_content"
    Android:layout_height="wrap_content" >

    <ImageView
        Android:id="@+id/imageView"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:src="@drawable/btndr" />

    <TextView
        Android:id="@+id/textView1"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_toRightOf="@+id/imageView" />

</RelativeLayout>
3
Hamid Shatu

Simplement, gardez votre image comme dessin 9patch.

Vous pouvez ajouter Android:drawableLeft="@drawable/checkmark" à votre textview. Vous pouvez également définir drawablePadding pour que la vue texte soit organisée. 

Android:drawableLeft="@drawable/button_icon"
Android:drawablePadding="2dip"

Voici le lien pour créer 9patch drawable

<TextView Android:text="@string/txtUserName" 
Android:id="@+id/txtUserName"
Android:layout_width="160dip"
Android:layout_height="60dip"
Android:layout_gravity="center"
Android:drawableLeft="@drawable/button_icon"
Android:drawablePadding="2dip"
/>  
2

Vous pouvez dessiner une ligne de la hauteur désirée sur une toile dessinable et la définir comme dessinable à gauche de votre TextView. regarde ça:

public class FullHeightLineDrawable extends Drawable {
    private Paint mPaint;
    private int mHeight;

    public FullHeightLineDrawable(int height) {
        mPaint = new Paint();
        mPaint.setColor(CompatUtils.getColor(R.color.colorAccent));
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(15);

        mHeight = height;
    }

    @Override
    public void draw(Canvas canvas) {
        canvas.drawLine(0, -mHeight, 0, mHeight, mPaint);
    }

    @Override
    public void setAlpha(int alpha) {
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
    }

    @Override
    public int getOpacity() {
        return 0;
    }
}

Usage:

final Drawable drawable = new FullHeightLineDrawable(getHeight());
mTextView.setTextColor(watchingColor);
mTextView.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
1
Ali Mehrpour

J'ai créé une classe qui étend TextView et redimensionne les éléments dessinables dans onPreDrawListener.

public class MyTextView extends AppCompatTextView {

    public MyTextView(Context context, AttributeSet attrs, int style) {
        super(context, attrs, style);
        fitCompoundDrawableToLineHeight();
    }

    private void fitCompoundDrawableToLineHeight() {
        OnPreDraw.run(this, () -> {
            final Drawable[] cd = getCompoundDrawables();
            Arrays.stream(cd)
                .filter(drawable -> drawable != null)
                .forEach(d -> d.setBounds(0, 0, getLineHeight(), getLineHeight()));
            setCompoundDrawables(cd[0], cd[1], cd[2], cd[3]);
        });
    }
}

// Convenience class that abstracts onPreDraw logic
public class OnPreDraw {
    public static void run(View view, Runnable task) {
        view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                if (!view.getViewTreeObserver().isAlive()) {
                    return true;
                }
                view.getViewTreeObserver().removeOnPreDrawListener(this);
                task.run();
                return true;
            }
        });
    }
}
0
guy.gc

Malheureusement, setBounds ne fonctionnait pas pour moi, j'ai donc dû contourner le problème.

// Turn wanted drawable to bitmap
Drawable dr = getResources().getDrawable(R.drawable.somedrawable);
Bitmap bitmap = ((BitmapDrawable) dr).getBitmap();

// I had a square image with same height and width so I needed only TextView height (getLineHeight)
int size = textView1.getLineHeight();
Drawable d = new BitmapDrawable(getResources(), Bitmap.createScaledBitmap(bitmap, size, size, true));
textView1.setCompoundDrawables(d, null, null, null);

// Now we can set some spacing between text and image
textView1.setCompoundDrawablePadding(10);

Ce n'est pas la meilleure solution en termes de performances, car un nouveau bitmap est créé, mais fonctionne toujours.

0
Tomislav Brabec

Je résume cette méthode. Cela fonctionne quand le dessinable est à gauche du TextView, une mise à l'échelle dynamique. Si drawable est sur le côté droit, cette méthode ne fonctionne pas, vous devez donc comprendre pourquoi, mais vous pouvez simplement utiliser directement textView.setcompounddrawableswithintrinsicbounds() avec la ressource Drawable de taille appropriée.

@RequiresApi(api = Build.VERSION_CODES.HONEYCOMB)
public static void ajustCompoundDrawableSizeWithText(final TextView textView, final Drawable leftDrawable, final Drawable topDrawable, final Drawable rightDrawable, final Drawable bottomDrawable) {
    textView.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
           if(leftDrawable != null){
               leftDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
           }
            if(topDrawable != null){
                topDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
            }
            if(rightDrawable != null){
                rightDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
            }
            if(bottomDrawable != null){
                bottomDrawable.setBounds(0, 0, (int)textView.getTextSize(), (int)textView.getTextSize());
            }
            textView.setCompoundDrawables(leftDrawable, topDrawable, rightDrawable, bottomDrawable);
                textView.removeOnLayoutChangeListener(this);
        }
    });
}
0
KyleZB