【问题标题】:How to move a view (button) programmatically in a constraint layout?如何在约束布局中以编程方式移动视图(按钮)?
【发布时间】:2020-03-20 23:26:11
【问题描述】:

我正在尝试创建一个简单的时间表,(我是初学者)。我已经为 7 天 24 小时的时间表创建了一个基本布局,我的想法是以编程方式插入按钮,通过操作按钮的位置和宽度来覆盖正确时间和持续时间的时间表,以便在单击时显示任务保存在下面的文本视图中:

我知道如何创建按钮,但经过数小时搜索工作方法以将其大小和位置更改为所需值但没有成功,我转向这里寻求帮助。

作为测试,我在设计视图中创建了一个带有一个预制约束视图的新空项目,并尝试在其中放置一个按钮并移动它。代码如下:


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

按钮出现在约束视图中,但无论我如何更改 x 和 y 都不会更改位置。我究竟做错了什么?另外我怎样才能改变大小?

编辑1: 按要求向 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>

编辑2:

添加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) 

【问题讨论】:

    标签: java android android-studio android-layout android-constraintlayout


    【解决方案1】:

    这些行不见了

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

    这是带有输出的工作解决方案。

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

    【讨论】:

    • 我试过了,但每当我添加其中一条或两条线时,我的应用程序就会崩溃?
    • 可以分享崩溃日志吗?
    • 是不是因为我没有加btn.setId(View.generateViewId());
    • 另外你知道如何回答问题的第二部分,如何改变按钮的大小吗?
    • 高度和宽度
    【解决方案2】:

    不要使用这一行:

    Button btn = new Button(this);
    

    您应该直接从 XML 中获取您的按钮。 例如:如果在 XML 文件中,您的按钮被命名为 btn1。 然后,使用这个:

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

    然后,尝试执行这些操作。 它应该可以工作。

    【讨论】:

    • 试过了,没用。它没有崩溃,但仍然没有移动。
    • 可以分享一下layout的xml文件吗?
    • 嗯,我按照@Usman Zafer 所说的进行了尝试,所以我在屏幕上做了一个按钮,然后添加了 set.clone 和 set.applyTo,我设法移动了 y 轴,但 x 轴仍在没变?
    • 另外,请分享您的 XML 文件。
    • 那不是 XML 文件。我想要带有 XML 代码的文件
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-08-09
    相关资源
    最近更新 更多