可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a RecyclerView
which consists of CardView
s 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.
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