24

I have a ViewPager that contains several instances of the same fragment, this fragment contains an article. The Article view hierarchy is quite simple, a Title, a Banner image, a subtitle and a body; everything but the title is wrapped in a scrollview.

The problem is, when you swipe to a new page, the fragment is presented with the Views at the top, and then it immediately scrolls to the middle of the container. (As a matter of fact it scrolls to the beginning of the TextView with id: article_content)

I have posted the layout at the bottom of the question.

Now, the ViewPager is set with a simple implementation of a FragmentStatePagerAdapter, here's the 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; } } 

The Fragment itself is pretty simple too. First, I check during onCreate to see if we have the article cached, the I call on 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; } 

It is worth noting that setApkArticleContent is a simple set of Texts, nothing fancy:

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))); } 

Also, please know that I did not have a pager before, the fragment was only loaded to an empty activity, and it worked without scrolling to the middle of the scrollview.

I am really not sure what is triggering the scroll, and yes, I know I can programatically set it to scroll back to the top after loading, but then again, that'd be two scroll movements when the fragment is loaded and it would be quite noticeable for the user.

Do you guys have any ideas why it would behave like this? Any ideas on how I can stop that unintentional scroll?

Thanks,

Below is the layout for the 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> 
7
  • Have you tried messing with the android:descendantFocusability on the ScrollView? Commented Apr 24, 2013 at 2:59
  • Just did, I actually tried all three values for it, got same results for all three, the scrollview still scrolls to the middle. Commented Apr 24, 2013 at 3:06
  • Note: You may need to use android:focusable=true and android:focusableInTouchMode=true for android:descendantFocusability=beforeDescendants. I suspect that the issues is based in the inclusion of android:textIsSelectable. Also try removing that, as a control. Commented Apr 24, 2013 at 3:12
  • Hmm, I don't see why <code>android:textIsSelectable</code> should be the source of the issue, after all the property was there before, when it was a single activity containing a single fragment. But yes, that did work, and it doesn't scroll to the middle anymore, thanks! Commented Apr 24, 2013 at 3:16
  • You should that as an answer by the way, I think I can deal with not having the text selectable. Commented Apr 24, 2013 at 3:17

6 Answers 6

32

This is likely caused by android:textIsSelectable. You may try adding the following to the ScrollView:

android:focusable="true" android:focusableInTouchMode="true" android:descendantFocusability="beforeDescendants" 
Sign up to request clarification or add additional context in comments.

4 Comments

Perhaps even try these on the root LinearLayout, if this doesn't work.
Adding the lines to the LinearLayout inside the ScrollView worked well, also did removing the android:textIsSelectable.
Added these lines to the root LinearLayout, worked, thanks bro.
This actually works. But when i click on my textView it stills scrolls me to the top of the text.
10

Add this attribute value android:descendantFocusability="blocksDescendants" to the child of ScrollView, according to this question: How to prevent a scrollview from scrolling to a webview after data is loaded?

Comments

2

I also had this problem. I solved it with setting android:focusable="true" and android:focusableInTouchMode="true" to the first element in the ScrollView's LinearLayout.

Comments

2

i try to add

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

in the root viewGroup . it's work's well. like below.

 <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> 

1 Comment

You might want to add some words of explanation.
0

I tried solution:

android:focusable=true android:focusableInTouchMode=true android:descendantFocusability=beforeDescendants 

And i dont know why but I cant do this with my RelativeLayout which is parent view (this does not work).

I had to wrap my TextView inside FrameLayout and now everything is ok. Maybe this helps somebody.

 <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> 

Comments

0

ScrollView inside ViewPager scrolls automatically but does not scrolls in middle.. Check out this.

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 is ViewPager's object and scroll is ScrollView and iv is any View say TextView or ImageView.

When we change page in viewpager, scrollbar automatically scrolls but to the left. If you would have find solution to middle please let me know.. :)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.