简体   繁体   English

如何在约束布局中以编程方式移动视图(按钮)?

[英]How to move a view (button) programmatically in a constraint layout?

I'm trying to create a simple timetable, (I'm a beginner).我正在尝试创建一个简单的时间表,(我是初学者)。 I have created a basic layout for the timetable with 7 days and 24 hours, and my idea was to insert buttons programmatically, overlaying the timetable for the correct time and duration by manipulating the position and width of the buttons, so that when clicked they display the task saved in the textview below as such:我已经为 7 天 24 小时的时间表创建了一个基本布局,我的想法是以编程方式插入按钮,通过操纵按钮的位置和宽度来覆盖正确时间和持续时间的时间表,以便在单击时显示保存在下面的文本视图中的任务如下:

时间表布局

I know how to create the buttons but after hours of searching for a working method to change their size and location to the desired values with no success I turn here for help.我知道如何创建按钮,但经过数小时的搜索工作方法将它们的大小和位置更改为所需的值但没有成功,我在这里寻求帮助。

As a test I made a new empty project with one premade constraint view in the design view and tried to place a single button within it and move it.作为测试,我在设计视图中创建了一个带有预制约束视图的新空项目,并尝试在其中放置一个按钮并移动它。 Here is the code:这是代码:


import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.constraintlayout.widget.ConstraintSet;

import android.os.Bundle;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ConstraintLayout constraintLayout01 = (ConstraintLayout)findViewById(R.id.constraintLayout01); //a constraint layout pre-made in design view

        Button btn = new Button(this);
        btn.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
        constraintLayout01.addView(btn);

        int x = 100;
        int y = 5;
        ConstraintSet set = new ConstraintSet();
        set.connect(btn.getId(), ConstraintSet.LEFT, constraintLayout01.getId(), ConstraintSet.LEFT, x);
        set.connect(btn.getId(), ConstraintSet.TOP, constraintLayout01.getId(), ConstraintSet.TOP, y);
    }
}

The button appears within the constraint view but no matter how I change x and y nothing ever changes location.该按钮出现在约束视图中,但无论我如何更改 x 和 y 都不会更改位置。 What am I doing wrong?我究竟做错了什么? Also how can I change the size?另外我怎样才能改变大小?

Edit1: Added a button to xml as requested: Edit1:根据要求向 xml 添加了一个按钮:

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/RootLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/constraintLayout01"
        android:layout_width="390dp"
        android:layout_height="645dp"
        android:layout_marginStart="28dp"
        android:layout_marginTop="16dp"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <Button
            android:id="@+id/button2"
            android:layout_width="38dp"
            android:layout_height="41dp"
            android:layout_marginStart="100dp"
            android:layout_marginTop="100dp"
            android:text=""
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    </androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

edit2:编辑2:

logcat after adding set.clone and set.applyTo:添加 set.clone 和 set.applyTo 后的 logcat:

2020-03-23 10:24:56.111 10888-10888/? E/.example.test0: Unknown bits set in runtime_flags: 0x8000
2020-03-23 10:24:56.201 10888-10888/com.example.test02 I/Perf: Connecting to perf service.
2020-03-23 10:24:56.210 10888-10918/com.example.test02 E/Perf: Fail to get file list com.example.test02
2020-03-23 10:24:56.210 10888-10918/com.example.test02 E/Perf: getFolderSize() : Exception_1 = java.lang.NullPointerException: Attempt to get length of null array
2020-03-23 10:24:56.307 10888-10888/com.example.test02 W/.example.test0: Accessing hidden method Landroid/view/View;->computeFitSystemWindows(Landroid/graphics/Rect;Landroid/graphics/Rect;)Z (greylist, reflection, allowed)
2020-03-23 10:24:56.308 10888-10888/com.example.test02 W/.example.test0: Accessing hidden method Landroid/view/ViewGroup;->makeOptionalFitsSystemWindows()V (greylist, reflection, allowed)
2020-03-23 10:24:56.346 10888-10888/com.example.test02 D/AndroidRuntime: Shutting down VM
2020-03-23 10:24:56.347 10888-10888/com.example.test02 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.test02, PID: 10888
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.test02/com.example.test02.MainActivity}: java.lang.RuntimeException: All children of ConstraintLayout must have ids to use ConstraintSet
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3271)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3410)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017)
        at android.os.Handler.dispatchMessage(Handler.java:107)
        at android.os.Looper.loop(Looper.java:214)
        at android.app.ActivityThread.main(ActivityThread.java:7397)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935)
     Caused by: java.lang.RuntimeException: All children of ConstraintLayout must have ids to use ConstraintSet
        at androidx.constraintlayout.widget.ConstraintSet.clone(ConstraintSet.java:713)
        at com.example.test02.MainActivity.onCreate(MainActivity.java:29)
        at android.app.Activity.performCreate(Activity.java:7802)
        at android.app.Activity.performCreate(Activity.java:7791)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1307)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3246)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3410) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2017) 
        at android.os.Handler.dispatchMessage(Handler.java:107) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7397) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:935) 

Instead of using this line:而不是使用这一行:

Button btn = new Button(this);

You should get your button directly from the XML.您应该直接从 XML 获取按钮。 For example: if in the XML file, your button is named btn1.例如:如果在 XML 文件中,您的按钮名为 btn1。 Then, use this:然后,使用这个:

Button btn = (Button)findViewbyId(R.id.btn1);

Then, try performing the operations.然后,尝试执行操作。 It should work.它应该工作。

These lines were missing这些行不见了

    btn.setId(View.generateViewId());
    set.clone(constraintLayout);
    set.applyTo(constraintLayout);

Here is the working solution with the output.这是带有输出的工作解决方案。

public class Main_One extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_one);
        ConstraintLayout constraintLayout = (ConstraintLayout)findViewById(R.id.connstraint_layout); //a constraint layout pre-made in design view
        Button btn = new Button(this);
        btn.setText("StackFlow");
        btn.setLayoutParams(new ConstraintLayout.LayoutParams(ConstraintLayout.LayoutParams.WRAP_CONTENT, ConstraintLayout.LayoutParams.WRAP_CONTENT));
        btn.setId(View.generateViewId());
        constraintLayout.addView(btn);
        int x = 100;
        int y = 505;
        ConstraintSet set = new ConstraintSet();
        set.clone(constraintLayout);
        set.connect(btn.getId(), ConstraintSet.LEFT, constraintLayout.getId(), ConstraintSet.LEFT, x);
        set.connect(btn.getId(), ConstraintSet.TOP, constraintLayout.getId(), ConstraintSet.TOP, y);
        set.applyTo(constraintLayout);
}

    }

XML XML

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

   <androidx.constraintlayout.widget.ConstraintLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/connstraint_layout">

   </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM