当前位置: 首页 > 知识库问答 >
问题:

如何同步容器内动态水平滚动视图的滚动视图位置?

丌官嘉勋
2023-03-14

在我的一个活动中有一个父容器,它调用由一个水平scrollview组成的子容器作为对象之一。有点像recyclerview,其中放置了行对象,有一个由水平滚动视图组成的公共行/项布局。

我的目标是同步horizontalscrollview的位置,这样,当我在其中一个对象上从位置1水平滚动到位置2时,包含HorizonalScrollview的所有其他项目都会从位置1更新到位置2。

这是我的主容器代码:(活动代码)

 for (int index = 0; index < roomCount; index++) {
        Room r2 = ((LobbyReservationRowView) container.getChildAt(index))
                .getRoom();
        // Log.d("Lobby", "sorting: " + r.getName() + ":" + r.isFree() +
        // " -- " + r2.getName() + ":" + r2.isFree());

        if (r.equals(r2)) {
            Log.d("LobbyActivity", "duplicate room -- " + r.getEmail());
            // XXX: minor logic error; same room
            // someone else requested also an update, and we got rooms twice
            container.removeViewAt(index);
            container.addView(v, index);
            added = true;
            break;
        } else if (roomCmp.compare(r, r2) < 0) {
            container.addView(v, index);
            added = true;

            break;
        }

    }
    if (!added) {
        container.addView(v);

    }

