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 はっきりtarget
とmode
がOnClickの属性です。しかし、その名前空間に見つからないため、mode
を使用するとプロジェクトはコンパイルされません。
質問3:正しい名前空間を使用していますか?
削除することで、最初からプログラムでクリックを処理することもできます。
<OnClick app:target="@id/nextButton" />
_
完全に。また、遷移の進行状況を確認することで、ビューが拡張されているかどうかを確認できます。そのため、Java/Kotlinファイルにプログラム的に処理することができます。
yourButton.setOnClickListener {
if (yourMotionLayoutId.progress == 0.0)
yourMotionLayoutId.transitionToEnd
}
_
このように、遷移が発生していない状態(進行状況は0.0となる)と遷移に遷移しているかどうかを確認します。そうしないと、何もしません。
私はそれをするためのよりきれいで正しい方法を見つけました、あなたはこれを行うことができます....ビューから直接オンにします..
注:それは:<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
}
一般に、コールバックが必要な場合は、おそらくアニメーションを自分で管理したいと思うでしょう。それで、あなたがonClickを追加しているのであれば、あなたは自分自身の移行を呼び出すべきです。
public void onClick(View v) {
((MotionLayout)v.getParent()).transitionToEnd());
// you can decide all the actions and conditionals.
}
_
意図は開発者が気にしないのか便利です。 UI要素などの非表示/明らかな、またはテストのために、コールバックを配線する前にテストのため。
遷移時に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) {
}
_
}
このハックを使用しただけで、クリックはプログラムで処理されますが、<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>