web-dev-qa-db-ja.com

MotionLayout:MotionScene OnClickはSetOnClickListenerをオーバーライドします

MotionLayoutで遊び始めています。 MotionLayoutを使用してMotionSceneを使用してアクティビティレイアウトを定義しました。

MotionSceneトランジションは次のようになります。

<Transition
    app:constraintSetStart="@id/collapsed"
    app:constraintSetEnd="@id/expanded">

    <OnClick app:target="@id/nextButton"  />

</Transition>
 _

トラブルーは、プログラムでClickListenerをボタンに追加すると何も起こりません。

nextButton.setOnClickListener {
        //do some stuff
    }
 _

このリスナーは完全に無視されますが、遷移(ビューの展開/折りたたみ)がすべてのクリックでトリガされます。私は誰か extendsMotionLayoutを扱うためにイベントを扱うが、ボタンの別のクリックリスナーを追加する方法が簡単なようです。

質問1:ClickListenerをMotionLayout遷移でターゲットに追加する方法はありますか?

質問2:遷移を1回のイベントだけにする方法はありますか?ボタンをクリックしたときにビューが折りたたまれている場合それからビューは展開されますが、それがすでに拡張されている場合は、拡張されています。

最後に、ネームスペースを使用しています"http://schemas.Android.com/apk/res-auto"とdocs はっきりtargetmodeがOnClickの属性です。しかし、その名前空間に見つからないため、modeを使用するとプロジェクトはコンパイルされません。

質問3:正しい名前空間を使用していますか?

11
MayNotBe

削除することで、最初からプログラムでクリックを処理することもできます。

 <OnClick app:target="@id/nextButton"  />
 _

完全に。また、遷移の進行状況を確認することで、ビューが拡張されているかどうかを確認できます。そのため、Java/Kotlinファイルにプログラム的に処理することができます。

yourButton.setOnClickListener {
    if (yourMotionLayoutId.progress == 0.0)
        yourMotionLayoutId.transitionToEnd
}
 _

このように、遷移が発生していない状態(進行状況は0.0となる)と遷移に遷移しているかどうかを確認します。そうしないと、何もしません。

2
kjanderson2

私はそれをするためのよりきれいで正しい方法を見つけました、あなたはこれを行うことができます....ビューから直接オンにします..

注:それは:<OnSwipe/>しか<OnClick/>だけでは機能しません。

PD。すみません、私はメキシコ出身で、私は翻訳者を使っています

<androidx.appcompat.widget.AppCompatImageView
        Android:id="@+id/play_pause_button_collapsed"
        Android:layout_width="30dp"
        Android:layout_height="50dp"
        app:srcCompat="@drawable/ic_play_arrow_black_48dp"
        Android:layout_marginTop="25dp"
        Android:elevation="2dp"
        Android:alpha="0"

        Android:onClick="handleAction"

        tools:ignore="ContentDescription" />



fun handleAction(view: View) { 
   //handle click
}
1
Erick Alvarez

一般に、コールバックが必要な場合は、おそらくアニメーションを自分で管理したいと思うでしょう。それで、あなたがonClickを追加しているのであれば、あなたは自分自身の移行を呼び出すべきです。

public void onClick(View v) {
   ((MotionLayout)v.getParent()).transitionToEnd());
   // you can decide all the actions and conditionals.
 }
 _

意図は開発者が気にしないのか便利です。 UI要素などの非表示/明らかな、またはテストのために、コールバックを配線する前にテストのため。

0
hoford

遷移時にMotionLayout.TransitionListenerをハンドライベントに実装できます。

public class LoginActivity extends AppCompatActivity implements MotionLayout.TransitionListener {
private static final String TAG = "LoginActivity";
private FirebaseAuth mAuth;
private LoginLayoutBinding binding;

@SuppressLint("ClickableViewAccessibility")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    binding = LoginLayoutBinding.inflate(getLayoutInflater());
    setContentView(binding.getRoot());

    // initialize the FirebaseAuth instance.
    mAuth = FirebaseAuth.getInstance();
    binding.getRoot().addTransitionListener(this);
}


@Override
public void onStart() {
    super.onStart();
    // Check if user is signed in (non-null) and update UI accordingly.
    FirebaseUser currentUser = mAuth.getCurrentUser();
    updateUI(currentUser);
}

private void updateUI(FirebaseUser currentUser) {
    hideProgressBar();
    if (currentUser != null) {
        Intent intent = new Intent(LoginActivity.this, MainActivity.class);
        startActivity(intent);
        finish();
    }
}

private void hideProgressBar() {
    binding.progressBar2.setVisibility(View.GONE);
}

private void createAccount(String email, String password) {
    mAuth.createUserWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "createUserWithEmail:success");
                        FirebaseUser user = mAuth.getCurrentUser();
                        updateUI(user);
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "createUserWithEmail:failure", task.getException());
                        Toast.makeText(LoginActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                        updateUI(null);
                    }
                }
            });
}

private void signIn(String email, String password) {
    mAuth.signInWithEmailAndPassword(email, password)
            .addOnCompleteListener(this, new OnCompleteListener<AuthResult>() {
                @Override
                public void onComplete(@NonNull Task<AuthResult> task) {
                    if (task.isSuccessful()) {
                        // Sign in success, update UI with the signed-in user's information
                        Log.d(TAG, "signInWithEmail:success");
                        FirebaseUser user = mAuth.getCurrentUser();
                        updateUI(user);
                    } else {
                        // If sign in fails, display a message to the user.
                        Log.w(TAG, "signInWithEmail:failure", task.getException());
                        Toast.makeText(LoginActivity.this, "Authentication failed.",
                                Toast.LENGTH_SHORT).show();
                        updateUI(null);
                    }
                }
            });
}


@Override
public void onTransitionStarted(MotionLayout motionLayout, int startId, int endId) {

}

@Override
public void onTransitionChange(MotionLayout motionLayout, int startId, int endId, float progress) {

}

@Override
public void onTransitionCompleted(MotionLayout motionLayout, int currentId) {
    if (currentId==R.id.end){
        binding.btnLogin.setText(R.string.sign_up);
        binding.textView3.setEnabled(false);
        binding.textView2.setEnabled(true);
    }else {
        binding.btnLogin.setText(R.string.login);
        binding.textView2.setEnabled(false);
        binding.textView3.setEnabled(true);
    }

}

@Override
public void onTransitionTrigger(MotionLayout motionLayout, int triggerId, boolean positive, float progress) {

}
 _

}

0

このハックを使用しただけで、クリックはプログラムで処理されますが、<OnClick>MotionSceneに登録されている隠しビューをトリガーします。

actualVisibleView.setOnClickListener {
            doSomeLogic()
            hiddenView.performClick()
        }

そしてMotionSceneで:

<Transition
        Android:id="@+id/hackedTransitionThanksToGoogle"
        motion:constraintSetEnd="@layout/expanded"
        motion:constraintSetStart="@layout/closed"
        motion:duration="300"
        motion:motionInterpolator="linear">

        <OnClick
            motion:clickAction="transitionToEnd"
            motion:targetId="@+id/hiddenView" />
</Transition>