0
votes

Android: Manipulation de la taille du texte pour différents appareils DIP

Je reçois une taille de texte différente pour la même taille de l'écran, différents périphériques DPI. Je veux que le texte soit exactement de la même taille sur tous les périphériques (comme Inshort app).

Entrez la description de l'image ici p>

comme on peut le voir dans ces captures d'écran Taille du texte de XXHDPI est légèrement plus grand que 560 dpi Device. P>

My Disposition XML: P>

P>

<?xml version="1.0" encoding="utf-8"?>
<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"
    tools:context=".MainActivity"
    android:layout_margin="30dp">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum."
        android:textSize="14sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>


5 commentaires

Convertissez les valeurs dans plusieurs parties , comme..small, moyen, normal, grand et extra-grand..et valeurs à l'intérieur de ces fichiers.


Utilisez DP au lieu de SP pour la taille du texte


@Parthlotia J'ai essayé aussi que le problème est que mon deux appareils est sous la catégorie grande, il n'y a pas de changement.


@underoid comme mentionné, j'ai essayé dp aussi sans aucun succès.


Le problème est que votre largeur TextView n'est pas constante (Wrap_Content), si vous faites une largeur de votre constante TextView en taille de texte DP dans DP devrait fonctionner.


5 Réponses :


0
votes

Si vous voulez que vos tailles de texte soient indépendantes de la densité, vous devez utiliser DP au lieu de SP.

De cette façon, vos tailles de texte ne seront pas également affectées par l'utilisateur Textsize Préférences dans les paramètres de téléphone.


1 commentaires

Comme mentionné dans ma question, j'ai essayé dp mais n'a aucun effet. Les tailles de texte étaient différentes après avoir utilisé DP comme dans les captures d'écran.



0
votes

Ajoutez la classe suivante (AutoFeizetextView) dans votre projet, puis ajoutez le code suivant dans votre XML. À la valeur Android: Maxlines = "1" Mettez ce que vous voulez, donc le calcul automatique modifie la taille de la police xxx pré>

voici la classe AutoFeReizetextViews P>

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.RectF;
import android.os.Build;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.method.TransformationMethod;
import android.util.AttributeSet;
import android.util.SparseIntArray;
import android.util.TypedValue;
import android.widget.TextView;

/**
 * http://stackoverflow.com/questions/16017165/auto-fit-textview-for-android/21851239
 */
public class AutoResizeTextView extends TextView {

