【问题标题】:How to create a RelativeLayout programmatically with two buttons one on top of the other?如何使用两个按钮一个在另一个之上以编程方式创建一个 RelativeLayout?
【发布时间】:2011-02-12 16:42:02
【问题描述】:

我在 UI 中添加了两个按钮,但它们彼此重叠出现。我希望它们彼此相邻出现。我在这段代码中遗漏了什么?

m_btnCrown = new ImageButton(this);
m_btnCrown.setImageResource(R.drawable.king_crown_thumb);
m_btnCrown.setAlpha(100);

RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);


addContentView(m_btnCrown, lp);


m_btnMonkey = new ImageButton(this);
m_btnMonkey.setImageResource(R.drawable.monkey_small);
m_btnMonkey.setAlpha(100);

lp = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
lp.addRule(RelativeLayout.ALIGN_PARENT_TOP);
lp.addRule(RelativeLayout.RIGHT_OF, m_btnCrown.getId());   

addContentView(m_btnMonkey, lp);

【问题讨论】:

    标签: android android-relativelayout


    【解决方案1】:

    我编写了一个简单的示例来演示如何以编程方式创建布局。

    public class CodeLayout extends Activity {
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            // Creating a new RelativeLayout
            RelativeLayout relativeLayout = new RelativeLayout(this);
    
            // Defining the RelativeLayout layout parameters.
            // In this case I want to fill its parent
            RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.FILL_PARENT,
                    RelativeLayout.LayoutParams.FILL_PARENT);
    
            // Creating a new TextView
            TextView tv = new TextView(this);
            tv.setText("Test");
    
            // Defining the layout parameters of the TextView
            RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
                    RelativeLayout.LayoutParams.WRAP_CONTENT,
                    RelativeLayout.LayoutParams.WRAP_CONTENT);
            lp.addRule(RelativeLayout.CENTER_IN_PARENT);
    
            // Setting the parameters on the TextView
            tv.setLayoutParams(lp);
    
            // Adding the TextView to the RelativeLayout as a child
            relativeLayout.addView(tv);
    
            // Setting the RelativeLayout as our content view
            setContentView(relativeLayout, rlp);
        }
    }
    

    理论上,一切都应该清楚,因为它被评论了。如果您有不明白的地方,请告诉我。

    【讨论】:

    • 尽管此示例有效,但我的实际问题(重叠控件)仍未得到解答。更多搜索揭示了stackoverflow.com/questions/2305395/… 中的解决方案我们应该使用 setId() 显式设置 id。只有这样 RIGHT_OF 规则才有意义
    • 嗯,这是不言自明的。如果你想通过它的 id 访问某些东西,你也必须设置它。我想用我的回答强调的是你做错了。调用addContentView覆盖之前设置的或使用setContentView 设置的内容视图。
    • 我不这么认为。只需查看此文档:developer.android.com/reference/android/app/…, android.view.ViewGroup.LayoutParams),上面写着“向屏幕添加额外的内容视图。在屏幕中的任何现有视图之后添加 - 不会删除现有视图”
    • 这个答案应该被否决。它与 OP 的问题几乎没有关系,而且是切线
    • 如果可能的话,我会建议您将布局放入 XML 中,然后使用 LayoutInflater.inflate(...) 创建实际的对象。例如,如果您需要创建可变数量的按钮,您可以有一个表示单个按钮的布局 XML,然后在循环中对其进行多次膨胀。我在尝试以编程方式执行所有操作时遇到了很多问题,因为某些属性的工作方式与在 XML 中的工作方式不同
    【解决方案2】:

    How to lay out Views in RelativeLayout programmatically?找到答案

    我们应该使用 setId() 显式设置 id。只有这样,RIGHT_OF 规则才有意义。

    我犯的另一个错误是,在控件之间重用了 layoutparams 对象。我们应该为每个控件创建新对象

    【讨论】:

    • layoutparams 部分没有错。您定义它的方式完全有效,但正如您在我上面的评论中看到的那样,您添加视图的方式是不正确的。
    【解决方案3】:
    public class AndroidWalkthroughApp1 extends Activity implements View.OnClickListener {
    
        final int TOP_ID = 3;
        final int BOTTOM_ID = 4;
    
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);
    
            // create two layouts to hold buttons
            RelativeLayout top = new RelativeLayout(this);
            top.setId(TOP_ID);
            RelativeLayout bottom = new RelativeLayout(this);
            bottom.setId(BOTTOM_ID);
    
            // create buttons in a loop
            for (int i = 0; i < 2; i++) {
                Button button = new Button(this);
                button.setText("Button " + i);
                // R.id won't be generated for us, so we need to create one
                button.setId(i);
    
                // add our event handler (less memory than an anonymous inner class)
                button.setOnClickListener(this);
    
                // add generated button to view
                if (i == 0) {
                    top.addView(button);
                }
                else {
                    bottom.addView(button);
                }
            }
    
            RelativeLayout root = (RelativeLayout) findViewById(R.id.root_layout);
    
            // add generated layouts to root layout view
           // LinearLayout root = (LinearLayout)this.findViewById(R.id.root_layout);
    
            root.addView(top);
            root.addView(bottom);
        }
    
        @Override
        public void onClick(View v) {
            // show a message with the button's ID
            Toast toast = Toast.makeText(AndroidWalkthroughApp1.this, "You clicked button " + v.getId(), Toast.LENGTH_LONG);
            toast.show();
    
            // get the parent layout and remove the clicked button
            RelativeLayout parentLayout = (RelativeLayout)v.getParent();
            parentLayout.removeView(v);
    
    
    
        }
    }
    

    【讨论】:

    • 对于您的代码,这些按钮也彼此重叠。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多