質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.51%

  • Android

    7297questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。

RecyclerViewが勝手にスクロールする

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,451
退会済みユーザー

退会済みユーザー

前提・実現したいこと

RecyclerViewを用いた画面を作成しています。
スワイプで画面を切り替えると自動でスクロールしてしまいます。
なぜ勝手にスクロールしてしまうのか理由がわかりません。
そもそもこのようなレイアウトは不可能なのでしょうか。

発生している問題・エラーメッセージ

RecyclerView - View - RecyclerViewという順で
LinearLayoutのVerticalで配置しています。
真ん中のViewが表示される位置までスクロールした状態で、
スワイプで画面を切り替え、元に戻ると、
下部のRecyclerViewの上端がレイアウトのトップの位置に
自動でスクロールしてしまいます。

エラーメッセージは特にありません。


起動直後
イメージ説明
真ん中のViewが表示される位置までスクロール
イメージ説明
スワイプで画面切り替え
イメージ説明
元のページに戻り中
イメージ説明
元のページに戻りきった直後にScrollToされたかのように位置が変わる
イメージ説明

該当のソースコード

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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.support.design.widget.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content">
       <android.support.v7.widget.Toolbar
           android:id="@+id/toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           android:background="?attr/colorPrimary"
           app:layout_scrollFlags="scroll|enterAlways" />
       <android.support.design.widget.TabLayout
           android:id="@+id/tab_layout"
           android:layout_width="match_parent"
           android:layout_height="wrap_content"
           android:background="?attr/colorPrimary"
           app:tabIndicatorColor="#FFFF8D" />
   </android.support.design.widget.AppBarLayout>
   <android.support.v4.view.ViewPager
       android:id="@+id/view_pager"
       app:layout_behavior="@string/appbar_scrolling_view_behavior"
       android:layout_width="match_parent"
       android:layout_height="wrap_content"/>
</android.support.design.widget.CoordinatorLayout>


MainActivity.java

public class MainActivity extends AppCompatActivity implements ViewPager.OnPageChangeListener {
   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
       setSupportActionBar(toolbar);
       FragmentPagerAdapter adapter = new FragmentPagerAdapter(getSupportFragmentManager()) {
           @Override
           public Fragment getItem(int position) {
               return BlankFragment.newInstance("", "");
           }
           @Override
           public CharSequence getPageTitle(int position) {
               return "tab " + (position + 1);
           }
           @Override
           public int getCount() {
               return 2;
           }
       };
       ViewPager viewPager = (ViewPager) findViewById(R.id.view_pager);
       viewPager.setAdapter(adapter);
       TabLayout tabLayout = (TabLayout) findViewById(R.id.tab_layout);
       tabLayout.setupWithViewPager(viewPager);
   }
   @Override
   public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
   }
   @Override
   public void onPageSelected(int position) {
   }
   @Override
   public void onPageScrollStateChanged(int state) {
   }
}


RecyclerAdapter.java

public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ViewHolder> {
   private LayoutInflater mInflater;
   private ArrayList<String> mData;
   public RecyclerAdapter(Context context, ArrayList<String> data) {
       mInflater = LayoutInflater.from(context);
       mData = data;
   }
   @Override
   public RecyclerAdapter.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
       return new ViewHolder(mInflater.inflate(R.layout.list_item, viewGroup, false));
   }
   @Override
   public void onBindViewHolder(ViewHolder viewHolder, final int i) {
       if (mData != null && mData.size() > i && mData.get(i) != null) {
           viewHolder.textView.setText(mData.get(i));
           if (i % 2 == 0) {
               viewHolder.textView.setBackgroundColor(Color.argb(0x44, 0xff, 0x00, 0x00));
           } else {
               viewHolder.textView.setBackgroundColor(Color.argb(0x44, 0x00, 0x00, 0xff));
           }
       }
   }
   @Override
   public int getItemCount() {
       if (mData != null) {
           return mData.size();
       } else {
           return 0;
       }
   }
   class ViewHolder extends RecyclerView.ViewHolder {
       TextView textView;
       public ViewHolder(View itemView) {
           super(itemView);
           textView = (TextView) itemView.findViewById(R.id.list_item_text);
       }
   }
}


BlankFragment.java

public class BlankFragment extends Fragment {
   private static final String ARG_PARAM1 = "param1";
   private static final String ARG_PARAM2 = "param2";
   private String mParam1;
   private String mParam2;
   private View mRootView;
   public BlankFragment() {
   }
   public static BlankFragment newInstance(String param1, String param2) {
       BlankFragment fragment = new BlankFragment();
       Bundle args = new Bundle();
       args.putString(ARG_PARAM1, param1);
       args.putString(ARG_PARAM2, param2);
       fragment.setArguments(args);
       return fragment;
   }
   @Override
   public void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       if (getArguments() != null) {
           mParam1 = getArguments().getString(ARG_PARAM1);
           mParam2 = getArguments().getString(ARG_PARAM2);
       }
   }
   @Override
   public View onCreateView(LayoutInflater inflater, ViewGroup container,
                            Bundle savedInstanceState) {
       mRootView = inflater.inflate(R.layout.fragment_blank, container, false);
       return mRootView;
   }
   @Override
   public void onAttach(Context context) {
       super.onAttach(context);
   }
   @Override
   public void onDetach() {
       super.onDetach();
   }
   @Override
   public void onActivityCreated(@Nullable Bundle savedInstanceState) {
       super.onActivityCreated(savedInstanceState);
       ArrayList<String> upperArray = new ArrayList<>();
       for (Integer i=0; i<10; i++) {
           upperArray.add("upper " + i.toString());
       }
       RecyclerAdapter upperAdapter = new RecyclerAdapter(getActivity(), upperArray);
       RecyclerView mRecyclerView = (RecyclerView) mRootView.findViewById(R.id.upper_recycler_view);
       mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
       mRecyclerView.setAdapter(upperAdapter);
       ArrayList<String> lowerArray = new ArrayList<>();
       for (Integer i=0; i<10; i++) {
           lowerArray.add("lower " + i.toString());
       }
       RecyclerAdapter lowerAdapter = new RecyclerAdapter(getActivity(), lowerArray);
       RecyclerView mRecyclerView2 = (RecyclerView) mRootView.findViewById(R.id.lower_recycler_view);
       mRecyclerView2.setLayoutManager(new LinearLayoutManager(getActivity()));
       mRecyclerView2.setAdapter(lowerAdapter);
   }
}


