Android 添加 scrollview 时会显示多个视图,但只有在删除 scrollview 和实现自定义滚动时才首先显示

Android multiple views show when scrollview is added but only first shows if scrollview removed and custom scrolling implemented

我已将片段添加到线性布局,其中每个 child 片段视图占据整个屏幕。现在我必须实现滚动功能,以便我可以浏览它们。我试图添加一个 scrollView(水平)并且它显示了所有 children 但由于某些问题我无法使用 scrollview。因此,为了滚动,我使用了以下滚动良好的代码,但并未显示所有 children,即使滚动后也只有第一个可见:

/**
     * A function to scroll towards the left.
     */
    public void scrollLeft(){
        LinearLayout layout = findViewById(R.id.viewList);
        int x = getResources().getDisplayMetrics().widthPixels;
        layout.scrollBy(-x, 0); // scroll by the amount of the screen's width
    }


    /**
     * A function to scroll towards the right.
     */
    public void scrollRight(){
        LinearLayout layout = findViewById(R.id.viewList);
        int x = getResources().getDisplayMetrics().widthPixels;
        layout.scrollBy(x, 0); // scroll by the amount of the screen's width
        }

我什至尝试滚动 ConstraintLayout(基本布局),但结果也一样。 这是我的 activity_test.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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:id="@+id/TestRoot"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".TestActivity">


    <LinearLayout
        android:id="@+id/viewList"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:baselineAligned="false"
        android:orientation="horizontal"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"></LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

这是我用来向 LinearLayout 添加片段的代码,它仅在 onCreate 方法中调用:

FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();

for (int i = 0; i < results.length; i++) {
    ResultFragment result = new ResultFragment();         
    // configuring the fragment
    // ....


    LinearLayout l = new LinearLayout(this);
    l.setId(View.generateViewId());
    transaction.add(l.getId(), result, "result-"+i);
    ((LinearLayout)findViewById(R.id.viewList)).addView(l,i);
    findViewById(R.id.viewList).invalidate();
}
transaction.commit();

没有反应但没有问题,我自己找到了解决方案。 所以我做的很简单。我创建了一个自定义的 ScrollView,它覆盖了 onTouchEvent 函数,实现了我自己的滚动机制,并将我的 linearlayout 放在这个 scrollView 和 kaboom 中!有效。新的 ScrollView 看起来像这样:

package com.nalin.test;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.HorizontalScrollView;


public class LockedHScrollView extends HorizontalScrollView {

    /** The variables used to detect left-right swipes*/
    float x1, x2;
    /** variable to check whether the swipes made were valid (distance was large enough) */
    final float distance = 200;



    public LockedHScrollView(Context context){super(context);}
    public LockedHScrollView(Context context, AttributeSet attrs){super(context, attrs);}
    public LockedHScrollView(Context context, AttributeSet attrs, int defStyleAttr){super(context, attrs, defStyleAttr);}


    /**
     * A function to scroll towards the left.
     */
    public void scrollLeft(){
        int x = getResources().getDisplayMetrics().widthPixels;
        scrollBy(-x, 0); // scroll by the amount of the screen's width
    }


    /**
     * A function to scroll towards the right.
     */
    public void scrollRight(){
        int x = getResources().getDisplayMetrics().widthPixels;
        scrollBy(x, 0); // scroll by the amount of the screen's width
    }


    /**
     * A function to check swipes for scrolling between multiple result fragments.
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction()==MotionEvent.ACTION_DOWN){
            x1 = event.getX();
        }else if (event.getAction() == MotionEvent.ACTION_UP){
            x2 = event.getX();
            if ((x2-x1)>0){             //Right swipe
                if (x2-x1 >= distance){        // Validate that the swipe was long enough
                    scrollLeft();
                }
            }else if((x1-x2)>0){        // Left swipe
                if ((x1-x2)>=distance){        // Validate that the swipe was long enough
                    scrollRight();
                }
            }
        }
        return true;
    }
}