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 fillViewport
atributos não funciona, então reescreveremos ViewPager
o onmeasure
mé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.