web-dev-qa-db-fra.com

Comment aligner drawableLeft to top à la place du centre dans Android TextView?

Dans TextView j'ai placé drawableLeft où la drawable est affichée depuis le centre. Je dois aligner la drawableLeft avec le haut à l'intérieur de TextView comme cette image. 

enter image description here

Est-il possible d'y parvenir?

27
androidcodehunter

Voir ma réponse ici .

Vous pouvez aligner un composé-Drawable vers le haut (ou le bas) en créant un Drawable personnalisé qui enveloppe votre Drawable, puis manipuler le dessin de votre Drawable personnalisé en remplaçant la méthode onDraw(Canvas).

L'exemple ci-dessous est l'exemple le plus simple possible. Cela aligne l'image en haut, mais vous pouvez également l'aligner en bas, à gauche ou à droite de TextView en implémentant la logique requise dans la méthode onDraw(Canvas)-. Vous voudrez peut-être également insérer une marge dans la onDraw(Canvas), pour rendre votre pixel d'implémentation de la conception parfait.

Exemple d'utilisation:

GravityCompoundDrawable gravityDrawable = new GravityCompoundDrawable(innerDrawable);
// NOTE: next 2 lines are important!
innerDrawable.setBounds(0, 0, innerDrawable.getIntrinsicWidth(), innerDrawable.getIntrinsicHeight());
gravityDrawable.setBounds(0, 0, innerDrawable.getIntrinsicWidth(), innerDrawable.getIntrinsicHeight());
mTextView.setCompoundDrawables(gravityDrawable, null, null, null);

Exemple de code:

public class GravityCompoundDrawable extends Drawable {

    // inner Drawable
    private final Drawable mDrawable;

    public GravityCompoundDrawable(Drawable drawable) {
        mDrawable = drawable;
    }

    @Override
    public int getIntrinsicWidth() {
        return mDrawable.getIntrinsicWidth();
    }

    @Override
    public int getIntrinsicHeight() {
        return mDrawable.getIntrinsicHeight();
    }

    @Override
    public void draw(Canvas canvas) {
        int halfCanvas= canvas.getHeight() / 2;
        int halfDrawable = mDrawable.getIntrinsicHeight() / 2;

        // align to top
        canvas.save();
        canvas.translate(0, -halfCanvas + halfDrawable);
        mDrawable.draw(canvas);
        canvas.restore();
    }
}
6
Reinier

Utilisez SpannableString et ImageSpan pour y parvenir.

String msg=" "+"haii";
ImageSpan mImageSpan== new ImageSpan(mContext, R.drawable.icon);
SpannableString text = new SpannableString(msg);
text.setSpan(mImageSpan, 0, 1, 0);
mTextView.setText(text);

l'espace supplémentaire dans la variable chaîne est remplacé par l'icône.

4
Rahul M Mohan

Je pense que c'est encore plus facile que toutes les réponses ci-dessus: Il suffit de faire ceci:

public class TopGravityDrawable extends BitmapDrawable {

    public TopGravityDrawable(Resources res, Bitmap bitmap) {
        super(res, bitmap);
    }

    @Override
    public void draw(Canvas canvas) {
        int halfCanvas = canvas.getHeight() / 2;
        int halfDrawable = getIntrinsicHeight() / 2;
        canvas.save();
        canvas.translate(0, -halfCanvas + halfDrawable);
        super.draw(canvas);
        canvas.restore();
    }
}

Et alors

 final Bitmap bitmap = BitmapFactory.decodeResource(mTitle.getResources(), R.drawable.icon);
 icon = new TopGravityDrawable(mTitle.getResources(), bitmap);
 title.setCompoundDrawablesWithIntrinsicBounds(null, null, null, icon);

Rappelez-vous que cela ne fonctionne que correctement avecLEFTetRIGHTdrawables composés 

4
cesards

Si vous voulez une solution purement XML, vous pouvez utiliser un encadré dessinable pour repositionner votre dessinable souhaité.

<?xml version="1.0" encoding="utf-8"?>
<inset
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:drawable="@drawable/actual_image_to_be_shown"
    Android:insetTop="-32dp" />

Vous devrez peut-être jouer avec la valeur d’encart en fonction de votre scénario. Ensuite, utilisez simplement ce fichier XML pouvant être dessiné dans votre définition TextView drawableLeft/Start.

1
Andrew Kelly

vous pouvez faire comme ça:

public class DrawableTopLeftTextView extends TextView {

    public DrawableTopLeftTextView(Context context) {
        super(context);
    }

    public DrawableTopLeftTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public DrawableTopLeftTextView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (!TextUtils.isEmpty(getText())) {

            Drawable[] drawables = getCompoundDrawables();

            if (drawables != null) {

                Drawable drawableLeft = drawables[0];

                if (drawableLeft != null) {

                    Paint.FontMetricsInt fontMetricsInt = getPaint().getFontMetricsInt();
                    Rect bounds = new Rect();
                    getPaint().getTextBounds((String) getText(), 0, length(), bounds);
                    int textVerticalSpace = Math.round(bounds.top - fontMetricsInt.top);
                    int offset = (getHeight() - drawableLeft.getIntrinsicHeight()) / 2 - textVerticalSpace - getPaddingTop() / 2;
                    drawableLeft.setBounds(0, -offset, drawableLeft.getIntrinsicWidth(), drawableLeft.getIntrinsicHeight() - offset);
                }
            }
        }
        super.onDraw(canvas);
    }
}
0
xzw happy