Collapsing AppBarLayout no se desplaza con TabLayout y NestedScrollView

Tengo un problema con el desplazamiento de la barra de aplicaciones contraída, cuando intento desplazarla tocando la parte AppBarLayout. Y también a veces se desplaza sin problemas.

Aquí hay un breve video (1m 30s) del problema: https: //www.youtube.com/watch? v = n32N9Z4S3SA & feature = youtu.be

Aquí hay un enlace a un proyecto simple (solo este problema en github): https: //github.com/yozhik/Reviews/tree/master/app/src/main/java/com/ylet/sr/revie

Estoy usando: com.android.support: appcompat-v7: 27.1.1

Hay un problema fuera del sitio:https: //issuetracker.google.com/issues/3705015

Como es:https: //www.youtube.com/watch? v = xWadOVEaTSY & feature = youtu.be

Como debería ser:https: //www.youtube.com/watch? v = J8ITp6RusZo & feature = youtu.be

¿Alguien sabe cómo solucionar este problema que viste en el video? Creé diseños absolutamente simples para evitar cualquier efecto secundario, pero el error aún se reproduce. Gracias por adelantado

Descripción

CollapsingActivity - actividad conCollapsing AppBarLayout. Que carga uno o dos fragmentos en "fragment_content_holder" y tieneTabLayout para cambiar entre fragmentos en el buscapersonas.

En el método de actividadonCreate() - Solo estoy simulando una solicitud al servidor loadData), y cuando se cargan algunos datos falsos (estoy mostrando fragmentos en el buscapersonas, en la primera llamada), estoy creando nuevosTabMenuAdapter extiendeFragmentPagerAdapter, llénelo con fragmentos y guarde enlaces en instancias. En la próxima llamada: no creo fragmentos desde cero y solo los relleno con datos nuevos.

MenuFragment1, MenuFragment1 - dos fragmentos. @MenuFragment1 - tiene un método public voidsetupData(SomeCustomData data), para establecer nuevos datos, sin recrear fragmentos en la reconexión de red.

NetworkStateReceiver: escucha los cambios en la red y envía notificaciones.

TabMenuAdapter - solo una clase simple para contener fragmentos.

Next es solo copiar / pegar el código:

public class CollapsingActivity extends AppCompatActivity implements ChangeNetworkNotification {
    private static int dataReloadIteration = 0;
    private SomeCustomData dummyDataFromServer;

    @BindView(R.id.root_layout)
    CoordinatorLayout root_layout;

    @BindView(R.id.app_bar_layout)
    AppBarLayout app_bar_layout;

    @BindView(R.id.collapsing_toolbar_layout)
    CollapsingToolbarLayout collapsing_toolbar_layout;

    @BindView(R.id.view_pager_layout)
    ViewPager viewPager;

    @BindView(R.id.tab_layout)
    TabLayout tabLayout;

    @BindView(R.id.collapsing_data_1_txt)
    TextView collapsing_data_1_txt;

    private NetworkStateReceiver networkStateReceiver;
    private boolean isConnected;

    protected Fragment currentFragment;
    protected Fragment previousFragment;
    protected FragmentManager fragmentManager;

    private boolean dataLoading = false;
    private boolean isCreated = false;