其中container是包含以下布局作为其子布局的布局:(上面的代码迭代这个布局以生成后续行)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:orientation="vertical"
    android:gravity="center_vertical">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:background="#232527"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:layout_height="109dp">
        <ImageView
            android:id="@+id/roomDefaultIcon"
            android:layout_width="116dp"
            android:layout_height="82dp"
            android:src="@drawable/75"
            android:contentDescription="@string/default_room_icon_content_description" />
            <LinearLayout
                android:id="@+id/titleLayout"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|center"
                android:layout_toEndOf="@id/roomDefaultIcon"
                android:layout_marginStart="16dp"
                android:orientation="vertical">

                <TextView
                    android:id="@+id/roomNameLabel"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/white"
                    android:layout_marginTop="20dp"
                    android:textStyle="bold"
                    android:textSize="14sp"
                    android:text="@string/tech_room" />

                <TextView
                    android:id="@+id/roomInfoLabel"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:textColor="@color/TextInfoColor"
                    android:visibility="gone"
                    android:text="(42 persons)" />
            </LinearLayout>
            <HorizontalScrollView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_below="@+id/roomDefaultIcon"
                android:id="@+id/horizontal_timebar_view"
                android:fillViewport="true">
                <com.roombooking.androidview.TimeBarView
                    android:id="@+id/mainTimeBarView"
                    android:layout_width="wrap_content"
                    android:layout_height="50dp"
                    android:orientation="horizontal"
                    >
                    <Button android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Button One"
                        android:visibility="invisible"/>
                    <Button android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Button Two"
                        android:visibility="invisible"/>
                    <Button android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Button Three"
                        android:visibility="invisible"/>
                    <Button android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Button Four"
                        android:visibility="invisible"/>


                </com.roombooking.androidview.TimeBarView>
            </HorizontalScrollView>
        </RelativeLayout>

    </LinearLayout>



    <ViewSwitcher
        android:id="@+id/modeSwitcher"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center_vertical"
        android:inAnimation="@animator/fadein"
        android:outAnimation="@animator/fadeout">

        <LinearLayout
            android:id="@+id/normalMode"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:layout_marginBottom="10dp"
            android:layout_marginEnd="0dp"
            android:layout_marginRight="0dp"
            android:layout_marginTop="10dp"
            android:orientation="horizontal"
            android:visibility="visible"
            android:weightSum="9" >

            <Button
                android:id="@+id/bookNowButton"
                android:layout_width="100dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_weight="3"
                android:layout_marginStart="10dp"
                android:background="@drawable/button_background"
                android:focusable="true"
                android:text="@string/book_now"
                android:textColor="@android:color/white"
                android:layout_marginLeft="10dp" />

            <TextView
                android:id="@+id/roomStatusLabel"
                android:layout_width="0dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical"
                android:layout_marginLeft="20dp"
                android:layout_marginStart="20dp"
                android:layout_weight="5"
                android:minWidth="100dp"
                tools:text="&lt;status&gt;" />

            <Button
                android:id="@+id/calendarButton"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_gravity="center_vertical|start"
                android:background="@drawable/calendar_small_grey"
                android:focusable="true" />


        </LinearLayout>


        <LinearLayout
            android:id="@+id/bookingMode"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_gravity="center_vertical"
            android:gravity="center_vertical"
            android:orientation="vertical"
            android:paddingBottom="8dp">

            <ImageButton
                android:id="@+id/cancelButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="top|end"
                android:layout_marginEnd="10dp"
                android:layout_marginRight="10dp"
                android:layout_marginTop="10dp"
                android:background="@drawable/close_button_states"
                android:contentDescription="@string/cancel_reservation" />

            <com.roombooking.android.view.CustomTimeSpanPicker2
                android:id="@+id/timeSpanPicker2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginBottom="16dp" />

            <AutoCompleteTextView
                android:id="@+id/autoCompleteTextView1"
                android:layout_width="230dp"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginBottom="10dp"
                android:layout_marginLeft="10dp"
                android:layout_marginRight="10dp"
                android:layout_marginTop="10dp"
                android:completionHint="Your name"
                android:completionThreshold="2"
                android:hint="@string/hint_your_name"
                android:imeOptions="actionDone"
                android:inputType="textCapWords|textFilter"
                android:lines="1"
                android:maxLines="1"
                android:textColor="@color/button_color"
                android:textColorHint="@color/CalendarWeekTextColor"/>

            <TextView
                android:layout_gravity="center"
                android:id="@+id/hintText"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:visibility="gone"
                android:text="@string/hintText"
                android:textColor="@color/CalendarWeekTextColor"/>

            <Button
                android:id="@+id/reserveButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:layout_marginBottom="10dp"
                android:layout_marginTop="10dp"
                android:background="@drawable/button_background"
                android:focusable="true"
                android:text="@string/button_reserve"
                android:textColor="@android:color/white" />
            <TextView
                android:id="@+id/newRoomStatusLabel"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_gravity="center_vertical|start"
                android:layout_marginLeft="20dp"
                android:layout_marginStart="20dp"
                android:layout_weight="5"
                android:textColor="@android:color/black"
                android:minWidth="100dp"
                 />

            <Button
                android:id="@+id/newCalendarButton"
                android:layout_width="24dp"
                android:layout_height="24dp"
                android:layout_gravity="center_vertical|end"
                android:background="@drawable/calendar_small_grey"
                android:focusable="true" />
        </LinearLayout>
    </ViewSwitcher>
</LinearLayout>

我的焦点是包含时间条的水平滚动视图,它的位置为1到10。例如,如果我滚动到位置5,接下来的行的滚动条位置也应为5,但我无法同步它们。知道我的代码中可能缺少什么吗?仅供参考,以下是LobbyReservationRowView类代码片段:

public class LobbyReservationRowView extends FrameLayout implements
        OnClickListener, OnItemClickListener, HorizontalScrollView.OnScrollChangeListener {

    @BindView(R.id.horizontal_timebar_view)
    HorizontalScrollView mHorizontalTimeBarView;

 @Override
    public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

        mHorizontalTimeBarView.scrollTo(mHorizontalTimeBarView.getScrollX(),0);
    }

}

如果需要,很高兴分享整个示例项目

共有1个答案

宰父德馨
2023-03-14

您可以从Android Architecture Components实现与LiveData的同步滚动。声明一个接口

interface LobbyReservationHSVListener{
        void updateScrollPosition(int scrollX);
    }

声明一个MutableLiveData变量并在您的活动中实现LobbyReservationHSVListener,如下所示:

