如何使 ScrollView 中的项目位于屏幕中央

How to make an item in a ScrollView be positioned in the center of the screen

我在一个 HorizontalScrollView 中有三个 CardView,我希望中间的一个位于屏幕中央(就好像用户通过滑动来找到它一样)。我如何在 XML 中或以编程方式执行此操作?

XML布局:

<HorizontalScrollView
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="16dp"
    android:layout_marginTop="8dp"
    android:layout_marginEnd="16dp"
    android:scrollbars="none"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/culture_toolbar">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <androidx.cardview.widget.CardView
            android:id="@+id/one"
            android:layout_width="300dp"
            android:layout_height="300dp"
            android:layout_marginEnd="10dp"
            app:cardCornerRadius="12dp">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                android:src="@drawable/beach_bg_placeholder" />

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:id="@+id/two"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:cardCornerRadius="12dp">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                android:src="@drawable/beach_bg_placeholder" />

        </androidx.cardview.widget.CardView>

        <androidx.cardview.widget.CardView
            android:id="@+id/three"
            android:layout_width="300dp"
            android:layout_height="300dp"
            app:cardCornerRadius="12dp">

            <ImageView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:scaleType="fitXY"
                android:src="@drawable/beach_bg_placeholder" />

        </androidx.cardview.widget.CardView>
    </LinearLayout>
</HorizontalScrollView>

这是我想要的结果:

您是否尝试过在 LinearLayout 中使用 layout_gravity

android:layout_gravity="center"

添加前layout_gravity:center
查看结果(蓝图视图):

<LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

添加后layout_gravity:center
查看结果(蓝图视图):

<LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_gravity="center">

How do i do that in xml preferably?

AFAIK 使用 XML 只有那是不可能的

How to make an item in a ScrollView be positioned in the center of the screen

我建议您使用 carousel layout 而不是 HorizontalScrollView

你可以carousel layout using ViewPager and using RecyclerView

查看以下 carousel layout

的好文章

所以我认为您无法在 xml 中完成。

我的建议是用代码来完成。因此,在 Activity 中的 setContentView() 或 Fragment 中的 onViewCreated() 之后,您可以测量整个滚动视图的宽度,将其除以 2,如果不这样做,则使用方法 smoothScrollBy(int dx, int dy) of your horizontalScrollView, or scrollBy(int dx, int dy)让它动起来。

要获得滚动视图的宽度,您可以按照此 answer。只需确保将正确的单位传递给方法,像素、dps 等。

如果您需要转换单位,那么您可以使用 this.

我和你有同样的任务,在滚动视图中将项目居中

如果只是改变布局滚动视图我就做了

尝试将滚动视图替换为

https://github.com/yarolegovich/DiscreteScrollView

  <com.yarolegovich.discretescrollview.DiscreteScrollView
  android:id="@+id/picker"
  android:layout_width="match_parent"
  android:layout_height="wrap_content"
  app:dsv_orientation="horizontal|vertical" />

如果成功请告诉我

对于此行为,您应该使用 ViewPagerViewPager2(基本上是包含 SnapHelperRecyclerView

我将展示如何使用常规 ViewPager

所以轮播的寻呼机设置应该是这样的

pager.apply{
            // Set current item to the middle page so we can fling to both
            // directions left and right
            currentItem = 1

            // Necessary or the pager will only have one extra page to show
            // make this at least however many pages you can see
            offscreenPageLimit = 3

            // Set margin for pages as a negative number, so a part of next and
            // previous pages will be showed
            // Calculate here a value you need
            pageMargin = -((3f / 4f) * App.screenWidth).toInt()
        }

虽然改编应该实施ViewPager.PageTransformer

class CarouselPagerAdapter : PagerAdapter(), ViewPager.PageTransformer {

...

  companion object {
        val NO_SCALE = 1.0f
        val SMALL_SCALE_DOWN = 0.1f
        val DIFF_SCALE = NO_SCALE - SMALL_SCALE_DOWN

        val FULL_OPACITY = 255
        val LOW_OPACITY = 5
        val DIFF_OPACITY = FULL_OPACITY - LOW_OPACITY

        val NO_TRANSLATION = 0f
        val TRANSLATION_Y = 100f
        val DIFF_TRANSLATION_Y = TRANSLATION_Y - NO_TRANSLATION
    }

    override fun transformPage(page: View, position: Float) {
        val scalableLayout = page.item_child_wrapper
        val animatableLayout = page.child_name_wrapper
        var scale = NO_SCALE
        var opacity = FULL_OPACITY
        var translationY = NO_TRANSLATION
        if (position > 0) {
            scale -= position * DIFF_SCALE
            opacity -= (position * DIFF_OPACITY).toInt()
            translationY -= (position * DIFF_TRANSLATION_Y)
        } else {
            scale += position * DIFF_SCALE
            opacity += (position * DIFF_OPACITY).toInt()
            translationY += (position * DIFF_TRANSLATION_Y)
        }
        if (scale < 0) scale = 0f
        if (opacity < 0) opacity = 0
        if (opacity > 255) opacity = 255
        scalableLayout.setScale(scale)
        scalableLayout.setOpacity(opacity)
        animatableLayout.setScale(scale)
        animatableLayout.setTranslation(0f, translationY)
    }



}

这是我的旧代码,因此应该以某种方式对其进行现代化处理,它也适用于元素的不透明度和过渡 - 但我想您会想出如何使用它。

希望对您有所帮助。