web-dev-qa-db-ja.com

ConstraintLayout.Group内の個々のアイテムに可視性を設定することはできません

私は次のように定義された_ConstraintLayout.Group_を持っています:

_    <Android.support.constraint.Group
        Android:id="@+id/someGroup"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        app:constraint_referenced_ids="
        textView1,
        textView2,
        button1" />
_

このグループの可視性をGONEからVISIBLEに変更します。

_someGroup.visibility = VISIBLE
_

しかし、そのグループ内のビューの1つの可視性を指定してオーバーライドしようとすると、次のようになります。

_button1.visibility = GONE
_

...それは機能しません。この可視性をlogcatに記録すると、8 (GONE)ただし、ビューは表示されますと表示されます。

ここで何が起こっているのか考えはありますか?このグループでrequestLayoutupdatePreLayoutを呼び出してみました。可視性を数回変更して、表示、非表示、そして消えてみました。いくつかのstackoverflowの回答が、ConstraintLayoutの可視性の問題に役立つ可能性があると述べたため、プロジェクト全体を再構築しました。バージョン1.1.3と2.2.0-alphaも試しました。何も機能しませんでした。常に表示されます。

11
Michał K

正しい動作が見られます。グループ内にビューを配置すると、個々のビューの表示を変更する機能を放棄します。ビューの可視性は(あなたが)設定し、グループの可視性は(システムが)グループメンバーシップに基づいて割り当てられるというメカニズムだと思います。

回避策は、ニーズによって異なります。

  1. グループ外の可視性を制御するビューを保持します。
  2. 独自のグループロジックを管理し、システムによって提供されるグループを忘れてください。
  3. setReferencedIds を使用してグループメンバーシップを管理します。

これはよくある苦情だと思いますが、対処される可能性も低いと思います。 (私見では)


この正確な問題に関する別の質問にコメントしたので、ここに自由に投稿しました(回答はすでに受け入れられていますが)。ConstraintLayoutグループの管理に役立つ簡単なクラスです。

ManagedGroup.Java

/**
 * Manage a ConstraintLayout Group view membership as a view's visibility is changed. Calling
 * {@link #setVisibility(View, int)} will set a view's visibility and remove it from the group.
 * Other methods here provide explicit means to manage a group's view membership.
 * <p>
 * Usage: In XML define
 * <pre>{@code
 * <[Package].ManagedGroup
 *         Android:id="@+id/group"
 *         Android:layout_width="wrap_content"
 *         Android:layout_height="wrap_content"
 *         Android:visibility="visible"
 *         app:constraint_referenced_ids="id1,id2,id3..." />}
 * </pre>
 */
public class ManagedGroup extends Group {
    private final Set<Integer> mRemovedRefIds = new HashSet<>();

    public ManagedGroup(Context context) {
        super(context);
    }

    public ManagedGroup(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public ManagedGroup(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     * Set the reference ids for the group and clear the removed id array.
     *
     * @param ids All identifiers in the group.
     */
    @Override
    public void setReferencedIds(@NonNull int[] ids) {
        super.setReferencedIds(ids);
        mRemovedRefIds.clear();
    }

    /**
     * Set visibility for  view and remove the view's id from the group.
     *
     * @param view       View for visibility change
     * @param visibility View.VISIBLE, View.INVISIBLE or View.GONE.
     */
    public void setVisibility(@NonNull View view, int visibility) {
        removeReferencedIds(view.getId());
        view.setVisibility(visibility);
    }

    /**
     * Add all removed views back into the group.
     */
    public void resetGroup() {
        setReferencedIds(getAllReferencedIds());
    }

    /**
     * Remove reference ids from the group. This is done automatically when
     * setVisibility(View view, int visibility) is called.
     *
     * @param idsToRemove All the ids to remove from the group.
     */
    public void removeReferencedIds(int... idsToRemove) {
        for (int id : idsToRemove) {
            mRemovedRefIds.add(id);
        }

        int[] refIds = getReferencedIds();
        Set<Integer> newRefIdSet = new HashSet<>();

        for (int id : refIds) {
            if (!mRemovedRefIds.contains(id)) {
                newRefIdSet.add(id);
            }
        }
        super.setReferencedIds(copySetToIntArray(newRefIdSet));
    }

    /**
     * Add reference ids to the group.
     *
     * @param idsToAdd Identifiers to add to the group.
     */
    public void addReferencedIds(int... idsToAdd) {
        for (int id : idsToAdd) {
            mRemovedRefIds.remove(id);
        }
        super.setReferencedIds(joinArrays(getReferencedIds(), idsToAdd));
    }

    /**
     * Return int[] of all ids in the group plus those removed.
     *
     * @return All current ids in group plus those removed.
     */
    @NonNull
    public int[] getAllReferencedIds() {
        return joinArrays(getReferencedIds(), copySetToIntArray(mRemovedRefIds));
    }

    @NonNull
    private int[] copySetToIntArray(Set<Integer> fromSet) {
        int[] toArray = new int[fromSet.size()];
        int i = 0;

        for (int id : fromSet) {
            toArray[i++] = id;
        }

        return toArray;
    }

    @NonNull
    private int[] joinArrays(@NonNull int[] array1, @NonNull int[] array2) {
        int[] joinedArray = new int[array1.length + array2.length];

        System.arraycopy(array1, 0, joinedArray, 0, array1.length);
        System.arraycopy(array2, 0, joinedArray, array1.length, array2.length);
        return joinedArray;
    }
}
11
Cheticamp