web-dev-qa-db-ja.com

ViewPager内のScrollViewは、自動的に中央にスクロールします

同じフラグメントの複数のインスタンスを含むViewPagerがありますが、このフラグメントには記事が含まれています。記事ビューの階層は非常にシンプルで、タイトル、バナー画像、サブタイトル、本文です。タイトル以外はすべてスクロールビューでラップされます。

問題はで、新しいページにスワイプすると、フラグメントの上部にビューが表示され、すぐにコンテナーの中央にスクロールします。 (実際には、次のIDのTextViewの先頭までスクロールします:article_content

質問の一番下にレイアウトを掲載しました。

これで、ViewPagerはFragmentStatePagerAdapterの単純な実装で設定されました。コードは次のとおりです。

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

Fragment自体も非常に単純です。まず、onCreate中に記事がキャッシュされているかどうかを確認し、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;
}

setApkArticleContentは単純なテキストのセットであり、派手なものではないことに注意してください。

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

また、以前はページャーを持っていなかった、フラグメントは空のアクティビティにのみロードされ、 scrollviewの中央までスクロールせずに動作しました。

何がスクロールをトリガーしているのかよくわかりません。もちろん、ロード後に上にスクロールするようにプログラムで設定できることはわかっていますが、フラグメントがロードされると、2回のスクロール移動になります。ユーザーにとって非常に目立ちます。

なぜあなたはそれがこのように振る舞うのか何かアイデアを持っていますか?意図しないスクロールを止める方法についてのアイデアはありますか?

おかげで、

以下は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>
22
daniel_c05

これは、Android:textIsSelectableが原因である可能性があります。 ScrollViewに以下を追加してみてください。

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

この属性値を追加しますAndroid:descendantFocusability="blocksDescendants" ScrollViewの子へ、この質問によると: データがロードされた後にscrollviewがwebviewにスクロールしないようにするにはどうすればよいですか?

10
Ayman Mahgoub

私もこの問題を抱えていました。 Android:focusable="true"Android:focusableInTouchMode="true"をScrollViewのLinearLayoutの最初の要素に設定することで解決しました。

2
peter.bartos

追加してみます

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

ルートviewGroup内。それはうまくいっています。以下のように。

 <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>
2
xingkun zheng

ScrollView内部ViewPagerは自動的にスクロールしますが、途中でスクロールしません。これを確認してください。

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

pagerViewPagerのオブジェクトであり、scrollScrollViewであり、ivは任意のViewであるTextViewです。またはImageView

ビューページャーでページを変更すると、スクロールバーは自動的に左にスクロールします。真ん中の解決策を見つけたら、私に知らせてください.. :)

0
Rohit

私は解決策を試しました:

Android:focusable=true

Android:focusableInTouchMode=true

Android:descendantFocusability=beforeDescendants

理由はわかりませんが、親ビューであるRelativeLayoutではこれを実行できません(これは機能しません)。

TextViewをFrameLayout内にラップする必要がありましたが、これですべて問題ありません。多分これは誰かを助けます。

  <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