web-dev-qa-db-fra.com

ScrollView dans ViewPager, défile automatiquement jusqu'au milieu

J'ai un ViewPager qui contient plusieurs instances du même fragment, ce fragment contient un article. La hiérarchie de la vue Article est assez simple: un titre, une image bannière, un sous-titre et un corps; tout sauf le titre est enveloppé dans un scrollview. 

Le problème est , lorsque vous glissez vers une nouvelle page, le fragment est présenté avec les vues en haut, puis il défile immédiatement vers le milieu du conteneur. (En fait, il défile jusqu'au début de TextView avec l'id: article_content )

J'ai posté la mise en page au bas de la question. 

Maintenant, le ViewPager est configuré avec une implémentation simple de FragmentStatePagerAdapter, voici le code:

class ScreenSlidePagerAdapter extends FragmentStatePagerAdapter {

    Bundle args;
    int count;

    public ScreenSlidePagerAdapter(FragmentManager fm) {
        super(fm);
        this.count = 8;
    }

    @Override
    public Fragment getItem(int position) {
        ArticleFragment mPrimaryFragment = new ArticleFragment();
        args = new Bundle();
        args.putString(ArticleFragment.KEY_ARTICLE_URL, mCurArticleLink);
        mPrimaryFragment.setArguments(args);
        return mPrimaryFragment;            
    }

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

Le fragment lui-même est assez simple aussi. Tout d'abord, je vérifie pendant onCreate pour voir si l'article est mis en cache, puis-je appeler onCreateView

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.apk_article_view, null);

    mTitle = (TextView) view.findViewById(R.id.article_title);
    mBanner = (ImageView) view.findViewById(R.id.article_banner);
    mSubTitle = (TextView) view.findViewById(R.id.article_subtitle);
    mContent = (TextView) view.findViewById(R.id.article_content);

    if (isArticleCached) {
        Constants.logMessage("Article is cached, loading from database");
        setApkArticleContent();
    }
    else {
        Constants.logMessage("Article isn't cached, downloading");
        HtmlHelper.setApkArticleContent(mContext, mUrl, mTitle, mSubTitle, mContent, mBanner);
        setRefreshing(true);
    }

    return view;
}

Il est à noter que setApkArticleContent est un simple jeu de textes, rien d’extraordinaire: 

private void setApkArticleContent() {
    mTitle.setText(Html.fromHtml(mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.TITLE))));
    mSubTitle.setText(Html.fromHtml(mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.SUBTITLE))));
    mContent.setText(Html.fromHtml(mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.BODY))));
    UrlImageViewHelper.setUrlDrawable(mBanner, mCursor.getString(mCursor.getColumnIndex(DbOpenHelper.BANNER)));     
}

De plus, sachez que Je n'avais pas de téléavertisseur avant , le fragment n'était chargé que dans une activité vide et/ fonctionnait sans défilement jusqu'au milieu de la vue à défilement .

Je ne sais vraiment pas ce qui déclenche le défilement, et oui, je sais que je peux le configurer par programmation pour qu'il revienne au début après le chargement, mais là encore, ce serait deux mouvements de défilement lorsque le fragment est chargé et ce serait assez perceptible pour l'utilisateur. 

Avez-vous une idée de ce qui se passerait ainsi? Des idées sur la façon dont je peux arrêter ce parchemin involontaire? 

Merci, 

Ci-dessous se trouve la mise en page pour ArticleFragment: 

<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >

<TextView
    Android:id="@+id/article_title"
    style="@style/headerTextBoldNoUnderline"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    Android:gravity="left|center_vertical"
    Android:text="" />

