2012-09-05 49 views
7

我使用NineOldAndroids庫來縮放我的自定義佈局。Android ViewGroup.setScaleX()導致視圖被剪輯

public class MyLayout extends FrameLayout { 
    // LayoutParams.MATCH_PARENT and all. 
    ... 
    @Override 
    public boolean setPositionAndScale(ViewGroup v, PositionAndScale pas, PointInfo pi) { 
    ... 
    mScale = pas.getScale(); 
    ViewHelper.setScaleX(this, mScale); 
    ViewHelper.setScaleY(this, mScale); 
    } 
} 

我試過FrameLayout和AbsoluteLayout。所有都有相同的效果。 當mScale < 1.0縮放/縮放工程但部分佈局是修剪

mScale = 1.0:

mScale = 1.0

mScale < 1.0:縮放/縮放工作但佈局裁剪

mScale < 1.0

我怎樣才能解決這個問題?

編輯:照片是在ICS上拍攝的。所以我不認爲這是NineOldAndroids的問題。

+0

你期待輸出看起來像什麼? – alanv

+0

類似於MapView。佈局('MyLayout')填充整個屏幕,並不像2. pic中那樣剪切。 MyLayout的LayoutParam被設置爲match_parent。 – user802421

回答

2

如果任何人有到同樣的情況我。 我結束了使用這種方法:

protected void setScale(float scale, boolean updateView) { 
    mScale = scale; 
    if (updateView) { 
     LayoutParams params = getLayoutParams(); 
     onUpdateScale(scale, params); 
     setLayoutParams(params); 
    } 
} 

protected void onUpdateScale(float scale, LayoutParams params) { 
    params.leftMargin = (int) (mModel.getX() * scale); 
    params.topMargin = (int) (mModel.getY() * scale); 
    params.width = (int) (mModel.getWidth() * scale); 
    params.height = (int) (mModel.getHeight() * scale); 
} 
+0

這種方法速度快嗎?我的意思是,你是否使用類似手勢的比例來進行太多更新,或者你只在當時縮放一次? –

+0

我還沒有運行基準測試或追蹤視圖,但它在Xoom 1和Nexus S上運行良好。需求是需要不斷移動和縮放(如Google地圖),而不是一旦交互結束(如放大OSMTracker )。 – user802421

+0

那麼,沒有閃爍? (+1,如果你回答否:-)) –

1

如果我正確理解您的問題,您將縮放視圖組,並期望相應的縮放視圖。它不會這樣工作:縮放視圖組並且它改變大小,但其子視圖不會。

只需縮放所有子視圖。即便如此,我不確定文字和圖像是否會自動縮放。你想要的是縮放,而不是縮放。試試this reference

+0

縮放和縮放之間有什麼區別?圖2顯示縮放/縮放工作(mScale〜0.8)。這只是ViewGroup被剪裁。 – user802421

+0

那麼,你的引用和我的代碼一樣。 – user802421

+0

我退休後,我的答案,對不起,噪音。 – alexfernandez

1

由於API級別11,View級別有setScaleX()setScaleY()方法,它們按預期方式工作並且還縮放縮放視圖的子視圖。所以,如果那將會是一種方式適合你,降庫,只是做

v.setScaleX(mScale); 
v.setScaleY(mScale); 
+0

我曾嘗試過。它具有相同的裁剪效果。實際上,圖書館只是一個代理。在ICS上,NineOldAndroids只是調用相同的方法。 – user802421

+0

@ user802421這可能有所幫助:http://stackoverflow.com/q/14415035/350040 – sergio91pt

0

使用ViewGroup.layout。這可能是最簡單的縮放方式(&移動)ViewGroup。

3

您的視圖的父級必須禁用屬性android:clipChildren(從佈局文件或setClipChildren(false))。

但使用此方法,您不會在視圖剪輯邊界之外獲取觸摸事件。您可以通過從您的活動中發送或親自編寫自定義ViewGroup來解決問題。

我正在使用不同的黑客,似乎在我的情況下工作,訣竅是維護自己的變換矩陣。然後,你必須重載很多ViewGroup的方法才能使它工作。例如:

@Override 
protected void dispatchDraw(Canvas canvas) { 
    Log.d(TAG, "dispatchDraw " + canvas); 
    canvas.save(); 
    canvas.concat(mMatrix); 
    super.dispatchDraw(canvas); 
    canvas.restore();  
} 


@Override 
public boolean dispatchTouchEvent(MotionEvent ev) { 
    Log.d(TAG, "dispatchTouchEvent " + ev); 
    ev.transform(getInvMatrix()); // 
    return super.dispatchTouchEvent(ev); 

} 

private Matrix getInvMatrix() 
{ 
    if(!mTmpMatIsInvMat) 
     mMatrix.invert(mTmpMat); 
    mTmpMatIsInvMat = true; 
    return mTmpMat; 
} 
+0

您可以從視圖中獲取矩陣。 view.getMatrix()然後顛倒它,m.invert(m)並使用它來縮放運動事件。 – Tatarize

+0

我嘗試了幾種不同的黑客模式,只是簡單地轉播了原始觸摸,然後通過視圖矩陣進行了轉換。唯一能夠在我所能訪問的所有硬件上始終如一地工作的是維護我自己的矩陣並使用它來轉換motionevents,視圖和無效矩形。 – Tatarize