    private MenuFragment1 menu1Fragment1;
    private MenuFragment2 menu1Fragment2;
    private TabMenuAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("TEST", "CollapsingActivity.onCreate");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_collapsing);
        ButterKnife.bind(this);

        fragmentManager = getSupportFragmentManager();

        networkStateReceiver = new NetworkStateReceiver();
        networkStateReceiver.setNetworkReceiver(this);

        IntentFilter intentFilterForNetwork = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(networkStateReceiver, intentFilterForNetwork);

        initToolbar();
        loadData();
    }

    @Override
    protected void onStart() {
        Log.d("TEST", "CollapsingActivity.onStart");
        super.onStart();
        IntentFilter intentFilterForNetwork = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
        registerReceiver(networkStateReceiver, intentFilterForNetwork);
    }

    private void initToolbar() {
        Log.d("TEST", "CollapsingActivity.initToolbar");
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar_layout);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayShowTitleEnabled(false);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    }

    private void loadData() {
        Log.d("TEST", "CollapsingActivity.loadData");
        dataLoading = true;
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(CollapsingActivity.this, "Data loaded.", Toast.LENGTH_SHORT).show();
                        Log.d("TEST", "CollapsingActivity.Data loaded.");
                        dataReloadIteration++;
                        dummyDataFromServer = getDummyObjectFromServer();

                        collapsing_data_1_txt.setText(dummyDataFromServer.Name); //Set data from server in collapsing part of Activity

                        boolean showOneView = false;
                        if (showOneView) {
                            initSingleView();
                        } else {
                            if (!isCreated) {
                                initTabView();
                            } else {
                                menu1Fragment1.setupData(dummyDataFromServer);  //Set the data from server to fragment, not reloading it, just updating data
                            }
                        }
                        dataLoading = false;
                    }
                });
            }
        });
        t.start();
    }

    private SomeCustomData getDummyObjectFromServer() {
        SomeCustomData dto = new SomeCustomData();
        dto.Age = dataReloadIteration;
        dto.Name = "Name " + dataReloadIteration;
        return dto;
    }

    private void initSingleView() {
        Log.d("TEST", "CollapsingActivity.initSingleView");
        tabLayout.setVisibility(View.GONE);
        viewPager.setVisibility(View.GONE);
        showFragmentWithoutBackStack(R.id.fragment_content_holder, new MenuFragment1());
    }

    private void initTabView() {
        if (!isCreated) {
            Log.d("TEST", "CollapsingActivity.initTabView");
            tabLayout.setVisibility(View.VISIBLE);
            viewPager.setVisibility(View.VISIBLE);

            setupViewPager(viewPager);
            tabLayout.setupWithViewPager(viewPager);
            isCreated = true;
        }
    }

    private void setupViewPager(ViewPager viewPager) {
        Log.d("TEST", "CollapsingActivity.setupViewPager");
        menu1Fragment1 = MenuFragment1.newInstance(dummyDataFromServer);
        menu1Fragment2 = MenuFragment2.newInstance();

        adapter = new TabMenuAdapter(getSupportFragmentManager());
        adapter.addFragment(menu1Fragment1, "Menu 1");
        adapter.addFragment(menu1Fragment2, "Menu 2");
        viewPager.setAdapter(adapter);
    }

    @Override
    protected void onDestroy() {
        Log.d("TEST", "CollapsingActivity.onDestroy");
        super.onDestroy();
        unregisterReceiver(networkStateReceiver);
    }

    @Override
    public void networkStateIsChanged(boolean isConnected) {
        this.isConnected = isConnected;
        Log.d("TEST", "CollapsingActivity.networkStateIsChanged.isConnected: " + isConnected);
        if (isConnected) {
            Toast.makeText(CollapsingActivity.this, "Connection received.", Toast.LENGTH_SHORT).show();
            if (!dataLoading) {
                loadData();
            }
        } else {
            Toast.makeText(CollapsingActivity.this, "Connection lost.", Toast.LENGTH_SHORT).show();
        }
    }

    protected void showFragmentWithoutBackStack(int containerViewId, Fragment fragment) {
        Log.d("TEST", "CollapsingActivity.showFragmentWithoutBackStack");
        previousFragment = currentFragment;
        currentFragment = fragment;
        String fragmentTag = fragment.getClass().getSimpleName();
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
        fragmentTransaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
        if (previousFragment != null) {
            fragmentTransaction.remove(previousFragment);
        }
        fragmentTransaction.add(containerViewId, fragment, fragmentTag)
                .commitNowAllowingStateLoss();
    }
}

diseño de la actividad:

<?xml version="1.0" encoding="utf-8"?>
<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/root_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <android.support.design.widget.AppBarLayout
        android:id="@+id/app_bar_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:animateLayoutChanges="false"
        android:background="@color/white"
        android:stateListAnimator="@drawable/appbar_shadow"
        android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.design.widget.CollapsingToolbarLayout
            android:id="@+id/collapsing_toolbar_layout"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="@color/green"
            app:layout_scrollFlags="scroll|exitUntilCollapsed"
            app:title=""
            app:titleEnabled="false">

            <include
                layout="@layout/appbar_collapsing_part"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="?attr/actionBarSize"
                app:layout_scrollFlags="scroll|exitUntilCollapsed" />


            <android.support.v7.widget.Toolbar
                android:id="@+id/toolbar_layout"
                android:layout_width="match_parent"
                android:layout_height="?attr/actionBarSize"
                android:background="@color/green"
                android:stateListAnimator="@drawable/appbar_shadow"
                app:layout_collapseMode="pin"
                app:popupTheme="@style/AppTheme.PopupOverlay"
                app:theme="@style/ToolbarMenuItemsBackGroundTheme">

                <RelativeLayout
                    android:layout_width="match_parent"
                    android:layout_height="match_parent">

                    <TextView
                        android:id="@+id/title_txt"
                        android:layout_width="wrap_content"
                        android:layout_height="match_parent"
                        android:layout_alignParentStart="true"
                        android:layout_toStartOf="@+id/star_img"
                        android:ellipsize="end"
                        android:fontFamily="sans-serif-medium"
                        android:gravity="center_vertical"
                        android:maxLines="1"
                        android:textColor="@color/colorPrimaryDark"
                        android:textSize="19sp" />

                    <ImageView
                        android:id="@+id/star_img"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:layout_alignParentEnd="true"
                        android:layout_centerInParent="true"
                        android:layout_gravity="center"
                        android:layout_marginEnd="24dp"
                        android:padding="10dp"
                        android:src="@drawable/ic_favorite_filled" />

                </RelativeLayout>

            </android.support.v7.widget.Toolbar>

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

        <android.support.design.widget.TabLayout
            android:id="@+id/tab_layout"
            android:layout_width="wrap_content"
            android:layout_height="48dp"
            android:layout_marginLeft="16dp"
            android:layout_marginRight="16dp"
            android:background="#45b0b2"
            android:visibility="gone"
            app:tabBackground="@drawable/backgr_blue_transparent_selector"
            app:tabGravity="center"
            app:tabIndicatorColor="@color/colorPrimaryDark"
            app:tabIndicatorHeight="2dp"
            app:tabMinWidth="500dp"
            app:tabMode="fixed"
            app:tabSelectedTextColor="@color/colorPrimaryDark"
            app:tabTextAppearance="@style/CustomTabLayout"
            app:tabTextColor="@color/green" />

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


    <FrameLayout
        android:id="@+id/fragment_content_holder"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@color/blue"
        app:layout_behavior="@string/appbar_scrolling_view_behavior" />

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

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

