Scrollview + Viewpager + conflito de deslizamento de fragmento e reparo de problema de altura

Quando me deparei com essa combinação, verifiquei muitas informações relacionadas. Todos encontraram situações diferentes. Muitas delas não puderam ser implementadas ou não atenderam às necessidades: registre-as aqui e use-as para resolver meu problema: Aninhamento de layout complexo no Android solução de desenvolvimento (ScrollView + TabLayout + ViewPager + RecyclerView) para conflitos_World-CSDN Blog de Huang Qingqing

Organize o que uso: fácil de visualizar

Disposição geral:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    ferramentas:context=".MainActivity" >

    <com.hq.testscrollview.InterceptScrollView
        android:id="@+id/interceptScrollView"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/container_normal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:descendantFocusability="beforeDescendants"
            android:focusable="true"
            android:focusableInTouchMode="true"
            android: orientação="vertical">

            <RelativeLayout
                android:id="@+id/top_info"
                android:layout_width="match_parent"
                android:layout_height="60dp">

                <TextView
                    android:id="@+id/tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_centerInParent="true"
                    android:text="顶部内容模块添加"
                    android:textSize="18sp " />
            </RelativeLayout>

            <android.support.design.widget.TabLayout
                android:id="@+id/tabLayout"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:background="@android:color/white"
                app:tabMode ="fixed"
                app:tabSelectedTextColor="@android:color/black" />
            <!-- O layout do espaço reservado está no estado desaparecido por padrão. Quando o TabLayout é removido, seu estado é alterado para visível, alcançando "espaço reservado" Efeito -->
            <Ver
                android:id="@+id/view_place"
                android:layout_width="match_parent"
                android:layout_height="50dp"
                android:visibilidade = "desapareceu" />

            <com.hq.testscrollview.AutofitViewPager
                android:id="@+id/viewPager"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

        </LinearLayout>
    </com.hq.testscrollview.InterceptScrollView>

    <!-- Layout superior vazio suspenso acima da tela-->
    <LinearLayout
        android:id="@+id/container_top"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:orientation="vertical">

    </LinearLayout>
</RelativeLayout>
Dois códigos de controle personalizados:

classe pública InterceptScrollView estende ScrollView {

    private int lastInterceptX;
    private int lastInterceptY;

    privado ScrollChangedListener onScrollChangedListener;
    
    public InterceptScrollView(contexto de contexto) {         super(contexto);     }

    public InterceptScrollView(Context context, AttributeSet attrs) {         super(context, attrs);     }

    public InterceptScrollView (contexto de contexto, atributos AttributeSet, int defStyleAttr) {         super (contexto, atributos, defStyleAttr);     }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {         boolean intercept = false;         int x = (int) ev.getX();         int y = (int) ev.getY();         switch (ev.getAction()) {             case MotionEvent.ACTION_DOWN:                 interceptação = falso;                 quebrar;             caso MotionEvent.ACTION_MOVE:                 int deltaX = x - lastInterceptX;                 int deltaY = y - últimoInterceptY;                 //如果是垂直滑动,则拦截                 if (Math.abs(deltaX) - Math.abs(deltaY) < 0) {                     interceptar = true;                 } outro {














                    interceptar = falso;
                }

                break;
            case MotionEvent.ACTION_UP:
                intercept = false;
                break;
        }
        lastInterceptX = x;
        lastInterceptY = y;
        super.onInterceptTouchEvent(ev); //Esta frase não deve ser perdida, caso contrário o evento não poderá ser interceptado
        return intercept;
    }

    @Override
    protegido void onScrollChanged(int l, int t, int oldl, int oldt) {         super.onScrollChanged(l, t, oldl, oldt);         if(onScrollChangedListener!=null){             onScrollChangedListener.onScrollChanged(l,t,oldl,oldt);         }     }




    public void setScrollChangedListener(ouvinte ScrollChangedListener){         onScrollChangedListener = ouvinte;     }

    interface pública ScrollChangedListener{         void onScrollChanged(int scrollX, int scrollY, int oldScrollX, int oldScrollY);     } }


Usar fillViewportatributos não funciona, então reescreveremos ViewPagero onmeasuremétodo para resolver o problema da altura ser exibida como 0. Reescrito ViewPager, o código é o seguinte:

classe pública AutofitViewPager estende ViewPager {

    public AutofitViewPager(@NonNull Context context) {         this(context,null);     }

    public AutofitViewPager(@NonNull Context context, @Nullable AttributeSet attrs) {         super(context, attrs);         addOnPageChangeListener(new OnPageChangeListener() {             @Override             public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {             }




            @Override
            public void onPageSelected(int position) {                 requestLayout(); // Certifique-se de que cada vez que a página atual for selecionada, a altura seja calculada para obter o efeito adaptativo de altura             }

            @Override
            public void onPageScrollStateChanged(int state) {             }         });     }


    //Reescreva onMeasure para resolver o problema de que a altura é exibida como 0 e a altura é exibida dinamicamente como a altura do filho atual
    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {         int height = 0;         for (int i = 0; i < getChildCount (); i++) {             View child = getChildAt(i);             child.measure(widthMeasureSpec,                     MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));             int h = child.getMeasuredHeight();             if( i==getCurrentItem()) {                 altura=h;             }         }         heightMeasureSpec = MeasureSpec.makeMeasureSpec(altura,                 MeasureSpec.EXACTLY);












        super.onMeasure(larguraMeasureSpec, alturaMeasureSpec);
    }

}
Esta é uma solução comum.

Vamos dar uma olhada na introdução abaixo CoordinatorLayout, para não gastar muito espaço explicando. Quem tiver interesse neste layout pode aprender mais sobre ele. Claro, antes de usar este layout, lembre-se de adicionar as bibliotecas dependentes support:design. Coloque o código do layout diretamente abaixo:

<android.support.design.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res- auto"
    android:id="@+id/coordinatorLayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        app:elevation="0dp"
        android:background="@android:color/white">

        <RelativeLayout
            android:id="@+id/title_layout"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            app:layout_scrollFlags="scroll">

            <TextView
                android:id="@+id/tv"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:text="顶部内容模块"
                android:textSize="18sp" />
        </RelativeLayout>

        <android.support.design.widget.TabLayout
            android:id="@+id/tabLayout"
            android:layout_width="match_parent"
            android:layout_height="50dp"
            android:background="@android:color/white"
            app:tabMode ="fixo"
            app:tabSelectedTextColor="@android:color/black" />

    </android.support.design.widget.AppBarLayout>

    <android.support.v4.view.ViewPager
        android:id="@+id/viewPager"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

</android.support.design.widget.CoordinatorLayout>
Este layout pode resolver muitos problemas complexos de viewpager+fragmento, como várias alturas e conflitos de deslizamento.

Acho que você gosta

Origin blog.csdn.net/qq_25462179/article/details/121116720
Recomendado
Clasificación