    public AutoResizeTextView(Context context) {
        super(context);
        initialize();
    }

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

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

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public AutoResizeTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initialize();
    }

    private interface SizeTester {
        /**
         *
         * @param suggestedSize
         *            Size of text to be tested
         * @param availableSpace
         *            available space in which text must fit
         * @return an integer < 0 if after applying {@code suggestedSize} to
         *         text, it takes less space than {@code availableSpace}, > 0
         *         otherwise
         */
        public int onTestSize(int suggestedSize, RectF availableSpace);
    }

    private RectF mTextRect = new RectF();

    private RectF mAvailableSpaceRect;

    private SparseIntArray mTextCachedSizes;

    private TextPaint mPaint;

    private float mMaxTextSize;

    private float mSpacingMult = 1.0f;

    private float mSpacingAdd = 0.0f;

    private float mMinTextSize = 10;

    private int mWidthLimit;

    private static final int NO_LINE_LIMIT = -1;
    private int mMaxLines;

    private boolean mEnableSizeCache = true;
    private boolean mInitializedDimens;

    private void initialize() {
        mPaint = new TextPaint(getPaint());
        mMaxTextSize = getTextSize();
        mAvailableSpaceRect = new RectF();
        mTextCachedSizes = new SparseIntArray();
        if (mMaxLines == 0) {
            // no value was assigned during construction
            mMaxLines = NO_LINE_LIMIT;
        }
    }

    @Override
    public void setTextSize(float size) {
        mMaxTextSize = size;
        mTextCachedSizes.clear();
        adjustTextSize();
    }

    @Override
    public void setMaxLines(int maxlines) {
        super.setMaxLines(maxlines);
        mMaxLines = maxlines;
        adjustTextSize();
    }

    public int getMaxLines() {
        return mMaxLines;
    }

    @Override
    public void setSingleLine() {
        super.setSingleLine();
        mMaxLines = 1;
        adjustTextSize();
    }

    @Override
    public void setSingleLine(boolean singleLine) {
        super.setSingleLine(singleLine);
        if (singleLine) {
            mMaxLines = 1;
        } else {
            mMaxLines = NO_LINE_LIMIT;
        }
        adjustTextSize();
    }

    @Override
    public void setLines(int lines) {
        super.setLines(lines);
        mMaxLines = lines;
        adjustTextSize();
    }

    @Override
    public void setTextSize(int unit, float size) {
        Context c = getContext();
        Resources r;

        if (c == null)
            r = Resources.getSystem();
        else
            r = c.getResources();
        mMaxTextSize = TypedValue.applyDimension(unit, size,
                r.getDisplayMetrics());
        mTextCachedSizes.clear();
        adjustTextSize();
    }

    @Override
    public void setLineSpacing(float add, float mult) {
        super.setLineSpacing(add, mult);
        mSpacingMult = mult;
        mSpacingAdd = add;
    }

    /**
     * Set the lower text size limit and invalidate the view
     *
     * @param minTextSize
     */
    public void setMinTextSize(float minTextSize) {
        mMinTextSize = minTextSize;
        adjustTextSize();
    }

    private void adjustTextSize() {
        if (!mInitializedDimens) {
            return;
        }
        int startSize = (int) mMinTextSize;
        int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom()
                - getCompoundPaddingTop();
        mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
                - getCompoundPaddingRight();
        mAvailableSpaceRect.right = mWidthLimit;
        mAvailableSpaceRect.bottom = heightLimit;
        super.setTextSize(
                TypedValue.COMPLEX_UNIT_PX,
                efficientTextSizeSearch(startSize, (int) mMaxTextSize,
                        mSizeTester, mAvailableSpaceRect));
    }

    private final SizeTester mSizeTester = new SizeTester() {
        @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
        @Override
        public int onTestSize(int suggestedSize, RectF availableSPace) {
            mPaint.setTextSize(suggestedSize);
            String text = getTransformedText();
            boolean singleline = getMaxLines() == 1;
            if (singleline) {
                mTextRect.bottom = mPaint.getFontSpacing();
                mTextRect.right = mPaint.measureText(text);
            } else {
                StaticLayout layout = new StaticLayout(text, mPaint,
                        mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult,
                        mSpacingAdd, true);
                // return early if we have more lines
                if (getMaxLines() != NO_LINE_LIMIT
                        && layout.getLineCount() > getMaxLines()) {
                    return 1;
                }
                mTextRect.bottom = layout.getHeight();
                int maxWidth = -1;
                for (int i = 0; i < layout.getLineCount(); i++) {
                    if (maxWidth < layout.getLineWidth(i)) {
                        maxWidth = (int) layout.getLineWidth(i);
                    }
                }
                mTextRect.right = maxWidth;
            }

            mTextRect.offsetTo(0, 0);
            if (availableSPace.contains(mTextRect)) {
                // may be too small, don't worry we will find the best match
                return -1;
            } else {
                // too big
                return 1;
            }
        }
    };

    /**
     * Enables or disables size caching, enabling it will improve performance
     * where you are animating a value inside TextView. This stores the font
     * size against getText().length() Be careful though while enabling it as 0
     * takes more space than 1 on some fonts and so on.
     *
     * @param enable
     *            enable font size caching
     */
    public void enableSizeCache(boolean enable) {
        mEnableSizeCache = enable;
        mTextCachedSizes.clear();
        adjustTextSize();
    }

    private int efficientTextSizeSearch(int start, int end,
                                        SizeTester sizeTester, RectF availableSpace) {
        if (!mEnableSizeCache) {
            return binarySearch(start, end, sizeTester, availableSpace);
        }
        int key = getText().toString().length();
        int size = mTextCachedSizes.get(key);
        if (size != 0) {
            return size;
        }
        size = binarySearch(start, end, sizeTester, availableSpace);
        mTextCachedSizes.put(key, size);
        return size;
    }

    private static int binarySearch(int start, int end, SizeTester sizeTester,
                                    RectF availableSpace) {
        int lastBest = start;
        int lo = start;
        int hi = end - 1;
        int mid;
        while (lo <= hi) {
            mid = (lo + hi) >>> 1;
            int midValCmp = sizeTester.onTestSize(mid, availableSpace);
            if (midValCmp < 0) {
                lastBest = lo;
                lo = mid + 1;
            } else if (midValCmp > 0) {
                hi = mid - 1;
                lastBest = hi;
            } else {
                return mid;
            }
        }
        // make sure to return last best
        // this is what should always be returned
        return lastBest;

    }

    @Override
    protected void onTextChanged(final CharSequence text, final int start,
                                 final int before, final int after) {
        super.onTextChanged(text, start, before, after);
        adjustTextSize();
    }

    @Override
    protected void onSizeChanged(int width, int height, int oldwidth,
                                 int oldheight) {
        mInitializedDimens = true;
        mTextCachedSizes.clear();
        super.onSizeChanged(width, height, oldwidth, oldheight);
        if (width != oldwidth || height != oldheight) {
            adjustTextSize();
        }
    }

    private String getTransformedText() {
        CharSequence text = getText();
        if (text != null) {
            TransformationMethod transformationMethod = getTransformationMethod();
            if (transformationMethod != null) {
                text = transformationMethod.getTransformation(text, this);
            }
        }
        return text == null ? null : text.toString();
    }
}