fragment_blank.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:orientation="vertical"
   android:layout_width="match_parent"
   android:layout_height="match_parent" >
   <android.support.v4.widget.NestedScrollView
       android:layout_width="match_parent"
       android:layout_height="match_parent">
       <LinearLayout
           android:orientation="vertical"
           android:layout_width="match_parent"
           android:layout_height="match_parent">
           <android.support.v7.widget.RecyclerView
               android:id="@+id/upper_recycler_view"
               android:layout_width="match_parent"
               android:layout_height="wrap_content" />
           <View
               android:background="#ff00ff00"
               android:layout_width="match_parent"
               android:layout_height="200dp" />
           <android.support.v7.widget.RecyclerView
               android:id="@+id/lower_recycler_view"
               android:layout_width="match_parent"
               android:layout_height="wrap_content" />
       </LinearLayout>
   </android.support.v4.widget.NestedScrollView>
</LinearLayout>


build.gradleのdependencies

dependencies {
   compile fileTree(dir: 'libs', include: ['*.jar'])
   androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
       exclude group: 'com.android.support', module: 'support-annotations'
   })
   compile 'com.android.support:appcompat-v7:24.2.1'
   compile 'com.android.support:design:24.2.1'
   compile 'com.android.support:support-v4:24.2.1'
   compile 'com.android.support:recyclerview-v7:24.2.1'
   testCompile 'junit:junit:4.12'
}

試したこと

真ん中のViewが表示されない位置で試すと再現しない
エミュレータでも試してみましたが同様の結果でした。

補足情報(言語/FW/ツール等のバージョンなど)

端末: xperia z1
OS: Android 4.4.2
開発環境: Android studio 2.2.2

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2016/11/14 21:16

    他のユーザから「意図的に内容が抹消された質問」という指摘を受けました
    解決後に編集機能を用いて質問内容を改変し関係のない内容にしたり、内容を削除する行為は禁止しています。
    投稿していただいた質問は、後に他の誰かが困ったときに助けになる情報資産になると考えるからです。
    「質問を編集する」ボタンから編集を行い、他のユーザにも質問内容が見えるように修正してください。

回答 2

0

スクロールしているのを見ているわけではないですね?あくまでスクロールされたように元の位置に戻っているだけでは。
Viewが作り直されている可能性があるのでBlankFragment#onCreateViewでログ出力を行い、再度呼ばれていないかを確認してください。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/12 17:56 編集

    >スクロールしているのを見ているわけではないですね?

    キャンセル

  • 2016/11/12 20:36

    不思議ですね。
    NestedScrollViewとRecyclerViewを重ねてるのが関係してそうですね。
    NestedScrollViewを普通のScrollViewに変更してみるとどうなりますか?

    キャンセル

  • 2016/11/12 20:48 編集

    ScrollViewに変更して試してみましたが、同じようにスクロール位置が変わりました。

    キャンセル

  • 2016/11/12 21:20

    原意を切り分けたいだけなのでScrollViewを使えと言っているわけではありません。

    ・一旦Viewを削除して試してください。
    ・一旦RecyclerViewとViewを削除して試してください。

    キャンセル

  • 2016/11/12 21:36 編集

    >原意を切り分けたいだけなのでScrollViewを使えと言っているわけではありません。
    はい。

    キャンセル

  • 2016/11/12 21:44

    ということはScrollできるViewの中にRecyclerViewを2つ入れると問題が発生するのかも知れないですね。

    RecyclerViewだけを消して再度確認してください。

    キャンセル

  • 2016/11/12 21:49 編集

    特に何も問題はありませんでした。

    キャンセル

  • 2016/11/12 21:56 編集

    上のRecyclerViewのみをけした場合は再現しました!

    キャンセル

  • 2016/11/12 22:43

    View-RecyclerViewで発生したということですね?

    キャンセル

  • 2016/11/12 22:49 編集

    そうです。

    キャンセル

  • 2016/11/12 23:03 編集

    最下部までスクロールした状態からだと発生しないです。

    キャンセル

同じタグがついた質問を見る

  • Android

    7297questions

    Androidは、Google社が開発したスマートフォンやタブレットなど携帯端末向けのプラットフォームです。 カーネル・ミドルウェア・ユーザーインターフェイス・ウェブブラウザ・電話帳などのアプリケーションやソフトウェアをひとつにまとめて構成。 カーネル・ライブラリ・ランタイムはほとんどがC言語/C++、アプリケーションなどはJavaSEのサブセットとAndroid環境で書かれています。