2011-01-05 32 views
1

我正在嘗試創建一個簡單的遊戲。我想填充一個LinearLayout,我用一個XML定義了幾個RelativeLayouts。每次用戶按下按鈕時,我都希望將一個子視圖添加到LinearLayout中。每個RelativeLayout會根據用戶輸入(按下哪些按鈕等)而稍微改變。如何在Android中多次重複定義XML文件中的ViewGroup?

我基本上想創建一個基於XML佈局文件的新的RelativeLayout。然後我想操縱RelativeLayout的子視圖(特別是一些ImageViews的src)的一些屬性並將其添加到LinearLayout。這本身並不是特別困難。我可以使用findViewById獲得每個RelativeLayout的孩子,但是當我想要基於相同的XML創建n個RelativeLayouts時,我開始出現問題。我很確定重複ID導致崩潰。 RelativeLayout可以在不使用ID的情況下工作嗎?我應該嘗試找到使用不同ViewGroups構造界面的不同方法嗎?

我不知道我問的是甚至可能的,但我知道使用替代XML佈局的代碼即時創建這些項目是一個可怕的想法。

預先感謝您。

回答

0

我認爲你必須創建一個根元素,然後添加新的子元素。

像這樣:

RelatoveLayout root = ....;

RelativeLayout toadd = inflate(your XML);

由代碼變化取決於用戶輸入的應用,例如:

toadd.setBackgroundResource(....);

,最後的結果添加到根:

root.addView(TOADD)。

我真的很希望能幫到你!

再見!

2

編輯:我半途中失去了我的思路,前面的例子有一些bugginess。我已更新。

pedr0有正確的想法,但要澄清,你可以嘗試一下這個效果(假設你有一個在relative.xml中定義的RelativeLayout)。這沒有經過測試,但總的想法應該是有效的。你甚至都不需要做一個單獨的方法,你可以點擊在線處理程序做,或什麼,但我只是做了addChildView方法例如着想:

LayoutInflater inflater; 

@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    //get the LinearLayout that you plan to add rows to 
    LinearLayout linearLayout = (LinearLayout)findViewById(R.id.linear_layout); 

    //get the LayoutInflater from the system 
    inflater = getSystemService(LAYOUT_INFLATER_SERVICE); 

    //call getNewChildView with whatever drawable id you want to place 
    //as the source. If you want to pass in other types, just change 
    //the parameters (e.g. Drawable, Bitmap) 
    linearLayout.addView(getNewChildView(R.drawable.my_image)); 
} 

public RelativeLayout getNewChildView(int resId) { 
    //inflates a copy of your RelativeLayout template 
    RelativeLayout rl = (RelativeLayout)inflater.inflate(R.layout.relative, null); 

    //this assumes an ImageView in your RelativeLayout with an id of image 
    ImageView img = (ImageView)rl.findViewById(R.id.image); 
    img.setBackgroundResource(resId); 

    return rl; 
} 
+0

謝謝你的快速回復。我腦子裏有一些非常相似的東西,實際上是在類似的軌道上使用LayoutInflator。 – Tom 2011-01-06 01:04:06

1

編輯:我不能」 t甚至可以解決如何正確使用代碼標記嘆息

謝謝你們兩位的快速響應。我有一些非常相似的東西,事實上它們在同一條軌道上並使用LayoutInflator。我簡化了你的例子,因爲我不需要傳遞drawable的id。

LayoutInflater inflater; 

private void drawGuess() { 
    // The top level LinearLayout to add to 
    LinearLayout topLevel = (LinearLayout) findViewById(R.id.guessList); 

    // get the inflater` 
    inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE); 

    // add the view (based on stored data elsewhere) 
    topLevel.addView(getLatestGuess()); 
} 

private RelativeLayout getLatestGuess() { 
    //inflates a copy of your RelativeLayout template 
    RelativeLayout rl = (RelativeLayout)inflater.inflate(R.layout.guess_layout, null); 

    //this assumes an ImageView in your RelativeLayout with an id of image 
    ImageView guessOne = (ImageView)rl.findViewById(R.id.guess1); 
    guessOne.setImageResource(R.drawable.red); 
} 

運行此代碼的工作原理,捕捉它只有在您第一次調用它時才起作用。第二次調用getLatestGuess()時,它會崩潰。從RelativeLayout的所有子視圖中刪除XML中的ID(例如guess1)不會導致崩潰。不幸的是,現在我有一個相當無用的RelativeLayout,因爲他們沒有ID,所以我不能再看到子視圖。據推測,ID必須是唯一的。

+0

也許你只是將​​它遺漏了,但是你不會在getLatestGuess方法中返回任何東西。你也應該在你的onCreate()方法中初始化你的inflater。你的意思是「崩潰」?檢查LogCat以瞭解發生了什麼問題。 – kcoppock 2011-01-06 02:34:58

+0

對不起,這是我的複製/粘貼錯誤。我發現一個更優雅的方式來解決這個問題,就是擴展LinearLayout。當您使用XML定義的佈局時,相對佈局非常好,每個項目都有自己的ID,但爲了我的需要,LinearLayout更合適。感謝你的幫助。 在側面註釋中,與LayoutInflater混淆產生了一些奇怪的結果。佈局的高度和寬度正在喪失,這是預期的行爲? – Tom 2011-01-06 03:58:15

+0

擴展LinearLayout看起來對於這種情況確實會有點矯枉過正,但如果它適合你,那麼我認爲這很好。通過使用LayoutInflater「搞亂」,你能更具體嗎? – kcoppock 2011-01-06 14:52:05

相關問題