7 commentaires

Quelle différence entre développeur.android.com/Guide/topics / UI / look-and-sentir / ... et votre AutoFeReizetextView ?


@Natigbabayev Cette classe peut être utilisée pour toute version Android. Non seulement Android 8+ Comme votre lien dit


Lien également indique: "La bibliothèque de support 26.0 fournit une prise en charge complète de la fonctionnalité Autosize TextView sur les périphériques exécutant des versions Android antérieures à Android 8.0 (niveau 26 de l'API 26). La bibliothèque assure la prise en charge de Android 4.0 (niveau API 14) et plus. L'Android. Support.v4.Widget Package contient la classe TextViewCompat pour accéder aux fonctionnalités d'une manière compatible vers l'arrière. " Donc, fondamentalement, cela fonctionne sous Android 8 aussi.


@Christosthemelis mais mentionné comme mentionné, j'ai besoin exacte de la même taille de texte sur tous les périphériques et non de redimensionnement automatique en fonction de l'espace disponible.


@Sid, je pensais que tu voulais le même ratio. mon erreur. Essayez d'utiliser "PX" au lieu de "SP"


@Christosthemelis utilisant px n'aide pas non plus. Pour une taille de densité supérieure, la taille devient petite et inférieure, elle devient grande en cas de px. J'ai aussi essayé d'utiliser (px * getresources (). Getdisplaymetrics (). Densité) sans succès.


Je vais vous fournir une partie de mon projet qui fait quelque chose comme vous le souhaitez, juste pour savoir comment



0
votes

Vous devez utiliser des dimens pour comprendre que s'il vous plaît visitez les liens suivants:

Pour plus de détails, visite Dimens

Regardez également la réponse à la question suivante: Comment utiliser dimens.xml


1 commentaires

Merci pour le lien. Mais de ces liens, j'ai conclu que l'utilisation de DP devrait me donner exactement la même taille de texte et dans le cas de la taille du texte SP peut changer en fonction de la taille de la police sélectionnée du paramètre de périphérique Android. Et comme je l'ai mentionné, j'ai déjà utilisé DP et SP, et avoir une taille de texte différente dans différents appareils. S'il vous plait corrigez moi si je me trompe.



0
votes

Essayez différents dimens

Créer un fichier dimens.xml (SW-320DP-XHDPI) P>

 <resources>
         <dimen name="textSize">14sp</dimen>
  </resources>


1 commentaires

@Sidez-vous essayer cette solution?



0
votes

Voici une partie de mon projet qui redimensionne le texte en fonction de la taille de l'écran. Est-ce ce que vous voulez?

double height;
double width = parent.getMeasuredWidth();

boolean isLandscape;
if ( getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT ) {
    isLandscape = false;
    height = parent.getMeasuredHeight() / 3;
    width = width + (parent.getPaddingLeft() + parent.getPaddingRight());
} else {
    isLandscape = true;
    height = parent.getMeasuredHeight() / 2;
    width = parent.getMeasuredWidth() / 2;
    width = width + ((parent.getPaddingLeft() + parent.getPaddingRight()) / 2);
}       

height = height + (parent.getPaddingTop() + parent.getPaddingBottom());

view.setMinimumHeight((int) Math.round(height));

double h = height / 100;
double w = width / 100; 

if ( isLandscape ) {
    textViewService.setX((int) Math.round(w * 24));
    textViewService.setTextSize(TypedValue.COMPLEX_UNIT_PX, (int) Math.round(16 * h));
} else {
    textViewService.setX((int) Math.round(w * 23));
    textViewService.setTextSize(TypedValue.COMPLEX_UNIT_PX, (int) Math.round(18 * h));
}


0 commentaires