我正在尝试通过使用ConstraintLayout过渡动画通过滑动动画为日历及其下面的列表设置动画。它可以工作,但有时RecyclerView项会出现故障和重叠。是什么原因以及如何解决?
演示:https://gfycat.com/FlowerySelfreliantFennecfox
我使用了以下库:
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
implementation 'com.prolificinteractive:material-calendarview:1.4.3'
implementation 'com.github.pwittchen:swipe-rx2:0.3.0'
Java代码:
private void SetGestures(){
swipe = new Swipe();
swipe.setListener(new SwipeListener() {
@Override
public void onSwipingLeft(MotionEvent event) {
}
@Override
public boolean onSwipedLeft(MotionEvent event) {
return false;
}
@Override
public void onSwipingRight(MotionEvent event) {
}
@Override
public boolean onSwipedRight(MotionEvent event) {
return false;
}
@Override
public void onSwipingUp(MotionEvent event) {
}
@Override
public boolean onSwipedUp(MotionEvent event) {
CollapseCalendar();
return true;
}
@Override
public void onSwipingDown(MotionEvent event) {
}
@Override
public boolean onSwipedDown(MotionEvent event) {
ExpandCalendar();
return true;
}
});
calendarView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
return swipe.dispatchTouchEvent(event);
}
});
}
private void SetRecyclerGestures(){
rvCalendarFragment.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (!calendarCollapsed && newState == SCROLL_STATE_DRAGGING){
CollapseCalendar();
}
}
});
}
private void ExpandCalendar(){
calendarView.state().edit().setCalendarDisplayMode(CalendarMode.MONTHS).commit();
calendarCollapsed = false;
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(getActivity(),R.layout.fragment_calendar_new);
ChangeBounds transition = new ChangeBounds();
transition.setInterpolator(new AnticipateOvershootInterpolator(0.5f));
transition.setDuration(300);
TransitionManager.beginDelayedTransition(consFragmentCalendar,transition);
constraintSet.applyTo(consFragmentCalendar);
}
private void CollapseCalendar(){
calendarView.state().edit().setCalendarDisplayMode(CalendarMode.WEEKS).commit();
calendarCollapsed = true;
ConstraintSet constraintSet = new ConstraintSet();
constraintSet.clone(getActivity(),R.layout.fragment_calendar_new_collapsed);
ChangeBounds transition = new ChangeBounds();
transition.setInterpolator(new AnticipateOvershootInterpolator(0.5f));
transition.setDuration(300);
TransitionManager.beginDelayedTransition(consFragmentCalendar,transition);
constraintSet.applyTo(consFragmentCalendar);
}
fragment_calendar_new.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/consFragmentCalendar">
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:background="@color/grey_500"
android:id="@+id/calendarViewFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.6"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rvCalendarFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />
</android.support.constraint.ConstraintLayout>
fragment_calendar_new_collapsed.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/consFragmentCalendar">
<com.prolificinteractive.materialcalendarview.MaterialCalendarView
android:id="@+id/calendarViewFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toTopOf="@+id/guideline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<android.support.constraint.Guideline
android:id="@+id/guideline"
android:layout_width="1dp"
android:layout_height="wrap_content"
android:orientation="horizontal"
app:layout_constraintGuide_percent="0.2"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/rvCalendarFragment"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/guideline" />
</android.support.constraint.ConstraintLayout>
适配器代码:
public class NewCalendarEventsAdapter extends RecyclerView.Adapter<NewCalendarEventsAdapter.NewCalendarViewHolder>{
private ArrayList<CalendarEvent> events;
public NewCalendarEventsAdapter(ArrayList<CalendarEvent> events) {
this.events = events;
}
@NonNull
@Override
public NewCalendarViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item_calendar_new, parent, false);
return new NewCalendarViewHolder(itemView);
}
@Override
public void onBindViewHolder(@NonNull NewCalendarViewHolder holder, int position) {
CalendarEvent event = events.get(position);
holder.tvCalendarEventDate.setText(event.getStartDate());
holder.tvCalendarEventDate.setBackgroundColor(Color.parseColor(event.getBackgroundColor()));
holder.tvCalendarEventTitle.setText(event.getTitle());
}
@Override
public int getItemCount() {
return events.size();
}
public static class NewCalendarViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener{
TextView tvCalendarEventDate, tvCalendarEventTitle;
public NewCalendarViewHolder(View itemView) {
super(itemView);
tvCalendarEventDate = itemView.findViewById(R.id.tvCalendarEventDate);
tvCalendarEventTitle = itemView.findViewById(R.id.tvCalendarEventTitle);
}
@Override
public void onClick(View v) {
//TODO:
}
}
}
list_item_calendar_new.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
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="wrap_content">
<TextView
android:id="@+id/tvCalendarEventDate"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_margin="8dp"
android:layout_marginBottom="8dp"
android:background="@color/blue_400"
android:gravity="center_horizontal"
android:padding="8dp"
android:textColor="@color/white"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tvCalendarEventTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginBottom="8dp"
android:layout_marginEnd="8dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:maxLines="2"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/tvCalendarEventDate"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>