package com.mingle.myapplication;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.Log;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
public class ScalableLayout extends FrameLayout {
private static final float Default_Scale_Base_Width = 100f;
private static final float Default_Scale_Base_Height = 100f;
private static final float Default_Scale_Left = 0f;
private static final float Default_Scale_Top = 0f;
private static final float Default_Scale_Width = 100f;
private static final float Default_Scale_Height = 100f;
private static final float Default_Scale_TextSize = 100f;
private float mScale_Root_Width = Default_Scale_Base_Width;
private float mScale_Root_Height = Default_Scale_Base_Height;
private float mRatioOfWidthHeight = mScale_Root_Height / mScale_Root_Width;
public float getScaleWidth() { return mScale_Root_Width; }
public float getScaleHeight() { return mScale_Root_Height; }
public void setScaleWidth(float pWidth) { setScaleSize(pWidth, mScale_Root_Height); }
public void setScaleHeight(float pHeight) { setScaleSize(mScale_Root_Width, pHeight); }
public void setScaleSize(float pWidth, float pHeight) {
setScaleSize(pWidth, pHeight, true);
}
private void setScaleSize(float pWidth, float pHeight, boolean pWithInvalidate) {
mScale_Root_Width = pWidth;
mScale_Root_Height = pHeight;
mRatioOfWidthHeight = mScale_Root_Height / mScale_Root_Width;
if(pWithInvalidate) {
postDelayedRequestLayout();
}
}
private long mLastRequestPostTime = 0;
private void postDelayedRequestLayout() {
long now = System.currentTimeMillis();
if(mLastRequestPostTime < now - 50 || now < mLastRequestPostTime) {
mLastRequestPostTime = now;
// log("==== postDelayedRequestLayout Start");
// log(getStackTrace(Thread.currentThread().getStackTrace()));
// log("==== postDelayedRequestLayout End");
postDelayed(new Runnable() {
@Override
public void run() {
requestLayout();
forceLayout();
}
}, 10);
}
}
/**
* Simple constructor to use when creating a view from code.
* Scale_Width, Scale_Height uses a default value of 100.
* <p>
* code에서 ScalableLayout을 생성할 때 사용하는 constructor.
* Scale_Width, Scale_Height를 기본값인 100으로 세팅함.
*
* @param pContext
*/
public ScalableLayout(Context pContext) {
this(pContext, Default_Scale_Base_Width, Default_Scale_Base_Height);
}
/**
* Constructor that is called when inflating a view from XML.
* <p>
* XML에서 ScalableLayout을 생성할 때 사용하는 constructor.
*
* @param pContext
* @param pAttrs
*/
public ScalableLayout(Context pContext, AttributeSet pAttrs) {
this(pContext, pAttrs,
pContext.obtainStyledAttributes(pAttrs, R.styleable.ScalableLayout).getFloat(R.styleable.ScalableLayout_scale_base_width, Default_Scale_Base_Width),
pContext.obtainStyledAttributes(pAttrs, R.styleable.ScalableLayout).getFloat(R.styleable.ScalableLayout_scale_base_height, Default_Scale_Base_Height)
);
}
/**
* Simple constructor to use when creating a view from code.
* <p>
* code에서 ScalableLayout을 생성할 때 사용하는 constructor.
*
* @param pContext
* @param pScale_Width Scale width of ScalableLayout.
* @param pScale_Height Scale height of ScalableLayout.
*/
public ScalableLayout(Context pContext, float pScale_Width, float pScale_Height) {
this(pContext, null, pScale_Width, pScale_Height);
}
private ScalableLayout(Context pContext, AttributeSet pAttrs, float pScale_Width, float pScale_Height) {
super(pContext, pAttrs);
setScaleSize(pScale_Width, pScale_Height, true);
}
/**
* @param pChild
* @return Scalable.LayoutParams of pChild
*/
public LayoutParams getChildLayoutParams(View pChild) {
ViewGroup.LayoutParams lp = pChild.getLayoutParams();
if(lp == null) {
lp = generateDefaultLayoutParams();
pChild.setLayoutParams(lp);
}
if(lp instanceof LayoutParams == false) {
throw new IllegalArgumentException("pChild has not ScalableLayout.LayoutParams "+pChild.getLayoutParams());
}
return (LayoutParams) pChild.getLayoutParams();
}
/**
* sets TextSize of TextView and EdiText to scale automatically
* @param pTextView
* @param pScale_TextSize
*/
public void setScale_TextSize(TextView pTextView, float pScale_TextSize) {
getChildLayoutParams(pTextView).setScale_TextSize(pScale_TextSize);
}
/**
* @param pTextView target textview to wrap content
* @param pDirection
* @param pRescaleSurrounded
*/
public void setTextView_WrapContent(TextView pTextView, TextView_WrapContent_Direction pDirection, boolean pRescaleSurrounded) {
setTextView_WrapContent(pTextView, pDirection, pRescaleSurrounded, true);
}
public void setTextView_WrapContent(TextView pTextView, TextView_WrapContent_Direction pDirection, boolean pRescaleSurrounded, boolean pMoveSibligs) {
getChildLayoutParams(pTextView).setTextView_WrapContent(pDirection, pRescaleSurrounded, pMoveSibligs);
refreshTextChangedListener(pTextView);
}
private TextWatcher mTextWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence pS, int pStart, int pBefore, int pCount) {
postDelayedRequestLayout();
}
@Override
public void beforeTextChanged(CharSequence pS, int pStart, int pCount, int pAfter) { }
@Override
public void afterTextChanged(Editable pS) {
postDelayedRequestLayout();
}
};
private void refreshTextChangedListener(TextView pTextView) {
LayoutParams lSLLP = getChildLayoutParams(pTextView);
try {
pTextView.removeTextChangedListener(mTextWatcher);
} catch (Throwable e) {
}
if(lSLLP.mTextView_WrapContent_Direction != TextView_WrapContent_Direction.None) {
pTextView.addTextChangedListener(mTextWatcher);
}
}
@Override
public void addView(View pChild) { addView(pChild, getChildCount()); }
@Override
public void addView(View pChild, int pIndex) { addView(pChild, pIndex, generateDefaultLayoutParams()); }
@Override
public void addView(View pChild, int pWidth, int pHeight) { addView(pChild, new ViewGroup.LayoutParams(pWidth, pHeight)); }
@Override
public void addView(View pChild, ViewGroup.LayoutParams pParams) { addView(pChild, getChildCount(), pParams); }
@Override
public void addView(View pChild, int pIndex, ViewGroup.LayoutParams pParams) {
if(pParams instanceof LayoutParams) {
addView_Final(pChild, pIndex, (LayoutParams) pParams);
} else {
addView_Final(pChild, pIndex, generateLayoutParams(pParams));
}
}
public void addView(View pChild, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
addView_Final(pChild, getChildCount(), new LayoutParams(pScale_Left, pScale_Top, pScale_Width, pScale_Height));
}
private final void addView_Final(View pChild, int pIndex, LayoutParams pScaledLayoutParams) {
super.addView(pChild, pIndex, pScaledLayoutParams);
}
@Override
protected LayoutParams generateDefaultLayoutParams() {
return new LayoutParams(0f, 0f, getScaleWidth(), getScaleHeight());
}
@Override
public LayoutParams generateLayoutParams(AttributeSet pAttrs) {
TypedArray attrs = getContext().obtainStyledAttributes(pAttrs, R.styleable.ScalableLayout);
TextView_WrapContent_Direction dir = TextView_WrapContent_Direction.None;
String dirstr = attrs.getString(R.styleable.ScalableLayout_textview_wrapcontent_direction);
if(dirstr != null) {
for(TextView_WrapContent_Direction d : TextView_WrapContent_Direction.values()) {
if(dirstr.toLowerCase().compareTo(d.name().toLowerCase()) == 0) {
dir = d;
break;
}
}
}
return new LayoutParams(
attrs.getFloat(R.styleable.ScalableLayout_scale_left, Default_Scale_Left),
attrs.getFloat(R.styleable.ScalableLayout_scale_top, Default_Scale_Top),
attrs.getFloat(R.styleable.ScalableLayout_scale_width, Default_Scale_Width),
attrs.getFloat(R.styleable.ScalableLayout_scale_height, Default_Scale_Height),
attrs.getFloat(R.styleable.ScalableLayout_scale_textsize, Default_Scale_TextSize),
dir,
attrs.getBoolean(R.styleable.ScalableLayout_textview_wrapcontent_resizesurrounded, false),
attrs.getBoolean(R.styleable.ScalableLayout_textview_wrapcontent_movesiblings, true)
);
}
@Override
protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams pP) {
if(pP instanceof LayoutParams) {
return (LayoutParams) pP;
}
return new LayoutParams(pP);
}
/**
* move childView inside ScalableLayout
* @param pChildView view to move. should be child of ScaleLayout
* @param pScale_Left
* @param pScale_Top
*/
public void moveChildView(View pChildView, float pScale_Left, float pScale_Top) {
LayoutParams lSLLP = getChildLayoutParams(pChildView);
// log("moveChildView 1 lSLLP:"+lSLLP+" pChildView:"+pChildView);
lSLLP.mScale_Left = pScale_Left;
lSLLP.mScale_Top = pScale_Top;
// log("moveChildView 2 lSLLP:"+lSLLP+" pChildView:"+pChildView);
// log("moveChildView "+getStackTrace(Thread.currentThread().getStackTrace()));
postInvalidate();
}
/**
* move and resize childView inside ScalableLayout
* @param pChildView view to move. should be child of ScaleLayout
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
*/
public void moveChildView(View pChildView, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
LayoutParams lSLLP = getChildLayoutParams(pChildView);
lSLLP.mScale_Left = pScale_Left;
lSLLP.mScale_Top = pScale_Top;
lSLLP.mScale_Width = pScale_Width;
lSLLP.mScale_Height = pScale_Height;
postInvalidate();
}
@Override
protected void onMeasure(int pWidthMeasureSpec, int pHeightMeasureSpec) {
// log("onMeasure ================ Start "+this.toString());
// float lRoot_Width = 0;
float lRoot_Width_Max = 0;
int lRoot_MeasureSpec_WidthMode = MeasureSpec.getMode(pWidthMeasureSpec);
// float lRoot_Height = 0;
float lRoot_Height_Max = 0;
int lRoot_MeasureSpec_HeightMode = MeasureSpec.getMode(pHeightMeasureSpec);
// get condition of ScalableLayout
// ScalableLayout이 지켜야 되는 조건들을 확인함
{
int lRoot_MeasureSpec_Width = MeasureSpec.getSize(pWidthMeasureSpec);
int lRoot_MeasureSpec_Height = MeasureSpec.getSize(pHeightMeasureSpec);
switch (lRoot_MeasureSpec_WidthMode) {
case MeasureSpec.EXACTLY:
// log(" onMeasure Width Exactly "+lRoot_Width+" = min("+mScale_Root_Width+", "+lRoot_MeasureSpec_Width+")");
lRoot_Width_Max = lRoot_MeasureSpec_Width;
// log(" onMeasure Width Exactly = "+lRoot_Width_Max);
// lRoot_Width = lRoot_MeasureSpec_Width;
break;
case MeasureSpec.AT_MOST:
if(lRoot_MeasureSpec_HeightMode == MeasureSpec.EXACTLY) {
// lRoot_Width_Max = lRoot_MeasureSpec_Width;
lRoot_Width_Max = Float.MAX_VALUE;
} else {
lRoot_Width_Max = lRoot_MeasureSpec_Width;
}
// lRoot_Width = lRoot_MeasureSpec_Width;
// log(" onMeasure Width AtMost = "+lRoot_Width_Max);
break;
default:
// log(" onMeasure Width Unspecified "+lRoot_Width_Max+" = "+mScale_Root_Width);
// lRoot_Width = mScale_Root_Width;
// lRoot_Width_Max = Float.MAX_VALUE;
// lRoot_Width = lRoot_WidthSize;
// lRoot_Width_Max = lRoot_WidthSize;
// break;
// throw new IllegalArgumentException(String.format(" onMeasure Width Unspecified %08X", lRoot_MeasureSpec_Width));
lRoot_Width_Max = Float.MAX_VALUE;
// throw new IllegalArgumentException(String.format(" onMeasure Width Unspecified %08X lRoot_MeasureSpec_WidthMode:%d lRoot_MeasureSpec_Width:%d",
// lRoot_MeasureSpec_Width, lRoot_MeasureSpec_WidthMode, lRoot_MeasureSpec_Width));
}
switch (lRoot_MeasureSpec_HeightMode) {
case MeasureSpec.EXACTLY:
lRoot_Height_Max = lRoot_MeasureSpec_Height;
// log(" onMeasure Height Exactly = "+lRoot_Height_Max);
break;
case MeasureSpec.AT_MOST:
if(lRoot_MeasureSpec_WidthMode == MeasureSpec.EXACTLY) {
// lRoot_Height_Max = lRoot_MeasureSpec_Height;
lRoot_Height_Max = Float.MAX_VALUE;
} else {
lRoot_Height_Max = lRoot_MeasureSpec_Height;
}
// log(" onMeasure Height AtMost = "+lRoot_Height_Max);
break;
default:
// lRoot_Height = lRoot_Width * mRatioOfWidthHeight;
//// log(" onMeasure Height Unspecified "+lRootHeight+" = "+lRootWidth+"*"+mRatioOfWidthHeight);
// break;
lRoot_Height_Max = Float.MAX_VALUE;
// throw new IllegalArgumentException(String.format(" onMeasure Height Unspecified %08X lRoot_MeasureSpec_HeightMode:%d lRoot_MeasureSpec_Height:%d",
// lRoot_MeasureSpec_Height, lRoot_MeasureSpec_HeightMode, lRoot_MeasureSpec_Height));
}
}
// log(String.format("onMeasure 1 lScale:%5.3f ChildCount:%d Root:(%5.3f, %5.3f)", (lRootWidth/mScale_Full_Width), getChildCount(), lRootWidth, lRootHeight));
// log(String.format("onMeasure 1 lScale:%5.3f ChildCount:%d", (lRootWidth/mScale_Full_Width), getChildCount()));
float lRoot_Width = 0;
float lRoot_Height = 0;
for(int tryi = 0 ; tryi < 3 ; tryi++) {
float lScale_Ratio_Pre = Math.min(lRoot_Width_Max / mScale_Root_Width, lRoot_Height_Max / mScale_Root_Height);
// log(String.format("onMeasure 1 lScale_Ratio:%5.3f Scale_Ratio:(%5.3f, %5.3f) Scale:(%5.3f, %5.3f)",
// lScale_Ratio_Pre, (lRoot_Width_Max/mScale_Root_Width), (lRoot_Height_Max / mScale_Root_Height), mScale_Root_Width, mScale_Root_Height));
//////////////////////// Text Measure
// TODO english
// ScalableLayout내의 TextView중에 TextView_WrapContent_Direction 세팅되어 있을 경우 ScalableLayout의 Scale Size와 이웃한 View들의 Scalable LayoutParams를 재계산
for (int i=0;i<getChildCount();i++) {
View lView = getChildAt(i);
if(lView instanceof TextView) {
updateTextViewSize((TextView)lView, lScale_Ratio_Pre);
}
}
// calculate final size of ScalableLayout
// ScalableLayout의 최종적인 크기를 결정지음
float lScale_Ratio_Post = Math.min(lRoot_Width_Max / mScale_Root_Width, lRoot_Height_Max / mScale_Root_Height);
{
lRoot_Width = mScale_Root_Width * lScale_Ratio_Post;
lRoot_Height = mScale_Root_Height * lScale_Ratio_Post;
}
{
// 최종적으로 배치 위치를 세팅하기 위해 각 자식 뷰들의 layoutparams를 업데이트함
// update layoutparams of each child view to arrange finally
float lTopMarginFromWeight = (lRoot_Height - (lRoot_Width * mRatioOfWidthHeight))/4;
// log(" onMeasure ("+lRoot_Width+","+lRoot_Height+") Ratio:"+mRatioOfWidthHeight+" lScale_TextViewMeasure_Post:"+lScale_Ratio_Post+" lTopMarginFromWeight:"+lTopMarginFromWeight);
for (int i=0;i<getChildCount();i++) {
View lView = getChildAt(i);
LayoutParams lParams = getChildLayoutParams(lView);
// log(" onMeasure lSLLP:"+lParams+"\n");
boolean dif = false;
// log(" onMeasure bef v:"+lView+" pos:("+lParams.leftMargin+","+lParams.topMargin+") size:("+lParams.width+","+lParams.height+") dif:"+dif);
int lParams_Left = Math.round(lScale_Ratio_Post * lParams.mScale_Left);
// log(" onMeasure Left: "+lParams.leftMargin+" "+lParams_Left+" "+lScale_Ratio_Post+" "+lParams.mScale_Left);
if(lParams.leftMargin != lParams_Left)
dif = true;
lParams.leftMargin = lParams_Left;
int lParams_Top = Math.round(lScale_Ratio_Post * lParams.mScale_Top + lTopMarginFromWeight);
if(lParams.topMargin != lParams_Top)
dif = true;
lParams.topMargin = lParams_Top;
int lParams_Width = Math.round(lScale_Ratio_Post * (lParams.mScale_Left + lParams.mScale_Width)) - lParams.leftMargin;
if(lParams.width != lParams_Width)
dif = true;
lParams.width = lParams_Width;
int lParams_Height = Math.round(lScale_Ratio_Post * (lParams.mScale_Top + lParams.mScale_Height)) - lParams.topMargin;
if(lParams.height != lParams_Height)
dif = true;
lParams.height = lParams_Height;
// log(" onMeasure aft v:"+lView+" pos:("+lParams.leftMargin+","+lParams.topMargin+") size:("+lParams.width+","+lParams.height+") dif:"+dif);
// if(lParams.mScale_TextSize != -1 && lParams.mTextView_WrapContent_Direction == TextView_WrapContent_Direction.None) {
if(lParams.mScale_TextSize != -1) {
if(lView instanceof TextView) {
TextView v = (TextView) lView;
// if(v.getTextSize() != lParams.mScale_TextSize * lScale_Ratio_Post) {
if(isDifferentSufficiently(lParams.mScale_TextSize * lScale_Ratio_Post, v.getTextSize())) {
v.setTextSize(TypedValue.COMPLEX_UNIT_PX, lParams.mScale_TextSize * lScale_Ratio_Post);
}
}
}
if(dif) {
lView.setLayoutParams(lParams);
}
}
}
// log(String.format("onMeasure end lScale_Ratio:%5.3f->%5.3f Root:(%5.3f,%5.3f) Scale_Root:(%5.3f,%5.3f) ",
// lScale_Ratio_Pre, lScale_Ratio_Post,
// lRoot_Width, lRoot_Height,
// mScale_Root_Width, mScale_Root_Height));
if(isDifferentSufficiently(lScale_Ratio_Post, lScale_Ratio_Pre, 1.01f) == false) {
break;
}
}
// log("onMeasure ================ End "+this.toString());
super.onMeasure(MeasureSpec.makeMeasureSpec(Math.round(lRoot_Width), lRoot_MeasureSpec_WidthMode), MeasureSpec.makeMeasureSpec(Math.round(lRoot_Height), lRoot_MeasureSpec_HeightMode));
setMeasuredDimension(Math.round(lRoot_Width), Math.round(lRoot_Height));
}
private boolean isDifferentSufficiently(float pNew, float pOld) {
return isDifferentSufficiently(pNew, pOld, 1.1f);
}
private boolean isDifferentSufficiently(float pNew, float pOld, float pDiffDelta) {
if( pNew < pOld / pDiffDelta || pOld * pDiffDelta < pNew ) {
return true;
}
return false;
}
private enum ViewPosition {
Top,
Bottom,
Left,
Right,
Surrounded,
Nothing
}
private ViewPosition getViewPosition(LayoutParams pSrc, LayoutParams pDst) {
// 위에 있는 경우
if(pSrc.getScale_Top() >= pDst.getScale_Bottom() &&
(
( pSrc.getScale_Left() <= pDst.getScale_Left() && pDst.getScale_Left() <= pSrc.getScale_Right())
||
( pSrc.getScale_Left() <= pDst.getScale_Right() && pDst.getScale_Right() <= pSrc.getScale_Right())
||
( pDst.getScale_Left() <= pSrc.getScale_Left() && pSrc.getScale_Right() <= pDst.getScale_Right())
)) {
return ViewPosition.Top;
}
// 아래에 있는 경우
else if(pSrc.getScale_Bottom() <= pDst.getScale_Top() &&
(
( pSrc.getScale_Left() <= pDst.getScale_Left() && pDst.getScale_Left() <= pSrc.getScale_Right())
||
( pSrc.getScale_Left() <= pDst.getScale_Right() && pDst.getScale_Right() <= pSrc.getScale_Right())
||
( pDst.getScale_Left() <= pSrc.getScale_Left() && pSrc.getScale_Right() <= pDst.getScale_Right())
)) {
return ViewPosition.Bottom;
}
// 왼쪽에 있는 경우
else if(pSrc.getScale_Left() >= pDst.getScale_Right() &&
(
( pSrc.getScale_Top() <= pDst.getScale_Top() && pDst.getScale_Top() <= pSrc.getScale_Bottom())
||
( pSrc.getScale_Top() <= pDst.getScale_Bottom() && pDst.getScale_Bottom() <= pSrc.getScale_Bottom())
||
( pSrc.getScale_Top() >= pDst.getScale_Top() && pDst.getScale_Bottom() >= pSrc.getScale_Bottom())
)) {
return ViewPosition.Left;
}
// 오른쪽에 있는 경우
else if(pSrc.getScale_Right() <= pDst.getScale_Left() &&
(
( pSrc.getScale_Top() <= pDst.getScale_Top() && pDst.getScale_Top() <= pSrc.getScale_Bottom())
||
( pSrc.getScale_Top() <= pDst.getScale_Bottom() && pDst.getScale_Bottom() <= pSrc.getScale_Bottom())
||
( pSrc.getScale_Top() >= pDst.getScale_Top() && pDst.getScale_Bottom() >= pSrc.getScale_Bottom())
)) {
return ViewPosition.Right;
}
// 감싸고 있는 경우
else if(pDst.getScale_Top() <= pSrc.getScale_Top() &&
pDst.getScale_Left() <= pSrc.getScale_Left() &&
pDst.getScale_Right() >= pSrc.getScale_Right() &&
pDst.getScale_Bottom() >= pSrc.getScale_Bottom()) {
return ViewPosition.Surrounded;
}
return ViewPosition.Nothing;
}
private void updateTextViewSize(TextView pTV_Text, float pScale_TextViewMeasure_Pre) {
refreshTextChangedListener(pTV_Text);
LayoutParams lTV_SLLP = getChildLayoutParams(pTV_Text);
TextView_WrapContent_Direction lTextView_WrapContent_Direction = lTV_SLLP.mTextView_WrapContent_Direction;
if(lTextView_WrapContent_Direction == TextView_WrapContent_Direction.None) {
return;
}
float lTextView_ScaleWidth_Old = lTV_SLLP.getScale_Width();
float lTextView_ScaleHeight_Old = lTV_SLLP.getScale_Height();
float lTextView_ScaleWidth_New = lTextView_ScaleWidth_Old;
float lTextView_ScaleHeight_New = lTextView_ScaleHeight_Old;
{
// get new scale size
// 새로운 Scale 크기를 가져옴
float lTextSize_New = lTV_SLLP.mScale_TextSize * pScale_TextViewMeasure_Pre;
// log("updateTextViewHeight 1.1 lTextView_ScaleHeight_Old:"+lTextView_ScaleHeight_Old+" getScaleHeight():"+getScaleHeight()+" pScale_TextViewMeasure_Pre:"+pScale_TextViewMeasure_Pre);
// log("updateTextViewHeight 1.2 lTextSize_New:"+lTextSize_New+" pTV_Text.getTextSize():"+pTV_Text.getTextSize());
if(isDifferentSufficiently(lTextSize_New, pTV_Text.getTextSize())) {
// log("updateTextViewHeight 1.2.1 TextSize:"+pTV_Text.getTextSize()+"->"+lTextSize_New);
pTV_Text.setTextSize(TypedValue.COMPLEX_UNIT_PX, lTextSize_New);
}
switch (lTextView_WrapContent_Direction) {
case Top:
case Bottom:
case Center_Vertical:
{
int widthMeasureSpec = MeasureSpec.makeMeasureSpec((int) (lTextView_ScaleWidth_Old * pScale_TextViewMeasure_Pre), MeasureSpec.EXACTLY);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
pTV_Text.measure(widthMeasureSpec, heightMeasureSpec);
float lTextView_Height_New = pTV_Text.getMeasuredHeight() * 1.01f;
lTextView_ScaleHeight_New = lTextView_Height_New / pScale_TextViewMeasure_Pre;
} break;
case Left:
case Right:
case Center_Horizontal:
{
int widthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
int heightMeasureSpec = MeasureSpec.makeMeasureSpec((int) (lTextView_ScaleHeight_Old * pScale_TextViewMeasure_Pre), MeasureSpec.EXACTLY);
pTV_Text.measure(widthMeasureSpec, heightMeasureSpec);
float lTextView_Width_New = pTV_Text.getMeasuredWidth() * 1.01f;
lTextView_ScaleWidth_New = lTextView_Width_New / pScale_TextViewMeasure_Pre;
// log("updateTextViewWidth 1.3 lTextView_NewWidth:"+lTextView_Width_New+" lTextView_ScaleWidth_New:"+lTextView_ScaleWidth_New);
} break;
default:
break;
}
}
// log("updateTextViewWidth 1.4 " +
// " lTextView_ScaleWidth_New:"+lTextView_ScaleWidth_New+" lTextView_ScaleWidth_Old:"+lTextView_ScaleWidth_Old+
// " lTextView_ScaleHeight_New:"+lTextView_ScaleHeight_New+" lTextView_ScaleHeight_Old:"+lTextView_ScaleHeight_Old);
if(
isDifferentSufficiently(lTextView_ScaleWidth_New, lTextView_ScaleWidth_Old) == false &&
isDifferentSufficiently(lTextView_ScaleHeight_New, lTextView_ScaleHeight_Old) == false) {
return;
}
float lTextView_ScaleWidth_Diff = lTextView_ScaleWidth_New - lTextView_ScaleWidth_Old;
float lTextView_ScaleHeight_Diff = lTextView_ScaleHeight_New - lTextView_ScaleHeight_Old;
if(lTV_SLLP.mTextView_WrapContent_MoveSiblings == true) {
for(int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if(v == pTV_Text) {
continue;
}
LayoutParams lSLLP = getChildLayoutParams(v);
ViewPosition position = getViewPosition(lTV_SLLP, lSLLP);
switch (lTextView_WrapContent_Direction) {
case Top: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Top: {
} break;
case Surrounded: {
moveChildView(v,
lSLLP.getScale_Left(), lSLLP.getScale_Top(),
lSLLP.getScale_Width(), lSLLP.getScale_Height()+lTextView_ScaleHeight_Diff);
} break;
default: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top()+lTextView_ScaleHeight_Diff);
} break;
}
} else {
switch (position) {
case Top: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top()-lTextView_ScaleHeight_Diff);
} break;
}
}
} break;
case Bottom: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Bottom: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() + lTextView_ScaleHeight_Diff);
} break;
case Surrounded: {
moveChildView(v,
lSLLP.getScale_Left(), lSLLP.getScale_Top(),
lSLLP.getScale_Width(), lSLLP.getScale_Height() + lTextView_ScaleHeight_Diff);
} break;
}
} else {
switch (position) {
case Bottom: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() + lTextView_ScaleHeight_Diff);
} break;
} break;
}
} break;
case Center_Vertical: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Top: {
} break;
case Bottom: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() + lTextView_ScaleHeight_Diff);
} break;
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width(), lSLLP.getScale_Height()+lTextView_ScaleHeight_Diff);
} break;
default: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() + lTextView_ScaleHeight_Diff / 2, lSLLP.getScale_Width(), lSLLP.getScale_Height());
} break;
}
} else {
switch (position) {
case Top: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() - lTextView_ScaleHeight_Diff / 2);
} break;
case Bottom: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() + lTextView_ScaleHeight_Diff / 2);
} break;
}
}
} break;
case Left: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Left: {
} break;
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Height());
} break;
default: {
moveChildView(v, lSLLP.getScale_Left()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Top());
} break;
}
} else {
switch (position) {
case Left: {
moveChildView(v, lSLLP.getScale_Left()-lTextView_ScaleWidth_Diff, lSLLP.getScale_Top());
} break;
}
}
} break;
case Right: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Right: {
moveChildView(v, lSLLP.getScale_Left()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Top());
} break;
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Height());
} break;
}
} else {
switch (position) {
case Right: {
moveChildView(v, lSLLP.getScale_Left()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Top());
} break;
}
}
} break;
case Center_Horizontal: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Left: {
} break;
case Right: {
moveChildView(v, lSLLP.getScale_Left() + lTextView_ScaleWidth_Diff, lSLLP.getScale_Top());
} break;
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width() + lTextView_ScaleWidth_Diff, lSLLP.getScale_Height());
} break;
default: {
moveChildView(v, lSLLP.getScale_Left() + lTextView_ScaleWidth_Diff / 2, lSLLP.getScale_Top(), lSLLP.getScale_Width(), lSLLP.getScale_Height());
} break;
}
} else {
switch (position) {
case Left: {
moveChildView(v, lSLLP.getScale_Left() - lTextView_ScaleWidth_Diff / 2, lSLLP.getScale_Top());
} break;
case Right: {
moveChildView(v, lSLLP.getScale_Left() + lTextView_ScaleWidth_Diff / 2, lSLLP.getScale_Top());
} break;
}
}
} break;
default: {
} break;
}
}
} else {
for(int i = 0; i < getChildCount(); i++) {
View v = getChildAt(i);
if(v == pTV_Text) {
continue;
}
LayoutParams lSLLP = getChildLayoutParams(v);
ViewPosition position = getViewPosition(lTV_SLLP, lSLLP);
switch (lTextView_WrapContent_Direction) {
case Top: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Surrounded: {
moveChildView(v,
lSLLP.getScale_Left(), lSLLP.getScale_Top(),
lSLLP.getScale_Width(), lSLLP.getScale_Height()+lTextView_ScaleHeight_Diff);
} break;
default: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top()+lTextView_ScaleHeight_Diff);
} break;
}
} else {
}
} break;
case Bottom: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Surrounded: {
moveChildView(v,
lSLLP.getScale_Left(), lSLLP.getScale_Top(),
lSLLP.getScale_Width(), lSLLP.getScale_Height() + lTextView_ScaleHeight_Diff);
} break;
}
} else {
}
} break;
case Center_Vertical: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width(), lSLLP.getScale_Height()+lTextView_ScaleHeight_Diff);
} break;
default: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top() + lTextView_ScaleHeight_Diff / 2, lSLLP.getScale_Width(), lSLLP.getScale_Height());
} break;
}
} else {
}
} break;
case Left: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Height());
} break;
default: {
moveChildView(v, lSLLP.getScale_Left()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Top());
} break;
}
} else {
}
} break;
case Right: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width()+lTextView_ScaleWidth_Diff, lSLLP.getScale_Height());
} break;
}
} else {
}
} break;
case Center_Horizontal: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
switch (position) {
case Surrounded: {
moveChildView(v, lSLLP.getScale_Left(), lSLLP.getScale_Top(), lSLLP.getScale_Width() + lTextView_ScaleWidth_Diff, lSLLP.getScale_Height());
} break;
default: {
moveChildView(v, lSLLP.getScale_Left() + lTextView_ScaleWidth_Diff / 2, lSLLP.getScale_Top(), lSLLP.getScale_Width(), lSLLP.getScale_Height());
} break;
}
} else {
}
} break;
default: {
} break;
}
}
}
switch (lTextView_WrapContent_Direction) {
case Top: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top(), lTV_SLLP.getScale_Width(), lTextView_ScaleHeight_New);
} else {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top() - lTextView_ScaleHeight_Diff, lTV_SLLP.getScale_Width(), lTextView_ScaleHeight_New);
}
} break;
case Bottom: {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top(), lTV_SLLP.getScale_Width(), lTextView_ScaleHeight_New);
} break;
case Center_Vertical: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top(), lTV_SLLP.getScale_Width(), lTextView_ScaleHeight_New);
} else {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top() - lTextView_ScaleHeight_Diff / 2, lTV_SLLP.getScale_Width(), lTextView_ScaleHeight_New);
}
} break;
case Left: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top(), lTextView_ScaleWidth_New, lTV_SLLP.getScale_Height());
} else {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left() - lTextView_ScaleWidth_Diff, lTV_SLLP.getScale_Top(), lTextView_ScaleWidth_New, lTV_SLLP.getScale_Height());
}
} break;
case Right: {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top(), lTextView_ScaleWidth_New, lTV_SLLP.getScale_Height());
} break;
case Center_Horizontal: {
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left(), lTV_SLLP.getScale_Top(), lTextView_ScaleWidth_New, lTV_SLLP.getScale_Height());
} else {
moveChildView(pTV_Text, lTV_SLLP.getScale_Left() - lTextView_ScaleWidth_Diff / 2, lTV_SLLP.getScale_Top(), lTextView_ScaleWidth_New, lTV_SLLP.getScale_Height());
}
} break;
default:
break;
}
if(lTV_SLLP.mTextView_WrapContent_ResizeSurrounded) {
// log("setScaleSize From:"+getScaleHeight()+" To:"+(getScaleHeight()+lTextView_ScaleHeight_Diff)+" pScale_TextViewMeasure_Pre:"+pScale_TextViewMeasure_Pre);
setScaleSize(getScaleWidth()+lTextView_ScaleWidth_Diff, getScaleHeight()+lTextView_ScaleHeight_Diff, false);
}
// log("updateTextViewHeight 4 lTextView_ScaleHeight_Old:"+lTextView_ScaleHeight_Old+" getScaleHeight():"+getScaleHeight()+" pScale_TextViewMeasure_Pre:"+pScale_TextViewMeasure_Pre);
// log("updateTextViewHeight ret "+(pRootHeight+"*"+getScaleHeight()+"/"+lRootView_OldScaleHeight));
// log("updateTextViewHeight ret "+(pRootHeight*getScaleHeight()/lRootView_OldScaleHeight));
// return pRootHeight*getScaleHeight()/lRootView_OldScaleHeight;
}
public enum TextView_WrapContent_Direction {
None, Left, Right, Center_Horizontal, Top, Bottom, Center_Vertical,
}
/**
* ScalableLayout.LayoutParams
*/
public static class LayoutParams extends FrameLayout.LayoutParams {
public LayoutParams(Context pContext, AttributeSet pAttrs) { super(pContext, pAttrs); }
public LayoutParams(
float pScale_Left, float pScale_Top,
float pScale_Width, float pScale_Height) {
this(pScale_Left, pScale_Top, pScale_Width, pScale_Height, Default_Scale_TextSize, TextView_WrapContent_Direction.None, false, true);
}
private LayoutParams(
float pScale_Left, float pScale_Top,
float pScale_Width, float pScale_Height, float pScale_TextSize,
TextView_WrapContent_Direction pTextView_WrapContent_Direction, boolean pTextView_WrapContent_ResizeSurrounded, boolean pTextView_WrapContent_MoveSiblings ) {
super(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, Gravity.LEFT | Gravity.TOP);
setScale_Left(pScale_Left);
setScale_Top(pScale_Top);
setScale_Width(pScale_Width);
setScale_Height(pScale_Height);
setScale_TextSize(pScale_TextSize);
setTextView_WrapContent(pTextView_WrapContent_Direction, pTextView_WrapContent_ResizeSurrounded, pTextView_WrapContent_MoveSiblings);
}
private LayoutParams(ViewGroup.LayoutParams pLayoutParams) {
this(
Default_Scale_Left, Default_Scale_Top,
Default_Scale_Width, Default_Scale_Height,
Default_Scale_TextSize, TextView_WrapContent_Direction.None, false, true);
width = pLayoutParams.width;
height = pLayoutParams.height;
layoutAnimationParameters = pLayoutParams.layoutAnimationParameters;
gravity = Gravity.LEFT | Gravity.TOP;
}
@Override
public String toString() {
return String.format("%08x (%6.3f, %6.3f) (%6.3f, %6.3f)", hashCode(), getScale_Left(), getScale_Top(), getScale_Right(), getScale_Bottom());
}
private float mScale_Left = Default_Scale_Left;
public float getScale_Left() { return mScale_Left; }
public void setScale_Left(float pScale_Left) { mScale_Left = pScale_Left; }
public float getScale_Right() { return getScale_Left()+getScale_Width(); }
private float mScale_Top = Default_Scale_Top;
public float getScale_Top() { return mScale_Top; }
public void setScale_Top(float pScale_Top) { mScale_Top = pScale_Top; }
public float getScale_Bottom() { return getScale_Top()+getScale_Height(); }
private float mScale_Width = Default_Scale_Width;
public float getScale_Width() { return mScale_Width; }
public void setScale_Width(float pScale_Width) { mScale_Width = pScale_Width; }
private float mScale_Height = Default_Scale_Height;
public float getScale_Height() { return mScale_Height; }
public void setScale_Height(float pScale_Height) { mScale_Height = pScale_Height; }
private float mScale_TextSize = -1f;
public float getScale_TextSize() { return mScale_TextSize; }
public void setScale_TextSize(float pScale_TextSize) { mScale_TextSize = pScale_TextSize; }
private TextView_WrapContent_Direction mTextView_WrapContent_Direction = TextView_WrapContent_Direction.None;
private boolean mTextView_WrapContent_ResizeSurrounded = false;
private boolean mTextView_WrapContent_MoveSiblings = true;
public void setTextView_WrapContent(TextView_WrapContent_Direction pTextView_WrapContent_Direction, boolean pTextView_WrapContent_ResizeSurrounded, boolean pTextView_WrapContent_MoveSiblings) {
mTextView_WrapContent_Direction = pTextView_WrapContent_Direction;
mTextView_WrapContent_ResizeSurrounded = pTextView_WrapContent_ResizeSurrounded;
mTextView_WrapContent_MoveSiblings = pTextView_WrapContent_MoveSiblings;
}
}
//////////////// 편리하게 View를 추가하기 위한 함수들 //////////////
/**
* adds new TextView with (TextSize, Left, Top, Width, Height) parameters
* DuplicateState is false by default.
* @param pText
* @param pScale_TextSize
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @return created TextView instance
*/
public TextView addNewTextView(String pText,
float pScale_TextSize,
float pScale_Left, float pScale_Top,
float pScale_Width, float pScale_Height) {
return addNewTextView(pText, pScale_TextSize, pScale_Left, pScale_Top, pScale_Width, pScale_Height, false);
}
/**
* adds new TextView with (TextSize, Left, Top, Width, Height, duplicateState) parameters
* @param pText
* @param pScale_TextSize
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @param pDuplicateState
* @return created TextView instance
*/
public TextView addNewTextView(String pText,
float pScale_TextSize,
float pScale_Left, float pScale_Top,
float pScale_Width, float pScale_Height,
boolean pDuplicateState) {
TextView ret = new TextView(getContext());
addView(ret, pScale_Left, pScale_Top, pScale_Width, pScale_Height);
setScale_TextSize(ret, pScale_TextSize);
ret.setText(pText);
ret.setGravity(Gravity.CENTER);
ret.setTextColor(Color.BLACK);
ret.setDuplicateParentStateEnabled(pDuplicateState);
return ret;
}
/**
* adds new EditText with (TextSize, Left, Top, Width, Height) parameters
* @param pScale_TextSize
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @return created EditText instance
*/
public EditText addNewEditText(float pScale_TextSize, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
EditText ret = new EditText(getContext());
addView(ret, pScale_Left, pScale_Top, pScale_Width, pScale_Height);
setScale_TextSize(ret, pScale_TextSize);
ret.setGravity(Gravity.CENTER);
ret.setTextColor(Color.BLACK);
return ret;
}
/**
* adds new ImageView with (Left, Top, Width, Height) parameters
* Drawable is null by default.
* DuplicateState is false by default.
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @return created ImageView instance
*/
public ImageView addNewImageView(float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
return addNewImageView((Drawable)null, pScale_Left, pScale_Top, pScale_Width, pScale_Height, false);
}
/**
* adds new ImageView with (Bitmap, Left, Top, Width, Height) parameters
* sets Image of ImageView with Bitmap parameter
* DuplicateState is false by default.
* @param pBitmap
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @return created ImageView instance
*/
public ImageView addNewImageView(Bitmap pBitmap, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
BitmapDrawable bm = new BitmapDrawable(getResources(), pBitmap);
return addNewImageView(bm, pScale_Left, pScale_Top, pScale_Width, pScale_Height, false);
}
/**
* adds new ImageView with (ResourceID, Left, Top, Width, Height) parameters
* sets Image of ImageView with ResourceID parameter
* DuplicateState is false by default.
* @param pResID
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @return created ImageView instance
*/
public ImageView addNewImageView(int pResID, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
return addNewImageView(pResID, pScale_Left, pScale_Top, pScale_Width, pScale_Height, false);
}
/**
* adds new ImageView with (ResourceID, Left, Top, Width, Height, DuplicateState) parameters
* sets Image of ImageView with ResourceID parameter
* @param pResID
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @param pDuplicateState
* @return created ImageView instance
*/
public ImageView addNewImageView(int pResID, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height, boolean pDuplicateState) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
return addNewImageView(
new BitmapDrawable(getResources(), BitmapFactory.decodeResource(getResources(), pResID, options)),
pScale_Left, pScale_Top, pScale_Width, pScale_Height, pDuplicateState);
}
/**
* adds new ImageView with (Drawable, Left, Top, Width, Height) parameters
* sets Image of ImageView with Drawable parameter
* DuplicateState is false by default.
* @param drawable
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @return created ImageView instance
*/
public ImageView addNewImageView(Drawable drawable, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height) {
return addNewImageView(drawable, pScale_Left, pScale_Top, pScale_Width, pScale_Height, false);
}
/**
* adds new ImageView with (Drawable, Left, Top, Width, Height, DuplicateState) parameters
* sets Image of ImageView with Drawable parameter
* @param drawable
* @param pScale_Left
* @param pScale_Top
* @param pScale_Width
* @param pScale_Height
* @param pDuplicateState
* @return
*/
public ImageView addNewImageView(Drawable drawable, float pScale_Left, float pScale_Top, float pScale_Width, float pScale_Height, boolean pDuplicateState) {
ImageView lNewImageView = new ImageView(getContext());
lNewImageView.setImageDrawable(drawable);
lNewImageView.setScaleType(ScaleType.FIT_XY);
lNewImageView.setDuplicateParentStateEnabled(pDuplicateState);
addView(lNewImageView, pScale_Left, pScale_Top, pScale_Width, pScale_Height);
return lNewImageView;
}
////////////////////////// Log
@Override
public String toString() {
return String.format("{ScalableLayout:%08x}", this.hashCode());
}
void log(String pLog) {
if(sLogTag_Global != null) {
Log.e(sLogTag_Global, this+"] "+pLog);
}
if(mLogTag_This != null) {
Log.e(mLogTag_This, this+"] "+pLog);
}
}
private String mLogTag_This = null;
public String getLogTag_This() {
return mLogTag_This;
}
/**
* setLoggable("ScalableLayout");
*/
public void setThisLoggable() {
setThisLoggable("ScalableLayout");
}
/**
* Log를 출력할수 있게함
* @param pLogTag DDMS Log Tag를 지정
*/
public void setThisLoggable(String pLogTag) {
mLogTag_This = pLogTag;
}
private static String getStackTrace(StackTraceElement[] ste) {
StringBuilder sb = new StringBuilder();
for(int i=0;i<ste.length;i++){
sb.append("\t"+ste[i].toString()+"\n");
}
return sb.toString();
}
// private static String getStackTrace(Throwable e) {
// StringBuilder sb = new StringBuilder();
// printStackTrace(sb, e);
// while(e.getCause() != null){
// e = e.getCause();
// printStackTrace(sb, e);
// }
// return sb.toString();
// }
// private static void printStackTrace(StringBuilder sb, Throwable e) {
// sb.append("Caused by: "+e.getClass().getName()+", "+e.getMessage()+"\n");
// StackTraceElement[] ste = e.getStackTrace();
// for(int i=0;i<ste.length;i++){
// sb.append("\t"+ste[i].toString()+"\n");
// }
// }
private static String sLogTag_Global = null;
/**
* setLoggable("ScalableLayout");
*/
public static void setLoggable() {
setLoggable("ScalableLayout");
}
/**
* Log를 출력할수 있게함
* @param pLogTag DDMS Log Tag를 지정
*/
public static void setLoggable(String pLogTag) {
sLogTag_Global = pLogTag;
}
}