Fragmento 1:

public class MenuFragment1 extends Fragment {

    public SomeCustomData transferedDataFromActivity;
    private TextView data_1_txt;

    public static MenuFragment1 newInstance(SomeCustomData data) {
        Log.d("TEST", "MenuFragment1.newInstance");
        MenuFragment1 fragment = new MenuFragment1();

        Bundle args = new Bundle();
        args.putSerializable("DATA_FROM_ACTIVITY", data);
        fragment.setArguments(args);

        return fragment;
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("TEST", "MenuFragment1.onCreate");

        if (getArguments() != null) {
            this.transferedDataFromActivity = (SomeCustomData) getArguments().getSerializable("DATA_FROM_ACTIVITY");
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d("TEST", "MenuFragment1.onCreateView");
        View v = inflater.inflate(R.layout.menu_fragment_1, container, false);
        data_1_txt = (TextView) v.findViewById(R.id.data_1_txt);

        setupInOnCreateView();

        return v;
    }

    protected void setupInOnCreateView() {
        Log.d("TEST", "MenuFragment1.setupInOnCreateView");
        //initialization of all view elements of layout with data is happens here.
        setupData(transferedDataFromActivity);
    }

    public void setupData(SomeCustomData data) {
        Log.d("TEST", "MenuFragment1.setupData");
        this.transferedDataFromActivity = data;
        if (transferedDataFromActivity != null) {
            data_1_txt.setText(transferedDataFromActivity.Name);
        }
    }
}

Diseño del fragmento 1:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green"
    android:orientation="vertical">

    <TextView
        android:id="@+id/data_1_txt"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@color/yellow"
        android:text="Test"
        android:textSize="20sp" />

    <include layout="@layout/description_layout" />

</LinearLayout>

Fragmento 2:

public class MenuFragment2 extends Fragment {

    public static MenuFragment2 newInstance() {
        Log.d("TEST", "MenuFragment2.newInstance");
        MenuFragment2 fragment = new MenuFragment2();
        return fragment;
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Log.d("TEST", "MenuFragment2.onCreateView");
        View v = inflater.inflate(R.layout.menu_fragment_2, container, false);

        setupInOnCreateView();

        return v;
    }

    protected void setupInOnCreateView() {
        Log.d("TEST", "MenuFragment2.setupInOnCreateView");
        //initialization of all view elements of layout with data is happens here.
    }
}

Diseño del fragmento 2:

<?xml version="1.0" encoding="utf-8"?>

<android.support.v4.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/comments_scrollable_layout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:visibility="visible">

    <LinearLayout
        android:id="@+id/comments_layout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@color/yellow" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@color/blue" />

        <RelativeLayout
            android:layout_width="match_parent"
            android:layout_height="100dp"
            android:background="@color/yellow" />

    </LinearLayout>


</android.support.v4.widget.NestedScrollView>

TabMenuAdapter:

public class TabMenuAdapter extends FragmentPagerAdapter {
    private final List<Fragment> mFragments = new ArrayList<>();
    private final List<String> mFragmentTitles = new ArrayList<>();

    public TabMenuAdapter(FragmentManager fm) {
        super(fm);
    }

    public void addFragment(Fragment fragment, String title) {
        mFragments.add(fragment);
        mFragmentTitles.add(title);
    }

    @Override
    public Fragment getItem(int position) {
        return mFragments.get(position);
    }

    @Override
    public int getCount() {
        return mFragments.size();
    }

    @Override
    public CharSequence getPageTitle(int position) {
        return mFragmentTitles.get(position);
    }

}

Respuestas a la pregunta(5)

Su respuesta a la pregunta