API级别23以下的AnimationSet playTogether()不能同时播放ObjectAnimator的一部分

时间:2019-01-23 08:56:42

标签: android kotlin android-animation objectanimator

当我在API级别23上设置多个ObjectAnimatorplayTgether()时,不能同时播放动画,但是在API级别24上我可以按照预期工作。

但是,当我将每个ObjectAnimator设置为play()时,动画在模拟器API 23和24上都可以正常工作。

有人可以告诉我问题的原因吗?
我将在后面附加GIF和代码。

动画

在API级别23模拟器上
api_23.gif:
api_23.gif

在API级别24模拟器上
api_24.gif:
api_24.gif

代码

activity_text.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".presentation.view.activity.TestActivity">
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="50dp"
        android:layout_height="50dp"
        android:background="@color/browser_actions_title_color" />
</RelativeLayout>
TestActivity.kt
class TestActivity: AppCompatActivity() {

    private val TRANSLATION_X_START = 0f
    private val TRANSLATION_X_END = 500f
    private val TRANSLATION_Y_START = 0f
    private val TRANSLATION_Y_END = 500f
    private val DELAY_TRANSLATION = 2000
    private val TRANSLATE_ANIMATION_TIME = 800

    private val DEFAULT_SCALE = 1f
    private val MAX_SCALE = 3f
    private val DELAY_SCALE = 2000
    private val SCALE_ANIMATION_TIME = 800

    private val MIN_ALPHA = 0f
    private val MAX_ALPHA = 255f
    private val DELAY_ALPHA = 2250
    private val ALPHA_ANIMATION_TIME = 800

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_test)
        startAnimation(imageView)
    }

    private fun startAnimation(view: View) {

        val animationSet  = AnimatorSet()

        val animatorX = ObjectAnimator.ofFloat(view, "x", TRANSLATION_X_START, TRANSLATION_X_END)
        animatorX.interpolator = AccelerateDecelerateInterpolator()
        animatorX.duration = TRANSLATE_ANIMATION_TIME.toLong()
        animatorX.startDelay = DELAY_TRANSLATION.toLong()

        val animatorY = ObjectAnimator.ofFloat(view, "y", TRANSLATION_Y_START, TRANSLATION_Y_END)
        animatorY.interpolator = AccelerateDecelerateInterpolator()
        animatorY.duration = TRANSLATE_ANIMATION_TIME.toLong()
        animatorY.startDelay = DELAY_TRANSLATION.toLong()

        val animatorScaleX = ObjectAnimator.ofFloat(view, "scaleX", DEFAULT_SCALE, MAX_SCALE)
        animatorScaleX.interpolator = LinearInterpolator()
        animatorScaleX.duration = SCALE_ANIMATION_TIME.toLong()
        animatorScaleX.startDelay = DELAY_SCALE.toLong()

        val animatorScaleY = ObjectAnimator.ofFloat(view, "scaleY", DEFAULT_SCALE, MAX_SCALE)
        animatorScaleY.interpolator = LinearInterpolator()
        animatorScaleY.duration = SCALE_ANIMATION_TIME.toLong()
        animatorScaleY.startDelay = DELAY_SCALE.toLong()

        val animatorAlpha = ObjectAnimator.ofFloat(view, "alpha", MAX_ALPHA, MIN_ALPHA)
        animatorAlpha.interpolator = LinearInterpolator()
        animatorAlpha.duration = ALPHA_ANIMATION_TIME.toLong()
        animatorAlpha.startDelay = DELAY_ALPHA.toLong()

        animationSet.playTogether(animatorX, animatorScaleX, animatorY, animatorScaleY, animatorAlpha)

        animationSet.addListener(object : Animator.AnimatorListener {
            override fun onAnimationEnd(animation: Animator) {
            }
            override fun onAnimationStart(animation: Animator) {
            }
            override fun onAnimationCancel(animation: Animator) {}

            override fun onAnimationRepeat(animation: Animator) {}
        })

        animationSet.start()
    }
}

代码对api23和api24都适用

animationSet.play(animatorX)
animationSet.play(animatorScaleX)
animationSet.play(animatorY)
animationSet.play(animatorScaleY)
animationSet.play(animatorAlpha)

1 个答案:

答案 0 :(得分:0)

我也遇到了同样的问题,显然,这是SDK上的一个BUG。我的解决方法是仅在较高的API级别上使用动画器集,并在较低的API级别上处理单独的控制

