如何同步容器内动态水平滚动视图的滚动视图位置? [英] How do I synchronize scrollview positions of dynamic horizontal scroll views inside a container?

查看:35
本文介绍了如何同步容器内动态水平滚动视图的滚动视图位置?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

 for (int index = 0; index 

其中容器是包含以下布局的布局,因为它是子布局:(上面的代码迭代此布局以生成后续行)

<线性布局android:layout_width="match_parent"android:layout_height="wrap_content"机器人:方向=垂直"><相对布局android:layout_width="match_parent"机器人:背景=#232527"android:layout_marginStart="16dp"android:layout_marginEnd="16dp"android:layout_height="109dp"><图像视图android:id="@+id/roomDefaultIcon"android:layout_width="116dp"android:layout_height="82dp"android:src="@drawable/75"android:contentDescription="@string/default_room_icon_content_description"/><线性布局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:id="@+id/roomNameLabel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/white"android:layout_marginTop="20dp"android:textStyle="粗体"android:textSize="14sp"android:text="@string/tech_room"/><文本视图android:id="@+id/roomInfoLabel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/TextInfoColor"机器人:可见性=消失"android:text="(42 人)"/></LinearLayout><水平滚动视图android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/roomDefaultIcon"android:id="@+id/horizo​​ntal_timebar_view"android:fillViewport="true"><com.roombooking.androidview.TimeBarViewandroid:id="@+id/mainTimeBarView"android:layout_width="wrap_content"android:layout_height="50dp"机器人:方向=水平"><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按钮一"机器人:可见性=隐形"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按钮二"机器人:可见性=隐形"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按钮三"机器人:可见性=隐形"/><Button android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="按钮四"机器人:可见性=隐形"/></com.roombooking.androidview.TimeBarView></Horizo​​ntalScrollView></RelativeLayout></LinearLayout><视图切换器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"><线性布局android:id="@+id/normalMode"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_vertical"机器人:layout_marginBottom="10dp"android:layout_marginEnd="0dp"机器人:layout_marginRight="0dp"android:layout_marginTop="10dp"机器人:方向=水平"机器人:可见性=可见"android:weightSum="9" ><按钮android:id="@+id/bookNowButton"android:layout_width="100dp"android:layout_height="wrap_content"机器人:layout_gravity="中心"机器人:layout_weight="3"android:layout_marginStart="10dp"android:background="@drawable/button_background"机器人:焦点=真"android:text="@string/book_now"android:textColor="@android:color/white"android:layout_marginLeft="10dp"/><文本视图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"机器人:layout_weight="5"android:minWidth="100dp"工具:文本=<状态&gt;"/><按钮android:id="@+id/日历按钮"android:layout_width="24dp"android:layout_height="24dp"android:layout_gravity="center_vertical|开始"android:background="@drawable/calendar_small_grey"android:focusable="true"/></LinearLayout><线性布局android:id="@+id/bookingMode"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_gravity="center_vertical"机器人:重力=center_vertical"机器人:方向=垂直"android:paddingBottom="8dp"><图像按钮android:id="@+id/cancelButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="顶部|结束"android:layout_marginEnd="10dp"机器人:layout_marginRight="10dp"android:layout_marginTop="10dp"android:background="@drawable/close_button_states"android:contentDescription="@string/cancel_reservation"/><com.roombooking.android.view.CustomTimeSpanPicker2android:id="@+id/timeSpanPicker2"android:layout_width="wrap_content"android:layout_height="wrap_content"机器人:layout_gravity="中心"android:layout_marginBottom="16dp"/><自动完成文本视图android:id="@+id/autoCompleteTextView1"android:layout_width="230dp"android:layout_height="wrap_content"机器人:layout_gravity="中心"机器人:layout_marginBottom="10dp"android:layout_marginLeft="10dp"机器人:layout_marginRight="10dp"android:layout_marginTop="10dp"android:completionHint="你的名字"机器人:完成阈值=2"android:hint="@string/hint_your_name"android:imeOptions="actionDone"android:inputType="textCapWords|textFilter"机器人:线=1"机器人:maxLines =1"android:textColor="@color/button_color"android:textColorHint="@color/CalendarWeekTextColor"/><文本视图机器人:layout_gravity="中心"android:id="@+id/hintText"android:layout_width="wrap_content"android:layout_height="wrap_content"机器人:可见性=消失"android:text="@string/hintText"android:textColor="@color/CalendarWeekTextColor"/><按钮android:id="@+id/reserveButton"android:layout_width="wrap_content"android:layout_height="wrap_content"机器人:layout_gravity="中心"机器人:layout_marginBottom="10dp"android:layout_marginTop="10dp"android:background="@drawable/button_background"机器人:焦点=真"android:text="@string/button_reserve"android:textColor="@android:color/white"/><文本视图android:id="@+id/newRoomStatusLabel"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical|开始"android:layout_marginLeft="20dp"android:layout_marginStart="20dp"机器人:layout_weight="5"android:textColor="@android:color/black"android:minWidth="100dp"/><按钮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>

我的焦点是包含时间条的 Horizo​​ntalScrollView,其位置为 1 到 10.例如,如果我滚动到位置 5,接下来的后续行的滚动条位置也应为 5,但我无法同步他们.知道我的代码中可能缺少什么吗?仅供参考,这里是 LobbyReservationRowView 类代码片段:

 公共类 LobbyReservationRowView 扩展 FrameLayout 实现OnClickListener, OnItemClickListener, Horizo​​ntalScrollView.OnScrollChangeListener {@BindView(R.id.horizo​​ntal_timebar_view)Horizo​​ntalScrollView mHorizo​​ntalTimeBarView;@覆盖public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {mHorizo​​ntalTimeBarView.scrollTo(mHorizo​​ntalTimeBarView.getScrollX(),0);}}

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

解决方案

你可以通过

I have a parent container in one of my activities which make a call to it's child containers consisting of a horizontal scrollview as one of the objects. Sort of like a recyclerview with row objects placed inside where there is a common row/item layout consisting of a horizontal scroll view.

My objective is to sync the positions of the horizontalscrollview such that, when i am scrolling horizontally on one of the objects from position 1 to position 2, all the other items containing horizontal scrollview get updated from position 1 to position 2.

Here's my main container code: (Activity code)

 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);

    }

where container is the layout containing the following layout as it's child:( the above code iterates over this layout to generate subsequent rows)

<?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>

My point of focus is the HorizontalScrollView containing the timebar, which has positions 1 to 10. If I scroll to position 5 for example, the next subsequent rows should have the scrollbar position at 5 aswell, but I am not able to sync them. Any idea what could be missing from my code? Just for reference , here's LobbyReservationRowView class code snippet:

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);
    }

}

Happy to share the entire sample project if need be

解决方案

You can achieve the synchronized scrolling with LiveData from Android Architecture Components. Declare an interface

interface LobbyReservationHSVListener{
        void updateScrollPosition(int scrollX);
    }

Declare a MutableLiveData variable and implement the LobbyReservationHSVListener in your activity like below:

public class HorizontalActivity extends AppCompatActivity implements
        LobbyReservationHSVListener {

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

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

In onCreate in your activity start observing the MutableLiveData you declared. Whenever its value changes, loop through all children views of container and update their scroll positions.

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);
                }
            }
        });

In your LobbyReservationRowView create a function to set the LobbyReservationHSVListener object and call updateScrollPosition whenever scroll changes.

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);
    }

}

Don't forget to call setHSVUpdateListener(this) on your LobbyReservationRowView object whenever adding it to your container

You should get something like this:

这篇关于如何同步容器内动态水平滚动视图的滚动视图位置?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