テキストに\n
を含むTextView
がある場合、右側に2つのsingleLine
TextView
sがあり、その間に上下にスペースがありません。 3つのTextView
sすべてに対して以下を設定しました。
Android:lineSpacingMultiplier="1"
Android:lineSpacingExtra="0pt"
Android:paddingTop="0pt"
Android:paddingBottom="0pt"
左のTextView
の最初の行は、右上のTextView
と完全に一致します。
左のTextView
の2行目は、右下のTextView
の2行目より少し高くなっています。
TextView
sの上部と下部に何らかの隠しパディングがあるようです。どうすれば削除できますか?
setIncludeFontPadding (boolean includepad)
またはXML
で次のようになります。
Android:includeFontPadding="false"
TextView
に追加の上部および下部パディングを含めるかどうかを設定して、通常の上昇および下降を超えるアクセントのためのスペースを確保します。デフォルトはtrueです。
あなたの痛みが分かります。 setIncludeFontPadding
をfalseにするなど、上記のすべての回答を試しましたが、何もしませんでした。
私の解決策は? TextView
のlayout_marginBottom="-3dp"
は、ボトムの解決策を提供します、BAM!
ただし、layout_marginTop
の-3dpは失敗します。
私は適切な答えをたくさん探しましたが、TextView
からすべてのパディングを正確に削除できる答えを見つけることができませんでしたが、最終的に official doc を回避した後、単一行テキスト
Android:includeFontPadding="false"
Android:lineSpacingExtra="0dp"
これらの2行をTextView
xmlに追加すると、作業が行われます。
最初の属性は、アクセントのために予約されているパディングを削除し、2番目の属性は、2行のテキスト間の適切なスペースを維持するために予約されているスペースを削除します。
複数行のTextViewに
lineSpacingExtra="0dp"
を追加しないようにしてください。
これも私を悩ませ、私が見つけた答えは、TextViewではなく、フォント自体に実際には追加のスペースがあるということでした。文書発行の背景から来る、かなり刺激的です。活版印刷要素に対するAndroidの制御は限られています。この問題がない可能性のあるカスタム書体(再配布用にライセンスされているBitstream Vera Sansなど)を使用することをお勧めします。ただし、そうするかどうかは明確にわかりません。
カスタムビュー(NoPaddingTextView)の間隔を削除します。
https://github.com/SenhLinsh/NoPaddingTextView
package com.linsh.nopaddingtextview;
import Android.content.Context;
import Android.graphics.Canvas;
import Android.util.AttributeSet;
import Android.util.Log;
import Android.util.TypedValue;
import Android.widget.TextView;
/**
* Created by Senh Linsh on 17/3/27.
*/
public class NoPaddingTextView extends TextView {
private int mAdditionalPadding;
public NoPaddingTextView(Context context) {
super(context);
init();
}
public NoPaddingTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setIncludeFontPadding(false);
}
@Override
protected void onDraw(Canvas canvas) {
int yOff = -mAdditionalPadding / 6;
canvas.translate(0, yOff);
super.onDraw(canvas);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
getAdditionalPadding();
int mode = MeasureSpec.getMode(heightMeasureSpec);
if (mode != MeasureSpec.EXACTLY) {
int measureHeight = measureHeight(getText().toString(), widthMeasureSpec);
int height = measureHeight - mAdditionalPadding;
height += getPaddingTop() + getPaddingBottom();
heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
private int measureHeight(String text, int widthMeasureSpec) {
float textSize = getTextSize();
TextView textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
textView.setText(text);
textView.measure(widthMeasureSpec, 0);
return textView.getMeasuredHeight();
}
private int getAdditionalPadding() {
float textSize = getTextSize();
TextView textView = new TextView(getContext());
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
textView.setLines(1);
textView.measure(0, 0);
int measuredHeight = textView.getMeasuredHeight();
if (measuredHeight - textSize > 0) {
mAdditionalPadding = (int) (measuredHeight - textSize);
Log.v("NoPaddingTextView", "onMeasure: height=" + measuredHeight + " textSize=" + textSize + " mAdditionalPadding=" + mAdditionalPadding);
}
return mAdditionalPadding;
}
}
<RelativeLayout
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<TextView
Android:id="@+id/textView"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_alignBaseline="@+id/baselineImage"
Android:includeFontPadding="false" />
<ImageView
Android:id="@+id/baselineImage"
Android:layout_width="1dp"
Android:layout_height="1dp"
Android:baselineAlignBottom="true"
Android:layout_alignParentBottom="true" />
<!-- This view will be exactly 10dp below the baseline of textView -->
<View
Android:id="@+id/view"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_marginTop="10dp"
Android:layout_below="@+id/baselineImage" />
</RelativeLayout>
追加のImageViewを使用して、TextViewをImageViewのベースラインに合わせて設定し、ImageViewのAndroid:baselineAlignBottom
をtrueに設定すると、ImageViewのベースラインが下になります。他のビューは、TextViewのベースラインと同じImageViewの下部を使用してそれ自体を整列させることができます。
ただし、これは、上部ではなく下部のパディングのみを修正します。
私の要件はfindViewById(getResources().getIdentifier("xxx", "id", "Android"));
からの既存のtextView getをオーバーライドするため、他の答えのonDraw()
を単純に試すことはできません。
しかし、問題を修正するための正しい手順を見つけただけです。レイアウトインスペクターの最終結果は次のとおりです。
私が欲しかったのは単に上部のスペースを削除するだけなので、下部のスペースを削除するために他のフォントを選択する必要はありません。
これを修正する重要なコードは次のとおりです。
Typeface mfont = Typeface.createFromAsset(getResources().getAssets(), "fonts/myCustomFont.otf");
myTextView.setTypeface(mfont);
myTextView.setPadding(0, 0, 0, 0);
myTextView.setIncludeFontPadding(false);
最初のキーはカスタムフォント「fonts/myCustomFont.otf」に設定されます。このフォントは下部にスペースがあり、上部にはスペースがありません。otfファイルを開いてAndroid Studioで任意のフォントをクリックすると、
ご覧のとおり、下部のカーソルには余分なスペースがありますが、上部にはありませんので、問題を修正しました。
2番目のキーはです。コードを単純にスキップすることはできません。そうしないと機能しない可能性があります。これが、答えが機能しているとコメントする人もいれば、機能していないとコメントする人もいる理由です。
それらの1つを削除するとどうなるかを説明しましょう。
setTypeface(mfont);
なし:
setPadding(0, 0, 0, 0);
なし:
setIncludeFontPadding(false);
なし:
それらの3つ(すなわち、元の)なし:
この問題は次の方法で解決できると思います。
<TextView
Android:id="@+id/leftText"
Android:includeFontPadding="false"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:textSize="30dp"
Android:text="Hello World!\nhello world" />
<TextView
Android:id="@+id/rightUpperText"
Android:includeFontPadding="false"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@+id/leftText"
Android:layout_alignTop="@+id/leftText"
Android:textSize="30dp"
Android:text="Hello World!" />
<TextView
Android:id="@+id/rightLowerText"
Android:includeFontPadding="false"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:layout_toRightOf="@+id/leftText"
Android:layout_below="@+id/rightUpperText"
Android:textSize="30dp"
Android:text="hello world" />
結果は次のとおりです。
RightLowerTextの特殊文字の行は、leftTextの2行目より少し高く見えますが、それらのベースラインは揃えられたままです。
簡単な方法が働いた:
setSingleLine();
setIncludeFontPadding(false);
うまくいかない場合は、そのコードの上にこれを追加してみてください:
setLineSpacing(0f,0f);
// and set padding and margin to 0
複数行が必要な場合は、一時的な単一行TextView(パディングを削除する前後)でパディングの上下の高さを正確に計算する必要があります。笑
働いたのは
Android:lineSpacingExtra="-8dp"
左のテキストビューの下部を2番目の右のテキストビューの下部に揃えてみてください。
AppCompatTextView
(またはAPI 27
以降)を使用する場合、これら2つの属性の組み合わせを使用して、最初の行の間隔を削除できます。
XML
Android:firstBaselineToTopHeight="0dp"
Android:includeFontPadding="false"
Kotlin
text.firstBaselineToTopHeight = 0
text.includeFontPadding = false
単に使用する
Android:padding="0dp"
私の知る限り、これはほとんどのウィジェットに固有のものであり、「パディング」の量は電話メーカーによって異なります。このパディングは、画像の境界と9パッチ画像ファイルの画像との間の実際の空白です。
たとえば、私のDroid Xでは、スピナーウィジェットはボタンよりも余分な空白を取得するため、ボタンとインラインのスピナーを持っていると不自然に見えますが、私の妻の携帯電話でも同じアプリケーションには同じ問題がなく、見栄えがよくなります!
私が持っている唯一の提案は、独自の9つのパッチファイルを作成し、それらをアプリケーションで使用することです。
ああ、Androidの痛み。
編集:パディングと空白を明確にしました。