如何在Android中多次重用XML文件中定义的ViewGroup?

时间:2011-01-05 20:12:26

标签: android android-layout

我正在尝试创建一个简单的游戏。我想填充一个LinearLayout,我在XML中定义了几个RelativeLayouts。每次用户按下按钮时,我都希望将子视图添加到LinearLayout。每个RelativeLayout将根据用户输入(按下哪些按钮等)稍微改变。

我基本上想要基于XML布局文件创建一个新的RelativeLayout。然后我想操纵RelativeLayout的子视图的某些属性(特别是某些ImageView的src)并将其添加到LinearLayout。这本身并不是特别困难。我可以使用findViewById获取每个RelativeLayout的子节点,但是当我想基于相同的XML创建n个RelativeLayouts时,我开始遇到问题。我很确定重复的ID会导致崩溃。 RelativeLayout可以在不使用ID的情况下工作吗?我应该尝试使用不同的ViewGroups找到构建接口的不同方法吗?

我不确定我问的问题是否可能,但我知道使用XML布局替代代码即时创建这些项目是一个可怕的想法。

提前谢谢。

3 个答案:

答案 0 :(得分:2)

编辑:我中途失去了思路,前面的例子有些烦恼。我已经更新了。

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;
}

答案 1 :(得分:1)

编辑:我甚至无法正确理解如何正确使用代码标签叹息

感谢您的快速回复。我有一些非常相似的东西,实际上是在同一轨道上并使用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必须是唯一的。

答案 2 :(得分:0)

我认为你必须创建一个根元素,然后添加新的子元素。

像这样:

RelatoveLayout root = ....;

RelativeLayout toadd = inflate(你的XML);

根据用户输入通过代码更改来应用,例如:

toadd.setBackgroundResource(....);

最后将结果添加到根目录:

root.addView(TOADD)。

我真的希望能帮到你!

再见!