<ScrollView
    Android:layout_height="match_parent"
    Android:layout_width="match_parent"
    >

    <LinearLayout
        Android:orientation="vertical"
        Android:layout_height="wrap_content"
        Android:layout_width="match_parent"
        >

        <ImageView
            Android:id="@+id/article_banner"
            Android:layout_gravity="center_vertical|center_horizontal"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"
            Android:layout_margin="12dp" />

        <TextView
            Android:id="@+id/article_subtitle"
            style="@style/HeaderTextItalicNoUnderline"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:gravity="left|center_vertical" />

        <View
            Android:layout_width="fill_parent"
            Android:layout_height="1dp"
            Android:background="?android:attr/dividerVertical" />

        <TextView
            Android:id="@+id/article_content"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:fontFamily="sans-serif-light"
            Android:gravity="left|center_vertical"
            Android:padding="8dp"
            Android:textColor="?android:attr/textColorSecondary"
            Android:textIsSelectable="true"
            Android:textSize="16sp" />
    </LinearLayout>
</ScrollView>

</LinearLayout>
20
daniel_c05

Ceci est probablement dû à Android:textIsSelectable. Vous pouvez essayer d’ajouter les éléments suivants à ScrollView:

Android:focusable="true"
Android:focusableInTouchMode="true"
Android:descendantFocusability="beforeDescendants"
31
Paul Burke

Ajoutez cette valeur d'attribut Android:descendantFocusability="blocksDescendants" à l'enfant de ScrollView, en fonction de cette question: Comment empêcher un scrollview de défiler vers une vue Web après le chargement des données?

10
Ayman Mahgoub

J'ai aussi eu ce problème. Je l'ai résolu en définissant Android:focusable="true" et Android:focusableInTouchMode="true" sur le premier élément de LinearLayout dans ScrollView.

2
peter.bartos

j'essaie d'ajouter 

    Android:focusable="true"
    Android:focusableInTouchMode="true"
    Android:descendantFocusability="beforeDescendants"

dans le groupe de vues racine. le travail est bon. comme ci-dessous.

 <RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:app="http://schemas.Android.com/apk/res-auto"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    Android:focusable="true"
    Android:focusableInTouchMode="true"
    Android:descendantFocusability="beforeDescendants"
    Android:background="@color/normal_bg">

    <ScrollView
        Android:id="@+id/scroll"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:layout_above="@+id/rl_enter"
        Android:scrollbars="none">
        </ScrollView>
    </RelativeLayout>
0
xingkun zheng

ScrollView à l'intérieur de ViewPager défile automatiquement mais ne défile pas au milieu. Vérifiez ceci.

pager.setOnPageChangeListener(new OnPageChangeListener() {

                @Override
                public void onPageSelected(int position) {
                    // TODO Auto-generated method stub
                    int x=iv.getLeft();
                    int y=iv.getTop();
                    scroll.scrollTo(x, y);
                }

pager est l'objet de ViewPager et scroll est ScrollView et iv est toute View dire TextView ou ImageView

Lorsque nous changeons de page dans viewpager, la barre de défilement défile automatiquement mais vers la gauche. Si vous souhaitez trouver une solution au milieu s'il vous plaît faites le moi savoir .. :) 

0
Rohit

J'ai essayé la solution: 

Android:focusable=true

Android:focusableInTouchMode=true

Android:descendantFocusability=beforeDescendants

Et je ne sais pas pourquoi mais je ne peux pas le faire avec mon RelativeLayout qui est la vue parent (cela ne fonctionne pas). 

Je devais envelopper ma TextView dans FrameLayout et maintenant tout va bien. Peut-être que cela aide quelqu'un. 

  <FrameLayout
        Android:id="@+id/detail_description_container"
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:layout_below="@id/detail_parameters_container"
        Android:layout_centerInParent="true"
        Android:descendantFocusability="beforeDescendants"
        Android:focusable="true"
        Android:focusableInTouchMode="true" >

        <TextView
            Android:id="@+id/detail_descritpion"
            Android:layout_width="match_parent"
            Android:layout_height="wrap_content"
            Android:autoLink="all"
            Android:padding="10dp"
            Android:textIsSelectable="true" />
    </FrameLayout>
0
lukjar