public class HorizontalActivity extends AppCompatActivity implements
        LobbyReservationHSVListener {

    MutableLiveData<Integer> hsvPosition = new MutableLiveData<Integer>();

    @Override
    public void updateScrollPosition(int scrollX) {
        hsvPosition.setValue(scrollX);
    }
}

在活动中的onCreate中,开始观察您声明的MutableLiveData。每当其值发生变化时,循环遍历容器的所有子视图并更新其滚动位置。

hsvPosition.observe(this,new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                for(int i=0; i<container.getChildCount();i++){
                    HorizontalScrollView hsv = container.getChildAt(i).findViewById(R.id.horizontal_timebar_view);
                    hsv.smoothScrollTo(integer,0);
                }
            }
        });

在LobbyReservationRowView中创建一个函数来设置LobbyReservationHSVListener对象,并在滚动更改时调用updateScrollPosition。

public class LobbyReservationRowView extends FrameLayout implements
        OnClickListener, OnItemClickListener, HorizontalScrollView.OnScrollChangeListener {

    private LobbyReservationHSVListener hsvUpdateListener;

    @BindView(R.id.horizontal_timebar_view)
    HorizontalScrollView mHorizontalTimeBarView;

    public void setHSVUpdateListener(LobbyReservationHSVListener hsvUpdateListener){
        this.hsvUpdateListener = hsvUpdateListener;
    }

 @Override
    public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

        hsvUpdateListener.updateScrollPosition(scrollX);
    }

}

不要忘记在将 LobbyReservationRowView 对象添加到容器时调用 setHSVUpdateListener(this)

你应该得到这样的东西:

 类似资料:
  • 我有一个水平ScrollView,它有两个元素:CardView和水平RecycerView。所以,当用户水平滚动时,我希望这两个元素滚动。 我想有这样的东西:Goal,橙色的线是CardView,黄色的线是RecycerView。当用户滚动时,两个元素滚动,如下所示:Scrolled Goal。 现在在我的应用程序中,当用户滚动时,只有RecycerView滚动。CardView保持在他的位置。

  • 所以我在垂直ScrollView中有一个水平回收器视图。我的布局中的所有内容都显示得很好,并且都按照我想要的方向滚动,并且它做得很好。 我唯一的问题是,RecyclerView位于ScrollView中其他内容的下方,当RecyclerViewer部分可见时,它会在启动时将RecyclerView的底部与屏幕的底部对齐。这意味着RecyclerView上方的内容被推离屏幕。 有谁知道为什么会发生这

  • 我在类似的问题中搜索过,试过几个答案都没有解决..我有显示城市名称和一些数据的水平回收器视图,问题是我在主回收器视图适配器中的每个位置放置了如下图所示的画布条形图或RV图表,为了水平滚动该图表,我将图表放在水平滚动视图中,以便在从右向左滚动该图表时查看长水平方向上的图表数据,反之亦然,但实际上它并不水平滚动,只有主回收器视图水平滚动到 当触摸它时显示城市,当触摸它滚动(冻结)时RV内的图表没有滚动

  • 我在Scrollview中有Recyclerview 现在,滚动时,layoutStaticContent保持固定在顶部

  • 我在ViewPager中的NestedScrollView中有一个水平的RecyclerView。现在当我尝试滚动RecyclerView时,有时它滚动,但有时只有ViewPager滚动。 这就是我的RecyclerView XML的样子: 到目前为止,我所尝试的,正如你所看到的,我写了一个自定义的viewpager。我尝试告诉ViewPager,如果滚动来自RecyclerView,它就不能滚动

  • 利用UIScrollView实现视差滚动效果。在demo中,滑动ScrollView,背景图和文字的滚动速度不一样。直接用ScrollView 的协议,对其子视图的坐标进行随机系数比例的位置移动修正,从而实现视差滚动效果。没有用其他的框架,代码简单。 作者说:原创Demo 转载请注明出处。 [Code4App.com]