Ответ 1
Попробуйте использовать отрицательные поля. Это может немного поиграть с цифрами, чтобы все было правильно, но я сделал это раньше, и все получилось хорошо.
android:layout_marginTop="-5dp"
У меня есть вертикальный LinearLayout
с двумя TextView
внутри него. Первый содержит свойство статического текста (текст никогда не изменяется), а последний содержит регрессивный таймер. На изображении ниже показаны оба элемента:
Я хочу исключить пустое пространство, в котором оба текста имеют верх и низ. Я пробовал несколько подходов...
android:includeFontPadding="false"
android:lineSpacingMultiplier="1"
android:lineSpacingExtra="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
... но ни одно из них не удалило пространство над текстом. Как я могу сделать оба текста близко друг к другу без лишнего пространства?
PS: Я нашел этот похожий вопрос, но никто не ответил на него.
Полный код макета:
<LinearLayout
android:id="@+id/boxTime"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="20dp" >
<TextView
android:id="@+id/textRemainingTime2"
android:layout_width="wrap_content"
android:layout_heigh="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:textSize="70sp"
android:includeFontPadding="false"
android:lineSpacingMultiplier="1"
android:lineSpacingExtra="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:text="@string/title" />
<TextView
android:id="@+id/textRemainingTime"
android:layout_width="wrap_content"
android:layout_heigh="wrap_content"
android:layout_gravity="center"
android:gravity="center_horizontal"
android:includeFontPadding="false"
android:lineSpacingMultiplier="1"
android:lineSpacingExtra="0dp"
android:paddingTop="0dp"
android:paddingBottom="0dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:textSize="107sp"
android:text="@string/timer" />
</LinearLayout>
Попробуйте использовать отрицательные поля. Это может немного поиграть с цифрами, чтобы все было правильно, но я сделал это раньше, и все получилось хорошо.
android:layout_marginTop="-5dp"
Сделать исходный текст текста равным нижней части TextView.
public class BaselineTextView extends TextView {
public BaselineTextView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onDraw(Canvas canvas) {
int yOffset = getHeight() - getBaseline();
canvas.translate(0, yOffset);
super.onDraw(canvas);
}
}
По умолчанию, TextView включает в себя некоторые дополнения, чтобы оставить место для символов акцента. Вы можете отключить это:
android:includeFontPadding="false"
или
textView.setIncludeFontPadding(false)
отрицательные поля сделают трюк
Если вы установите includeFontPadding на false, это поможет.
android:includeFontPadding="false"
но если вы знаете, что у вас нет каких-либо descenders, потому что вы установили
android:textAllCaps="true"
или вы знаете, что нет символов, которые имеют descender, вы можете создать собственный TextView и установить высоту базовой линии.
public class ExTextView extends TextView {
public ExTextView(Context context) {
this(context, null);
}
public ExTextView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public ExTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ExTextView(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onDraw(Canvas canvas) {
setHeight(getBaseline()); // <--- Shrink size to baseline
super.onDraw(canvas);
}
}
Исходный код включен в мое тестовое приложение UiComponents. https://github.com/landenlabs/UiComponents
Отрицательные поля будут работать. Вы можете установить его двумя способами -
1) через xml - установите поле android:Layout_marginTop="-10dp"
отрицательным
2) с помощью java (Programmatically) - установите для поля topMargin
LayoutParams значение отрицательное.
вы должны изменить высоту TextView и, возможно, изменить андроид: gravity = "bottom"
высота между текстами и размером textView с Wrapcontent.
public class MyTextViewBounder extends TextView {
public MyTextViewBounder(Context context) {
super(context);
}
public MyTextViewBounder(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyTextViewBounder(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//test kích thước thực tế với kích thước của Textview bao quanh text của nó như thế nào
int width, height;
Paint iPaint;
Rect iRect = new Rect();
iPaint = new Paint();
iPaint.setTextSize(13);
iPaint.setTextAlign(Paint.Align.CENTER);
//call below code outsite
//this.setText("Hung");
//this.setTextSize(TypedValue.COMPLEX_UNIT_PX,13);
//this..setIncludeFontPadding(false); //height from 18px down to 15px
iPaint.getTextBounds("Hung",0,4,iRect); //width = 34px, height = 12px
width = this.getWidth(); //= 30px
height = this.getHeight(); //= 18px
width = this.getMeasuredWidth(); //=30px
height = this.getMeasuredHeight(); //= 18px
width = iRect.width(); //34px
height = iRect.height(); //12 px
}
}
Поскольку мое требование переопределяет существующий textView get from findViewById(getResources().getIdentifier("xxx", "id", "android"));
, поэтому я не могу просто попробовать onDraw()
другого ответа.
Но я просто выясню правильные шаги для исправления моей проблемы, вот окончательный результат от Layout Inspector:
Так как я хотел просто удалить верхние пространства, поэтому мне не нужно выбирать другой шрифт для удаления нижних пространств.
Вот критический код для его исправления:
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:
Как вы можете видеть, курсор внизу имеет дополнительный интервал, но не сверху, поэтому он исправил мою проблему.
Второй ключ , вы не можете просто пропустить любой код, иначе он может не работать. Это причина, по которой вы можете обнаружить, что некоторые люди отмечают, что ответ работает, а некоторые другие люди отмечают, что он не работает.
Покажем, что произойдет, если я удалю один из них.
Без setTypeface(mfont);
:
Без setPadding(0, 0, 0, 0);
:
Без setIncludeFontPadding(false);
:
Без 3 из них (т.е. оригинала):