TextView getting cut in some resolutions

2019-02-16 09:17发布

问题:

I have a RecyclerView which consists of CardViews that have a TextView and an ImageView, among some other layouts.
The problem is, in some screen resolutions the TextView gets cut off or shoved to the next line, which I don't want.
In other resolutions, the TextView has plenty of room.

Small Resolutions:

High Resolutions:

How do I organize the layout so that there is enough room for the TextView, and the ImageView will be sized accordingly?

This is my xml for the RecyclerView items:

<android.support.v7.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cardview="http://schemas.android.com/apk/res-auto"
android:id="@+id/zmanCard"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_gravity="center_horizontal"
android:gravity="center_horizontal"
cardview:cardUseCompatPadding="false"
cardview:cardPreventCornerOverlap="false"
cardview:cardCornerRadius="4dp"
cardview:cardElevation="2dp">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="?attr/colorPrimary"
    android:orientation="vertical">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="20dp"
        android:layout_gravity="top"
        android:gravity="center"
        android:orientation="vertical"
        android:background="?attr/colorPrimaryDark">
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/zmanCardTitle"
            android:textColor="#ffffff"
            android:gravity="center"
            android:textSize="13sp" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView
            android:layout_width="24dp"
            android:layout_height="wrap_content"
            android:layout_marginTop="2dp"
            android:layout_marginLeft="2dp"
            android:layout_marginRight="4dp"
            android:alpha="0.8"
            android:id="@+id/zmanCardImage" />
        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="7dp"
            android:layout_marginLeft="0dp"
            android:layout_marginRight="4dp">
            <TextView
                android:text="5:40"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="2dp"
                android:id="@+id/zmanCardTime"
                android:textColor="#ffffff"
                android:textSize="18sp" />
            <ProgressBar
                android:id="@+id/zmanProgressBar"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_gravity="top|left"
                style="@style/Base.Widget.AppCompat.ProgressBar" />
        </FrameLayout>
    </LinearLayout>
</LinearLayout>

回答1:

Try this. Works 100%.

AutoResizeTextView or sdp unit can help you.

SDP - a scalable size unit

An android SDK that provides a new size unit - sdp (scalable dp). This size unit scales with the screen size. It can help Android developers with supporting multiple screens.

for text views please refer to ssp which is based on the sp size unit for texts.

https://github.com/intuit/sdp

Auto Scale TextView Text to Fit within Bounds

And if you want support different layout designs for different screen:

res/layout/my_layout.xml             // layout for normal screen size ("default")
res/layout-small/my_layout.xml       // layout for small screen size
res/layout-large/my_layout.xml       // layout for large screen size
res/layout-xlarge/my_layout.xml      // layout for extra large screen size
res/layout-xlarge-land/my_layout.xml // layout for extra large in landscape orientation

Fore more information look here



回答2:

A TextView that automatically resizes text to fit perfectly within its bounds.

Usage:

dependencies {
    compile 'me.grantland:autofittextview:0.2.+'
}

Enable any View extending TextView in code:

AutofitHelper.create(textView);

Enable any View extending TextView in XML:

<me.grantland.widget.AutofitLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    >
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:singleLine="true"
        />
</me.grantland.widget.AutofitLayout>

Use the built in Widget in code or XML:

<RootElement
    xmlns:autofit="http://schemas.android.com/apk/res-auto"
    ...
<me.grantland.widget.AutofitTextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:singleLine="true"
    android:maxLines="2"
    android:textSize="40sp"
    autofit:minTextSize="16sp"
    />

Reference Link : https://github.com/grantland/android-autofittextview



回答3:

I can suggest two step solution one for your text size so with wrap_content attribute it gets fit to text and I suggest using a qualifier to provide several alternative layouts to target different screen configurations. You do so by using configuration qualifiers, which allows the run-time to automatically select the appropriate resource based on the current device’s configuration (such as a different layout design for different screen sizes). Supporting Different Screen Sizes

from this part till the end i copied my answer from this link from @Herry's answer: I think you need to check this Google IO Pdf for Design. In that pdf go to Page No:77 in which you will find how there suggesting for using dimens.xml for different devices of android for example see below structure:

res/values/dimens.xml

res/values-small/dimens.xml

res/values-normal/dimens.xml

res/values-large/dimens.xml

res/values-xlarge/dimens.xml

for Example you have used below dimens.xml in values.

<?xml version="1.0" encoding="utf-8"?>
<resources>
   <dimen name="text_size">18sp</dimen>
</resources>

In other values folder you need to change values for your text size.

for example:

<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
    <dimen name="font_size_small">10sp</dimen>
    <dimen name="font_size_medium">20sp</dimen>
    <dimen name="font_size_large">30sp</dimen>
</resources>


回答4:

If you want scalable screens, You shouldn't use fixed height or width as much as possible. In your case, you should place your components proportionately with layout_weight.

