35 votes

TabLayout avec viewpager ne fait pas défiler en douceur

Éditer

J'ai suivi ces tutoriels pour résoudre ce problème.

http://www.truiton.com/2015/06/android-tabs-example-fragments-viewpager/ https://guides.codepath.com/android/google-play-style-tabs-using-tablayout http://www.voidynullness.net/blog/2015/08/16/android-tablayout-design-support-library-tutorial/

Mais c'est ennuyant que le problème persiste même après avoir essayé plusieurs solutions. Voici une démo du problème auquel je suis confronté. Cela fait des semaines que je suis bloqué sur ce problème.

Lien pour la démo.

Les appareils que j'utilise pour les tests sont le Nexus 4 et le Nexus 5.

TabLayout avec ViewPager ne défile pas en douceur. Je dois swiper deux fois pour passer à l'onglet suivant. J'ai cherché sur le web mais je n'ai pas trouvé de solution. J'utilise la dernière bibliothèque de support design. Voici le fichier gradle

appliquer le plugin : 'com.android.application'

android {
compileSdkVersion 23
buildToolsVersion "23.0.3"

defaultConfig {
    applicationId "com.softoven.ultron"
    minSdkVersion 15
    targetSdkVersion 23
    versionCode 1
    versionName "1.0"
}
buildTypes {
    release {
        minifyEnabled false
        proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
}
}

dépendances {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.3.0'
compile 'com.android.support:design:23.3.0'
compile 'org.jsoup:jsoup:1.6.1'
compile 'com.mikhaellopez:circularimageview:3.0.0'
compile 'com.android.support:recyclerview-v7:23.3.0'
compile 'com.mcxiaoke.volley:library:1.0.19'
compile 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
compile 'com.google.code.gson:gson:2.5'
}

Voici le code de l'activité.

private DrawerLayout drawerLayout;
private ViewPager viewPager;
private TabLayout tabLayout;
private NavigationView navigationView;
private CategoriesDTO categoriesDTO;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    initToolbar();
    initUi();
    loadCategories();
}

private void initToolbar() {
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setHomeAsUpIndicator(R.drawable.ic_action_menu);
}

private void initUi() {
    drawerLayout = (DrawerLayout) findViewById(R.id.drawer);
    navigationView = (NavigationView) findViewById(R.id.navigation);
    viewPager = (ViewPager) findViewById(R.id.viewPager);
    tabLayout = (TabLayout) findViewById(R.id.tab);

}

private void loadCategories() {
    StringRequest request = new StringRequest(Constants.URL_GET_CATEGORIES, new Response.Listener() {
        @Override
        public void onResponse(String response) {
            categoriesDTO = Constants.gson.fromJson(response, CategoriesDTO.class);
            ViewPagerAdapter adapter = new ViewPagerAdapter(getSupportFragmentManager());
            viewPager.setOffscreenPageLimit(1);
            viewPager.setAdapter(adapter);
            setTabLayout();
        }
    }, new Response.ErrorListener() {
        @Override
        public void onErrorResponse(VolleyError error) {

        }
    });

    ApplicationController.getmInstance().addToRequestQueue(request);
}

private void setTabLayout() {

    tabLayout.setupWithViewPager(viewPager);

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater menuInflater = getMenuInflater();
    menuInflater.inflate(R.menu.home_side_menu, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    switch (id) {
        case android.R.id.home:
            drawerLayout.openDrawer(GravityCompat.START);
            return true;
    }
    return super.onOptionsItemSelected(item);
}

private class ViewPagerAdapter extends FragmentPagerAdapter {

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

    @Override
    public Fragment getItem(int position) {
        return new ContentFragment();
    }

    @Override
    public int getCount() {
        return 10;
    }

    @Override
    public CharSequence getPageTitle(int position) {
        String title = categoriesDTO.getCategories().get(position).getTitle();
        return (CharSequence) title;
    }
}

Et fichier xml

Voici la capture d'écran où vous pouvez voir que l'indicateur est partiellement divisé.

description de l'image ici

Une solution ?

34voto

ankit aggarwal Points 1344

Je viens de passer en revue votre code. Le problème est que vous ne fournissez aucun agencement à gonfler à l'intérieur de ContentFragment.java.

J'ai modifié votre méthode pour

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        //return super.onCreateView(inflater, container, savedInstanceState);
        return  inflater.inflate(R.layout.feed_item, container, false);

    }

Après avoir apporté ces modifications, vos onglets défilaient en douceur. Je ne connais pas la raison derrière ce comportement, mais cette chose a permis de le faire fonctionner

14voto

Hamed Nabizadeh Points 360

Changez cette ligne dans votre activité :

ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());

3voto

jaydroider Points 3713

Je pense que vous devez utiliser la méthode override setUserVisibleHint.

Vous devez ajouter cela dans votre Fragment.

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser) {
        // charger les données ici
    }else{
       // le fragment n'est plus visible
    }
}

Définissez votre offScreenPageLimit à NOMBRE D'ONGLETS que vous avez.

En savoir plus sur setUserVisibleHint ici.

3voto

Arihant Jain Points 41

Si vous allez créer TabLayout dans des fragments, utilisez getChildFragmentManager() au lieu de getSupportFragmentManager() comme paramètre.

ViewPagerAdapter adapter = new ViewPagerAdapter(getChildFragmentManager());

1voto

Chebyr Points 1216

Activer toutes les politiques StrictMode sur votre application pour détecter toutes les opérations de longue durée que vous pourriez effectuer involontairement sur le thread principal, provoquant des ralentissements, afin que vous puissiez prendre les mesures correctives nécessaires.

StrictMode est un outil pour les développeurs qui détecte les actions que vous pourriez faire par erreur et attire votre attention dessus pour que vous puissiez les corriger. StrictMode est le plus souvent utilisé pour détecter les accès disque ou réseau accidentels sur le thread principal de l'application, où les opérations d'interface utilisateur sont reçues et les animations ont lieu.

Consultez https://developer.android.com/reference/android/os/StrictMode.html pour plus de détails.

    // Activer toutes les politiques StrictMode sur les threads
    StrictMode.ThreadPolicy.Builder threadPolicyBuilder = new StrictMode.ThreadPolicy.Builder();

    // Détecter tout ce qui est potentiellement suspect
    threadPolicyBuilder.detectAll();

    // Arrêter tout le processus en cas de violation
    threadPolicyBuilder.penaltyDeath();

    // Enregistrer les violations détectées dans le log système
    threadPolicyBuilder.penaltyLog();

    // Arrêter tout le processus en cas d'utilisation du réseau
    threadPolicyBuilder.penaltyDeathOnNetwork();

    StrictMode.ThreadPolicy threadPolicy = threadPolicyBuilder.build();
    StrictMode.setThreadPolicy(threadPolicy);

    // Activer toutes les politiques StrictMode sur la machine virtuelle
    StrictMode.VmPolicy.Builder vmPolicyBuilder = new StrictMode.VmPolicy.Builder();

    // Détecter tout ce qui est potentiellement suspect
    vmPolicyBuilder.detectAll();

    // Enregistrer les violations détectées dans le log système
    vmPolicyBuilder.penaltyLog();

    StrictMode.VmPolicy vmPolicy = vmPolicyBuilder.build();
    StrictMode.setVmPolicy(vmPolicy);

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X