2011-08-01 32 views
1

「ListView内部のScrollView」に関するいくつかの質問があります。そして私は、両方のコンポーネントが独自のスクロールを持ち、Googleがそう言っているからといって、そのようなネスティングを行うべきではないことを知っている(私はそれが役に立たないことを読んだ)。しかし、私の現在のプロジェクトでは、このような振る舞いが必要です。listviewがスクロールできる場合 - スクロールしていない場合(リストビューの上端または下端) - scrollviewがスクロールしています。 だから、私が書いてきたようなコード:ListView内部のScrollViewスクロールの改善

public static void smartScroll(final ScrollView scroll, final ListView list){ 
     scroll.requestDisallowInterceptTouchEvent(true); 
     list.setOnTouchListener(new OnTouchListener() { 
      private boolean isListTop = false, isListBottom = false; 
      private float delta = 0, oldY = 0; 
      @Override 
      public boolean onTouch(View v, MotionEvent event) {    
       switch (event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        oldY = event.getY(); 
        break; 
       case MotionEvent.ACTION_UP: 
        delta = 0; 
        break; 
       case MotionEvent.ACTION_MOVE: 
        delta = event.getY() - oldY; 
        oldY = event.getY(); 

        isListTop = false; 
        isListBottom = false; 

        View first = list.getChildAt(0); 
        View last = list.getChildAt(list.getChildCount()-1);     
        if(first != null && list.getFirstVisiblePosition() == 0 && first.getTop() == 0 && delta > 0.0f){ 
         isListTop = true; 
        } 
        if(last != null && list.getLastVisiblePosition() == list.getCount()-1 && last.getBottom() <= list.getHeight() && delta < 0.0f){ 
         isListBottom = true; 
        } 

        if((isListTop && delta > 0.0f) || (isListBottom && delta < 0.0f)){ 
         scroll.post(new Runnable() { 
          public void run() { 
           scroll.smoothScrollBy(0, -(int)delta); 
          } 
         }); 
        } 

        break; 
       default: break; 
       }     
       scroll.requestDisallowInterceptTouchEvent(true); 
       return false; 
      } 
     }); 
    } 

そして、それは、少なくともターゲットAPI 8に、動作しますが、いくつかのスクロールの不具合(不自然なジャンプ)があります。私は、scroll.smoothScrollBy(0、 - (int)delta)の原因と思います。誰かの考えを持って、スクロールビューのスクロールを改善する方法:)それは頻繁に(動いている時に)呼び出され、ポストでは、それが原因でしょうか?

+0

こんにちは、あなたの現在の考えはどうですか?不自然なジャンプの問題を解決しましたか?ありがとう... – OferR

+0

こんにちは!さて、デザインが変更され、そのような動作はもう必要ありません。私の思考 - 彼らの実装のため、ScrollView内でListViewを使用することはできません。 Googleの人は正しいです:)このような動作を実現するには、ViewGroupに基づいて独自のUIコンポーネントを実装する方がよいでしょう。 – Olsavage

+0

あなたの答えOlsavageありがとう。したがって、私は情報を提示する他の方法を検討しています。 – OferR

答えて

3

が必要だと思います。私はこのコードを改善して、今は正しいと思っています。

public static void smartScroll(final ScrollView scroll, final ListView list){ 
    list.setOnTouchListener(new View.OnTouchListener() { 
     private boolean isListTop = false, isListBottom = false; 
     private float delta = 0, oldY = 0; 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      switch (event.getAction()) { 
       case MotionEvent.ACTION_DOWN: 
        scroll.requestDisallowInterceptTouchEvent(true); 
        list.requestDisallowInterceptTouchEvent(false); 
        oldY = event.getY(); 
        break; 
       case MotionEvent.ACTION_UP: 
        delta = 0; 
        break; 
       case MotionEvent.ACTION_MOVE: 
        delta = event.getY() - oldY; 
        oldY = event.getY(); 

        isListTop = false; 
        isListBottom = false; 

        View first = list.getChildAt(0); 
        View last = list.getChildAt(list.getChildCount()-1); 
        if(first != null && list.getFirstVisiblePosition() == 0 && first.getTop() == 0 && delta > 0.0f){ 
         isListTop = true; 
        } 
        if(last != null && list.getLastVisiblePosition() == list.getCount()-1 && last.getBottom() <= list.getHeight() && delta < 0.0f){ 
         isListBottom = true; 
        } 

        if((isListTop && delta > 0.0f) || (isListBottom && delta < 0.0f)){ 
         scroll.requestDisallowInterceptTouchEvent(false); 
         list.requestDisallowInterceptTouchEvent(true); 
        } 
        break; 
       default: break; 
      } 
      return false; 
     } 
    }); 
} 

我々はリストビューにタッチする - 私たちはそのスクロールを無効親スクロール可能:

    scroll.requestDisallowInterceptTouchEvent(true); 
        list.requestDisallowInterceptTouchEvent(false); 

そして、我々はリストの境界線に到達した場合を - 私たちはそのスクロールを無効にして、親のスクロールを有効にします。

    scroll.requestDisallowInterceptTouchEvent(false); 
        list.requestDisallowInterceptTouchEvent(true); 

私はかなりスムーズにスクロールします。お役に立てれば。

+0

私はあなたの変更をテストしました。うわー、私はこの質問をしてから約3年です。ありがとう=) – Olsavage

0

私のsugesstionは、リストビューのタグをスクロールビューの外側に置きます。そして、スクロールビュー内のリストビューの外に領域を追加します。その後、すべてを線形レイアウトの中に入れます。したがって、scollviewとlistviewは別々です。

+0

提案していただきありがとうございますが、私はListViewをコンテンツでスクロールする必要があります。 ListViewのスクロールが最優先事項である必要がありますが、ListViewのスクロールが起こっていない場合、親ScrollViewはリストビュー内でスクロールする必要があります。 – Olsavage

+0

OK、私はあなたの答えを受け入れるべきです。つまり、ListViewをScrollViewに入れないでください=)おそらく誰かがこの無駄なことに時間を費やさないように助けてくれるでしょう。 – Olsavage

1

親がScrollViewの場合は、LinearLayoutとして変更します。それが動作します。たとえば、ここではScrollViewではなくLinearLayoutを記述しました。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
android:id="@+id/scroll" 
android:layout_width="fill_parent" 
android:layout_height="fill_parent" 
android:fillViewport="true"> 

     <ListView android:id="@+id/fontlistView" 
      android:scrollbars="vertical" 
      android:layout_height="wrap_content" 
      android:layout_width="match_parent" 
      android:layout_gravity="center_horizontal" 
      android:scrollbarAlwaysDrawVerticalTrack="true"> 
     </ListView> 
</LinearLayout> 
0

私はuが私は同じ問題に直面しているこの

listview = (ListView) findViewById(R.id.search_list); 
listview.setOnTouchListener(new View.OnTouchListener() { 
      public boolean onTouch(View v, MotionEvent event) { 
       if (event.getAction() == MotionEvent.ACTION_DOWN) { 
        v.getParent().requestDisallowInterceptTouchEvent(true); 
       } else if (event.getAction() == MotionEvent.ACTION_UP) { 
        v.getParent().requestDisallowInterceptTouchEvent(false); 

       } 
       return false; 
      } 
     }); 
関連する問題