For more details;

What does android:layout_weight mean?



回答5:

For more simple way create your layout using relative layout with some proper technic sure it will resolve. if still haveing issue ask me for .xml file



回答6:

You should use padding so that textview always has some fixed padding and it never gets cut. In your code make following changes

  <TextView
            android:text="5:40"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginLeft="2dp"
            android:id="@+id/zmanCardTime"
            android:textColor="#ffffff"
            android:padding:"3dp"
            android:textSize="18sp" />


回答7:

Here you go again 2nd time with the key word

Resolution

What are the options you have in hand now?

  • Supporting Multiple Screens

    1 Multiple layouts 2.Multiple dimens

  • Famous Answer on this particular question (Auto Scale Text-view Text to Fit within Bounds)

  • Usage of Weight_sum attribute
  • GitHub Libraries like AutoFitTextView , SDP

Just summarized those answers(All-in-one)! any other options left?

As I can see your problem is bound with two hand in hand cases.

  1. Of course your text does not resize 2.Your layout is too much flexible.

See sometimes TextView itself go down.Any other options that you can try to avoid this, instead of your solutions that you have?

PercentRelativeLayout

Any extra advantage of this ? Yes, this supports percentage based dimensions and margins,You have set fixed margins and this will give you them using a percentage.It even have a cool attribute called layout_aspectRatio. Here is a link for a small tutorial.

Give sizes based on ratio / absolute position of a view

Before PercentRelativeLayout I mostly used this.First you need to have a model image/sketch of your view. My model is with 1920 px in height and 1080 in width (Normally its an HDTV resolution,16:9 aspect ratio)

In that image we know where the views are positioned.

Then for any view/any other screen I can use the same ratio to position them using LayoutParams. Now view stays according to your rules.

Here is an example:

DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
height = displaymetrics.heightPixels;
width = displaymetrics.widthPixels;

LinearLayout.LayoutParams topLenP= new LinearLayout.LayoutParams(300 * width / 1080, 400 * width / 1920); 
//topLenP.topMargin = x* height / 1920;
//topLenP.leftMargin = y* width / 1080;
myView.setLayoutParams(topLenP);

What actually I did here,as I said in my model view this view took 300 width , 400 in height,with this I am adjusting that same ratio for my currant screen.(using currant screen size).

Moving back to auto scaling since now we have a same ratio based view here is another good answer.

Auto-fit TextView for Android

android:textAppearance

Finally there are fixed sizes given in the android \platforms\android-X\data\res\values\themes.xml based on small, large and medium.

Without specifying what you exactly need you can also use it as

<TextView
   android:textAppearance="?android:attr/textAppearance"
   ....
   /> 

Hope this helps!



回答8:

try giving weight to the textview layout and imageview layout give weight 1 to both layouts



回答9:

Use AutoScaleTextView

The AutoScaleTextView takes the android:textSize value and uses it as the preferred text size. You can also set the minimum text size. The default for the minimum text size is 10dp. The AutoScaleTextView now tries to take the maximum value between the preferred and minimum size that fits into the Views width (with regarding the padding).

Please find full AutoScaleTextView class and its implementations in below LINK

http://ankri.de/autoscale-textview/



回答10:

Solution 1

https://developer.android.com/guide/practices/screens_support.html

// The TEXT SIZE in dp
private static final float TEXT_SIZE_DP = 16.0f;

// Get the screen's density scale
final float scale = getResources().getDisplayMetrics().density;
// Convert the dps to pixels, based on density scale
int textSize = (int) (TEXT_SIZE_DP * scale + 0.5f);

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,textSize);

Solution 2:

float dpi = getResources().getDisplayMetrics().widthPixels;
dpi = dpi / 320;

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX,TEXT_SIZE_DP*dpi);

How its Work refer below link

http://canvasonandroid.blogspot.in/2016/04/how-to-scale-font-size-for-different.html

Note: It will work only on the device, not on the tablet. we need to write different logic for the tablet. for this you need to set font size in dimen.xml



回答11:

I think you should not fix the spanCount of GridLayout. It would be better if for high resolutions you will display 4 items, for small resolutions you display 3 items, for landscape display 5 items, ...

To do that you should create a constants for all values folder that you will support like

res/values-small/dimens.xml
      constants.xml
res/values-large/dimens.xml
      constants.xml

for each constants.xml, it will look like

<resources>
<integer name="span_count">3</integer>
</resources>

Then when you create GridLayoutManager

GridLayoutManager lm = new GridLayoutManager(Context context, getContext().getResources().getInteger(R.integer.span_count));

After you do like this, your problem will not happend



回答12:

My experience in android I always use dp instead of sp, so u fix the dp value for all your textviews and will fit anyscreen.

Let me know if any issue.

Best Regds