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>
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"
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?
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.
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>
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 .. :)
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>