Android中ScrollView和RecylCerView的交互
我正在尝试创建一个垂直和水平滚动日历,当你垂直滚动时,它是按一天中的小时滚动,当你水平滚动时,它是按一个月中的天滚动。此链接包含我所需的几乎正常工作的gif: 如果您注意到在gif的后半部分附近,在垂直滚动之后,正文和日标题的水平滚动已同步,但一旦您将列表移回开始或结束,它们将再次同步 基本上,我这里有两个水平滚动的回收器视图,它们彼此滚动,如下所述: 实际执行情况:Android中ScrollView和RecylCerView的交互,android,Android,我正在尝试创建一个垂直和水平滚动日历,当你垂直滚动时,它是按一天中的小时滚动,当你水平滚动时,它是按一个月中的天滚动。此链接包含我所需的几乎正常工作的gif: 如果您注意到在gif的后半部分附近,在垂直滚动之后,正文和日标题的水平滚动已同步,但一旦您将列表移回开始或结束,它们将再次同步 基本上,我这里有两个水平滚动的回收器视图,它们彼此滚动,如下所述: 实际执行情况: public class CalendarFragment extends BaseFragment { @BindVie
public class CalendarFragment extends BaseFragment {
@BindView(R.id.dayHeaderView)
RecyclerView dayHeaderView;
@BindView(R.id.dayBodyView)
RecyclerView dayBodyView;
private static final String TAG = CalendarFragment.class.getSimpleName();
private DayHeaderAdapter dayHeaderAdapter = new DayHeaderAdapter();
private DayBodyAdapter dayBodyAdapter = new DayBodyAdapter();
private final RecyclerView.OnScrollListener dayHeaderOSL = new SelfRemovingOnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
dayBodyView.scrollBy(dx, dy);
Log.e(TAG, "onScrolled: dayHeader x : " + dx + " y : " + dy );
}
};
private final RecyclerView.OnScrollListener dayBodyOSL = new SelfRemovingOnScrollListener() {
@Override
public void onScrolled(@NonNull final RecyclerView recyclerView, final int dx, final int dy) {
super.onScrolled(recyclerView, dx, dy);
dayHeaderView.scrollBy(dx, dy);
Log.e(TAG, "onScrolled: function x : " + dx + " y : " + dy );
Log.e(TAG, "onScrolled: dayHeader x : " + dayHeaderView.getX() + " y : " + dayHeaderView.getY() );
Log.e(TAG, "onScrolled: dayBody x : " + dayBodyView.getX() + " y : " + dayBodyView.getY() );
}
};
public CalendarFragment() {}
public static CalendarFragment create(boolean showScheduler) {
return new CalendarFragment();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_calendar, container, false);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getComponent().inject(this);
ButterKnife.bind(this, view);
LinearLayoutManager llm = new LinearLayoutManager(getContext());
llm.setOrientation(LinearLayoutManager.HORIZONTAL);
LinearLayoutManager llm2 = new LinearLayoutManager(getContext());
llm2.setOrientation(LinearLayoutManager.HORIZONTAL);
dayHeaderView.setLayoutManager(llm2);
dayHeaderView.setAdapter(dayHeaderAdapter);
dayHeaderAdapter.displayHeader();
dayHeaderView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
private int mLastX;
@Override
public boolean onInterceptTouchEvent(@NonNull final RecyclerView rv, @NonNull final
MotionEvent e) {
Log.d("debug", "Day Header: onInterceptTouchEvent");
final Boolean ret = rv.getScrollState() != RecyclerView.SCROLL_STATE_IDLE;
if (!ret) {
onTouchEvent(rv, e);
}
return Boolean.FALSE;
}
@Override
public void onTouchEvent(@NonNull final RecyclerView rv, @NonNull final MotionEvent e) {
Log.d("debug", "Day Header: onTouchEvent");
final int action;
if ((action = e.getAction()) == MotionEvent.ACTION_DOWN && dayBodyView
.getScrollState() == RecyclerView.SCROLL_STATE_IDLE) {
mLastX = rv.getScrollX();
dayBodyView.scrollBy(rv.getScrollX(), rv.getScrollY());
rv.addOnScrollListener(dayHeaderOSL);
}
else {
if (action == MotionEvent.ACTION_UP && rv.getScrollX() == mLastX) {
rv.removeOnScrollListener(dayHeaderOSL);
}
}
}
@Override
public void onRequestDisallowInterceptTouchEvent(final boolean disallowIntercept) {
Log.d("debug", "Day Header: onRequestDisallowInterceptTouchEvent");
}
});
CalenderLayoutManager clm = new CalenderLayoutManager();
clm.setTotalColumnCount(10);
dayBodyView.setLayoutManager(llm);
dayBodyView.setAdapter(dayBodyAdapter);
dayBodyAdapter.displayBody();
dayBodyView.addOnItemTouchListener(new RecyclerView.OnItemTouchListener() {
private int mLastX;
@Override
public boolean onInterceptTouchEvent(@NonNull final RecyclerView rv, @NonNull final
MotionEvent e) {
Log.d("debug", "Day Body: onInterceptTouchEvent");
final Boolean ret = rv.getScrollState() != RecyclerView.SCROLL_STATE_IDLE;
if (!ret) {
onTouchEvent(rv, e);
}
return Boolean.FALSE;
}
@Override
public void onTouchEvent(@NonNull final RecyclerView rv, @NonNull final MotionEvent e) {
Log.d("debug", "Day Body: onTouchEvent");
final int action;
if ((action = e.getAction()) == MotionEvent.ACTION_DOWN && dayHeaderView
.getScrollState
() == RecyclerView.SCROLL_STATE_IDLE) {
mLastX = rv.getScrollX();
dayHeaderView.scrollBy(rv.getScrollX(), rv.getScrollY());
rv.addOnScrollListener(dayBodyOSL);
}
else {
if (action == MotionEvent.ACTION_UP && rv.getScrollX() == mLastX) {
rv.removeOnScrollListener(dayBodyOSL);
}
}
}
@Override
public void onRequestDisallowInterceptTouchEvent(final boolean disallowIntercept) {
Log.d("debug", "Day Body: onRequestDisallowInterceptTouchEvent");
}
});
}
public class SelfRemovingOnScrollListener extends RecyclerView.OnScrollListener {
@Override
public final void onScrollStateChanged(@NonNull final RecyclerView recyclerView, final int newState) {
super.onScrollStateChanged(recyclerView, newState);
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
recyclerView.removeOnScrollListener(this);
}
}
}
}
垂直滚动通过列行完成,第二个水平回收器视图的主体包含在滚动视图中。如图所示:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/silver"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:id="@+id/fillable_area_01"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:splitMotionEvents="false">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
<View
android:layout_width="30dp"
android:layout_height="40dp"
android:background="@color/black"/>
<android.support.v7.widget.RecyclerView
android:id="@+id/dayHeaderView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
<ScrollView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:scrollbars="none"
android:splitMotionEvents="false">
<LinearLayout
android:id="@+id/fillable_area_02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:splitMotionEvents="false">
<edu.calendar.ui.HourView
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<android.support.v7.widget.RecyclerView
android:id="@+id/dayBodyView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</ScrollView>
</LinearLayout>
有人知道为什么在使用scrollview之后会出现dsync吗?我能做些什么来修复它?失败或除此之外,是否有更好的方法来实现此设置?标题的行为有时是固定的,有时是可滚动的,这对我来说是个难题,任何建议都将不胜感激
非常感谢你抽出时间