public class BlogRecyclerAdapter extends RecyclerView.Adapter<BlogRecyclerAdapter.ViewHolder> {

private OnItemClickListner listner;

public List<BlogPost> blog_list;

private FirebaseFirestore firebaseFirestore;
private FirebaseDatabase firebaseDatabase;
private FirebaseFirestore db = FirebaseFirestore.getInstance();

private DatabaseReference mUserDatabase;
private FirebaseUser mCurrentUser;

private Context mContext;

public BlogRecyclerAdapter(Context context, List<BlogPost> blog_list) {
    mContext = context;
    this.blog_list = blog_list;
}

@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.blog_list_item, parent, false);
    firebaseFirestore = FirebaseFirestore.getInstance();
    return new ViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull final ViewHolder holder, int position) {

    CollectionReference mUsersDB = db.collection("Posts");


    String desc_data = blog_list.get(position).getDesc();
    holder.setDescText(desc_data);

    String image_url = blog_list.get(position).getImage_url();
    holder.setBlogImage(image_url);

    long millisecond = blog_list.get(position).getTimestamp().getTime();
    String dateString = DateFormat.format("MM/dd/yyyy", new Date(millisecond)).toString();
    holder.setTime(dateString);

    holder.parentLayout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {

            Intent intent = new Intent(mContext, Confirmation_Activity.class);
            mContext.startActivity(intent);
        }
    });

}

@Override
public int getItemCount() {
    return blog_list.size();
}

public class ViewHolder extends RecyclerView.ViewHolder {

    public Context mContext;
    ConstraintLayout parentLayout;
    private View mView;
    private TextView descView;
    private ImageView blogPostView;
    private TextView blogDate;
    private TextView blogUserName;
    private CircleImageView blogUserImage;
    private StorageReference mImageStorage;
    private DocumentSnapshot documentSnapshot;

    @SuppressLint("ResourceType")
    public ViewHolder(final View itemView) {
        super(itemView);
        mView = itemView;
        parentLayout = itemView.findViewById(R.id.Main_Blog_Post);

        itemView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = getAdapterPosition();

                String id = documentSnapshot.getId();
                DocumentReference docRef = db.collection("Posts").document(id);
                String postID = docRef.toString();
                Toast.makeText(mContext,postID,Toast.LENGTH_SHORT).show();

                if (position != RecyclerView.NO_POSITION && listner != null){

                    listner.onItemClick(get);
                }

            }
        });

    }


    public void setDescText(String descText) {
        descView = mView.findViewById(R.id.blog_desc);
        descView.setText(descText);

    }

    public void setUserData(String downloadUrl, String name) {

        mImageStorage = FirebaseStorage.getInstance().getReference();

        mCurrentUser = FirebaseAuth.getInstance().getCurrentUser();
        final String current_uid = mCurrentUser.getUid();

        mUserDatabase = FirebaseDatabase.getInstance().getReference().child("Users").child(current_uid);
        mUserDatabase.keepSynced(true);

        mUserDatabase.addValueEventListener(new ValueEventListener() {
            @Override
            public void onDataChange(DataSnapshot dataSnapshot) {

                String name = Objects.requireNonNull(dataSnapshot.child("name").getValue()).toString();

                StorageReference filepath = mImageStorage.child("profile_images").child(current_uid + (".jpeg"));
                Log.d("heere", "S");

                // This gets the download url async
                filepath.getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
                    @Override
                    public void onSuccess(Uri uri) {

                        //The download url
                        final String downloadUrl =
                                uri.toString();
                        Log.d("tag", downloadUrl);
                        if (!downloadUrl.equals("default")) {

                            //  Glide.with(getApplicationContext()).load(downloadUrl).into(mDisplayImage);
                            Glide.with(itemView.getContext()).load(downloadUrl).into(blogUserImage);

                        }
                    }
                }).addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        // Toast.makeText(getApplicationContext(), "Something went wrong", Toast.LENGTH_SHORT).show();
                    }
                });
                //Toast.makeText(getApplicationContext(), image, Toast.LENGTH_SHORT).show();

                Log.d("value", dataSnapshot.getValue().toString());
                Log.d("key", dataSnapshot.getKey());
            }

            @Override
            public void onCancelled(DatabaseError databaseError) {

            }
        });


    }

    public void setTime(String date) {

        blogDate = mView.findViewById(R.id.blog_date);
        blogDate.setText(date);

    }

    public void setBlogImage(final String downloadUri) {

        blogPostView = mView.findViewById(R.id.blog_image);
        Glide.with(itemView.getContext()).load(downloadUri).into(blogPostView);


    }
}

public interface OnItemClickListner{
    void onItemClick(DocumentSnapshot documentSnapshot, int position);

}

public void setOnItemClickListner(OnItemClickListner listner){
    this.listner = listner;

}
}