sp단위로 인한 참사
public class CustomTextView extends TextView implements OnClickListener,
OnFocusChangeListener {
public CustomTextView(Context context) {
super(context);
init(context);
}
public CustomTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(context);
}
public CustomTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
setTextSize(context.getResources().getDimension(R.dimen.dimen_30sp));
setOnClickListener(this);
setOnFocusChangeListener(this);
}
@Override
public void onClick(View v) {
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
}
}
컨트롤을 정의할 때 컨트롤의 텍스트 크기를 30sp로 정의합니다. 어울리기 위해 30sp는dimens에서 시작합니다.xml 파일에서 가져옵니다.당시 이 컨트롤을 썼을 때 화면 해상도는 320x480, 밀도는 160dpi, 30sp=30dp=30px였는데 나중에 480x640의 해상도에 맞게 240의 화면이 필요했다. 이때 30sp=30dp=45px였다.
그러나 결과는 예상을 크게 벗어났다. 240dpi의 화면에서 이 컨트롤러의 글씨체는 45px가 아니라 67.5px로 우리의 요구에 부합되지 않았다.그 중 한 동료가 오랫동안 괴로워하며 나에게 가르침을 청했다. 그래서 나는 setTextSize 함수가 무슨 짓을 했는지 의심했다. 그래서 원본 코드를 보고 문득 깨달았다.
/**
* Set the default text size to the given value, interpreted as "scaled
* pixel" units. This size is adjusted based on the current density and
* user font size preference.
*
* @param size The scaled pixel size.
*
* @attr ref android.R.styleable#TextView_textSize
*/
@android.view.RemotableViewMethod
public void setTextSize(float size) {
setTextSize(TypedValue.COMPLEX_UNIT_SP, size);
}
/**
* Set the default text size to a given unit and value. See {@link
* TypedValue} for the possible dimension units.
*
* @param unit The desired dimension unit.
* @param size The desired size in the given units.
*
* @attr ref android.R.styleable#TextView_textSize
*/
public void setTextSize(int unit, float size) {
Context c = getContext();
Resources r;
if (c == null)
r = Resources.getSystem();
else
r = c.getResources();
setRawTextSize(TypedValue.applyDimension(
unit, size, r.getDisplayMetrics()));
}
ApplyDimension 함수를 살펴보겠습니다.
public static float applyDimension(int unit, float value,
DisplayMetrics metrics)
{
switch (unit) {
case COMPLEX_UNIT_PX:
return value;
case COMPLEX_UNIT_DIP:
return value * metrics.density;
case COMPLEX_UNIT_SP:
return value * metrics.scaledDensity;
case COMPLEX_UNIT_PT:
return value * metrics.xdpi * (1.0f/72);
case COMPLEX_UNIT_IN:
return value * metrics.xdpi;
case COMPLEX_UNIT_MM:
return value * metrics.xdpi * (1.0f/25.4f);
}
return 0;
}
원래 setTextSize 함수에 대응하는 단위 자체가 sp였다.240밀도에서 30sp=45px, setTextSize 함수 내부에 scaleDensity를 곱해야 한다면 setTextSize(30sp)의 실제 설정 크기는 30spx1sp=45x1이다.5=67.5px.
따라서 사용자 정의 컨트롤을 할 때 컨트롤의 텍스트 크기를 설정할 때 조심해야 한다. 그렇지 않으면 반나절을 해도 문제의 문제점을 찾을 수 없다.
따라서 가장 좋은 방법은 setTextSize(TypedValue.COMPLEX UNIT PX,getResources()를 사용하는 것이다.getDimension(R.dimen.dimen_30sp));
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.