MotionLayout: MotionScene OnClick overrides setOnClickListener

后端 未结 7 1535
庸人自扰
庸人自扰 2021-02-13 19:02

I\'m just starting to play with MotionLayout. I have defined an activity layout using MotionLayout that uses a MotionScene to hide and sh

相关标签:
7条回答
  • 2021-02-13 19:14

    I found a cleaner and more correct way to do it, you can do this .... OnClick directly from view ..

    Note: It does not work with: <OnSwipe/> only <OnClick/>

    PD. I'm sorry, I'm from Mexico and I'm using the translator

    <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
    }
    
    0 讨论(0)
  • 2021-02-13 19:14

    You can implement MotionLayout.TransitionListener to handler event when transition.

    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 讨论(0)
  • 2021-02-13 19:18
    1. Not that I can find.
    2. I found success using the clickAction attribute with the "transitionToEnd" value. This will make it so that the motionlayout cannot go back to the startConstraintSet.
    <OnClick
          motion:targetId="@+id/rateUsButton"
          motion:clickAction="transitionToEnd"/>
    
    1. That is the namespace I am using, as well as the namespaced used in examples I've seen.

    Just ran into the same issue today. I was able to intercept the click by using setOnTouchListener instead of setOnClickListener in my code.

    rateUsButton.setOnTouchListener { _, event ->
        if (event.action == MotionEvent.ACTION_UP) {
            // handle the click
        }
        false
    }
    

    I know this solution isn't the best but I didn't find another option. Returning false means the touch was not handled here and thus will be handled by the motion layout.

    0 讨论(0)
  • 2021-02-13 19:22

    Here is simple solution:

    Just add this fun:

     @SuppressLint("ClickableViewAccessibility")
    fun View.setOnClick(clickEvent: () -> Unit) {
        this.setOnTouchListener { _, event ->
            if (event.action == MotionEvent.ACTION_UP) {
                clickEvent.invoke()
            }
            false
        }
    }
    

    This is how you use it:

    nextButton.setOnClick {
            //Do something 
    }
    
    0 讨论(0)
  • 2021-02-13 19:24

    In general if you need a callback you probably will want to control the animation yourself. So if you are adding an onClick you should call the transition yourself.

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

    The intent was is useful what the developer does not care. hide/reveal of ui elements etc. or for testing before you get to wiring up the callbacks.

    0 讨论(0)
  • 2021-02-13 19:28

    You can also just handle the click programmatically from the beginning by removing

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

    altogether. Also it is easy to see whether or not your view is expanded by checking the progress of your transition. So you can programmatically handle it in your java/kotlin file with

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

    This way, it will check if the transition is in the state where it has not occurred (progress will be 0.0) and transition, otherwise, it will do nothing.

    0 讨论(0)
提交回复
热议问题