2011-01-05 27 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

相关问题