以编程方式在多个相同视图之间设置约束

时间:2019-05-20 15:12:02

标签: android android-constraintlayout

我有一个constraintLayout,其中包含多个nodeViewnodeView是附着在ImageView圆圈node

左侧的一条ImageView线

我现在想将X个节点连接在一起。要以编程方式设置约束,请使用R.id,但是由于我将多个相同的节点连接在一起,并且它们都共享相同的R.id,因此无法正常工作。有什么方法可以引用特定视图的ImageView作为为另一个ImageView设置约束的参考?我开始认为我正在完全以错误的方式来对待。谢谢。

编辑:这是其余的代码。

节点代码

private void init(Context context, AttributeSet attrs, String description, boolean active, boolean base) {
        View inflatedView = inflate(context, R.layout.tracking_node, this);
        nodeLine = inflatedView.findViewById(R.id.imageNodeLine);
        nodeImage = inflatedView.findViewById(R.id.imageNode);
        nodeText = inflatedView.findViewById(R.id.textNode);

        nodeLine.setId(View.generateViewId());
        nodeImage.setId(View.generateViewId());

        nodeText.setText(description);
        if (active){
            nodeImage.setImageResource(R.drawable.circle_green);
            nodeLine.setImageResource(R.color.support_success);
        }else{
            nodeImage.setImageResource(R.drawable.circle_grey);
            nodeImage.setImageResource(R.color.grey);
        }

        //Remove left-side connecting line if base node
        if (base){
            nodeLine.getLayoutParams().width = 20;
            nodeLine.setImageResource(R.color.transparent);
        }
    }

    public int getNodeImageId(){
        return nodeImage.getId();
    }

    public int getNodeLineId(){
        return nodeLine.getId();
    }

constraintLayout代码

private void init(Context context, AttributeSet attrs) {
        View inflatedView = inflate(context, R.layout.delivery_status_view, this);
        deliveryTrackerView = inflatedView.findViewById(R.id.linearLayoutDeliveryTracking);
        shippingDetailsButton = inflatedView.findViewById(R.id.btnShippingDetails);


        //steps[] is a string array that contains the content of each node
        DeliveryNodeView node = new DeliveryNodeView(context, attrs, steps[0], true, true);
        //Saves resource ID of last node image
        int pastNodeID = node.getNodeImageId();

        //Generates nodes
        for (int i = 1; i < steps.length; i++){

            boolean active = ((i + 1) / currentStep) <= 1;
            node = new DeliveryNodeView(context, attrs, steps[i], active, false);
            int nodeLineID = node.getNodeLineId();


            ConstraintSet constraintSet = new ConstraintSet();
            constraintSet.clone(deliveryTrackerView);


            deliveryTrackerView.addView(node);
            constraintSet.connect(nodeLineID, ConstraintSet.START, pastNodeID, ConstraintSet.END);
            pastNodeID = node.getNodeImageId();

        }

    }

1 个答案:

答案 0 :(得分:0)

您的代码有一些问题。这是一些示例代码,可构建一个5x5的彩色框数组,如下所示:

enter image description here

代码中的注释概述了关键步骤。 activity_main.xml 只是一个空的 ConstraintLayout

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        ConstraintLayout layout = findViewById(R.id.layout);
        int colorCounter = 0;
        int idToTop = ConstraintSet.PARENT_ID;
        int idToTopSide = ConstraintSet.TOP;
        for (int i = 0; i < 5; i++) {
            int idToLeft = ConstraintSet.PARENT_ID;
            int idToLeftSide = ConstraintSet.START;
            for (int j = 0; j < 5; j++) {
                View box = getBox(colorCounter++ % 2 == 0);
                // Add the view before getting the ConstraintSet.
                layout.addView(box);
                ConstraintSet cs = new ConstraintSet();
                cs.clone(layout);
                // Must constrain the view horizontally...
                cs.connect(box.getId(), ConstraintSet.START, idToLeft, idToLeftSide);
                //... and vertically.
                cs.connect(box.getId(), ConstraintSet.TOP, idToTop, idToTopSide);
                idToLeft = box.getId();
                idToLeftSide = ConstraintSet.END;
                // Apply the ConstraintSet to the layout.
                cs.applyTo(layout);
            }
            idToTop = idToLeft;
            idToTopSide = ConstraintSet.BOTTOM;
        }
    }

    private View getBox(boolean isRed) {
        View view = new View(this);
        view.setId(View.generateViewId());
        view.setBackgroundColor((isRed) ? Color.RED : Color.BLUE);
        ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(200, 200);
        view.setLayoutParams(lp);
        return view;
    }
}

具有相同结果的备用代码将视图创建与创建 ConstraintSet 连接分开。这 可能会更有效率。

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        ConstraintLayout layout = findViewById(R.id.layout);
        int colorCounter = 0;

        int[][] connections = new int[5][5];
        for (int row = 0; row < 5; row++) {
            for (int col = 0; col < 5; col++) {
                View box = getBox(colorCounter++ % 2 == 0);
                // Add the view before getting the ConstraintSet.
                layout.addView(box);
                connections[row][col] = box.getId();
            }
        }

        int idToTop = ConstraintSet.PARENT_ID;
        int idToTopSide = ConstraintSet.TOP;
        ConstraintSet cs = new ConstraintSet();
        cs.clone(layout);
        for (int i = 0; i < 5; i++) {
            cs.connect(connections[i][0], ConstraintSet.START, ConstraintSet.PARENT_ID, ConstraintSet.START);
            cs.connect(connections[i][0], ConstraintSet.TOP, idToTop, idToTopSide);
            for (int j = 1; j < 5; j++) {
                // Must constrain the view horizontally...
                cs.connect(connections[i][j], ConstraintSet.START, connections[i][j - 1], ConstraintSet.END);
                //... and vertically.
                cs.connect(connections[i][j], ConstraintSet.TOP, idToTop, idToTopSide);
                // Apply the ConstraintSet to the layout.
            }
            idToTop = connections[i][0];
            idToTopSide = ConstraintSet.BOTTOM;
        }
        cs.applyTo(layout);
    }

    private View getBox(boolean isRed) {
        View view = new View(this);
        view.setId(View.generateViewId());
        view.setBackgroundColor((isRed) ? Color.RED : Color.BLUE);
        ConstraintLayout.LayoutParams lp = new ConstraintLayout.LayoutParams(200, 200);
        view.setLayoutParams(lp);
        return view;
    }
}