2015-09-17 13 views
8

Ben ScrollView bir ListView yorumlarınızı göstermek zorunda ve ben aşağıdakileri yapmak istiyorum:Geçiş hareket olayı/

kullanıcı ilk ScrollView gerektiğini tam olarak kaydırma, aşağı ucuz bira zaman liste en altta olduğu gibi. Tamamen kapalı olduğunda, Listiew kaydırma işlemine başlamalıdır.

Benzer şekilde, kullanıcı yukarı doğru kaydırırken, ScrollView kaydırılmaya başlamadan önce, önce ListView (burada tersine çevrilmiş!) Kaydırılmalıdır.

listView.setOnTouchListener(new View.OnTouchListener() { 
     // Setting on Touch Listener for handling the touch inside ScrollView 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 

      // If going up but the list is already at up, return false indicating we did not consume it. 
      if(event.getAction() == MotionEvent.ACTION_UP) { 
       if (listView.getChildCount() == 0 && listView.getChildAt(0).getTop() == 0) { 
        Log.e("Listview", "At top!"); 
        return false; 
       } 
      } 

      // Similar behaviour but when going down check if we are at the bottom. 
      if(event.getAction() == MotionEvent.ACTION_DOWN) { 
       if (listView.getLastVisiblePosition() == listView.getAdapter().getCount() - 1 && 
         listView.getChildAt(listView.getChildCount() - 1).getBottom() <= listView.getHeight()) { 
        Log.e("Listview","At bottom!"); 
        v.getParent().requestDisallowInterceptTouchEvent(false); 
        return false; 
       } 
      } 
      v.getParent().requestDisallowInterceptTouchEvent(true); 
      return false; 
     } 
    }); 

günlükleri doğru anda tetikler, ancak ScrollView ben return false halde hareket etmeyecektir:

Şimdiye kadar aşağıdaki yaptık.

Ayrıca, ifadelere v.getParent().requestDisallowInterceptTouchEvent(false); eklemeye çalıştım, ancak bu da işe yaramadı.

Nasıl çalıştırabilirim?

+0

. Ben iki NestedScrollView – PeonProgrammer

+0

kullanarak sona erdi Ben de NestedScrollView sınıfına baktım, ama diğer konuları üzerinde işaret edildiği gibi liste görünümleri bazı ek işlevleri var örneğin bir scrollview – Gooey

+0

içinde bir LinearLayout içinde yerine Ben bir ListView içinde bir başlık görünümü kullanmanızı öneririm ScrollView içinde bir ListView yuvalama - İç içe geçmiş kaydırma kapsayıcılar pre-RecyclerView biraz acı verici. –

cevap

8

Bir özel ScrollView ve ListView oluşturmak ve bunun gibi

onInterceptTouchEvent(MotionEvent event) 

geçersiz kılabilirsiniz:

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    View view = (View) getChildAt(getChildCount()-1); 
    int diff = (view.getBottom()-(getHeight()+getScrollY())); 

    if(event.getAction() == MotionEvent.ACTION_DOWN) { 
     if (diff ==0) { 
      return false; 
     } 
    } 

    return super.onInterceptTouchEvent(event); 
} 

ListView her Aşağı dokunun ScrollView dibinde iken gidecek Bu şekilde ListView.

Bu sadece bir karalama uygulamasıdır ama bir not olarak ListView

üstündeki geçerlidir diye kullanarak daha kolay bir uygulama denemek istiyorum algılamak için aynı şeyi yaparak bu Başlamak düşünüyorum Sadece ListView geçerli içeriğiniz ile ScrollViewlistView.addHeaderView(scrollViewContent) kullanarak ListView başlığı olarak eklendi.Bunun sizin ihtiyaçlarınız için uygun olup olmadığını bilmiyorum.

DÜZENLEME:

ScrollView kaydırma başlamalıdır zaman algılama. ScrollView'da ListView referansının tutulması. Kullanıcı yukarı doğru ilerlediğinde ve ListView en üstte olduğunda olayın ScrollView tarafından tüketilmesine izin verin. ListView

private void init(){ 
    ViewConfiguration vc = ViewConfiguration.get(getContext()); 
    mTouchSlop = vc.getScaledTouchSlop(); 
} 

@Override 
public boolean onInterceptTouchEvent(MotionEvent event) { 
    final int action = MotionEventCompat.getActionMasked(event); 

    switch (action) { 
     case MotionEvent.ACTION_DOWN:{ 
      yPrec = event.getY(); 
     } 
     case MotionEvent.ACTION_MOVE: { 
      final float dy = event.getY() - yPrec; 

      if (dy > mTouchSlop) { 
       // Start scrolling! 
       mIsScrolling = true; 
      } 
      break; 
     } 
    } 

    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { 
     mIsScrolling = false; 
    } 

    // Calculate the scrolldiff 
    View view = (View) getChildAt(getChildCount()-1); 
    int diff = (view.getBottom()-(getHeight()+getScrollY())); 

     if ((!mIsScrolling || !listViewReference.listIsAtTop()) && diff == 0) { 
      if (event.getAction() == MotionEvent.ACTION_MOVE) { 
       return false; 
      } 
    } 

    return super.onInterceptTouchEvent(event); 
} 

@Override 
public boolean onTouchEvent(MotionEvent ev) { 
    final int action = MotionEventCompat.getActionMasked(ev); 
    if (action == MotionEvent.ACTION_CANCEL || action == MotionEvent.ACTION_UP) { 
     mIsScrolling = false; 
    } 
    return super.onTouchEvent(ev); 
} 


public void setListViewReference(MyListView listViewReference) { 
    this.listViewReference = listViewReference; 
} 

yöntem listIsAtTop şuna benzer: Ben bunu (benim Scrollview bir liste görünümü iç içe) denedim ve işe alamadım

public boolean listIsAtTop() { 
    if(getChildCount() == 0) return true; 
    return (getChildAt(0).getTop() == 0 && getFirstVisiblePosition() ==0); 
} 
+0

Bu yaklaşımdaki sorun, liste görünümü ve scrollview arasında dairesel bir bağımlılık olmasıdır. Touch intercept yöntemiyle bir şey yapmayı denedim, ancak yukarı kaydırırken sıra tersine döndüğünde, liste görünümü ilk olarak yapılırsa scrollview'in "check-out" yapması gerekiyor. – Gooey

+0

Cevabımdaki düzenlemeye göz atın. Bir test yaptım ve işe yarıyor ama bunu başarmaya çalıştığınız şey olduğundan emin değilim. Sadece kaydırma görünümünde liste görünümüne bir başvuru yapmanız gerekir. Kod, bazı ekstra düzenleme ve temizlik gerektirebilir. – GeorgeP

0

Bu deneyin: Scrollview Tabanda ulaştıysa

  1. İlk bulabilirsiniz. ListView Top az ulaşmanız durumunda Kaydırma görüntüsü

    @Override 
    protected void onScrollChanged(int l, int t, int oldl, int oldt) 
    { 
        // Grab the last child placed in the ScrollView, we need it to determinate the bottom position. 
        View view = (View) getChildAt(getChildCount()-1); 
    
        // Calculate the scrolldiff 
        int diff = (view.getBottom()-(getHeight()+getScrollY())); 
    
        // if diff is zero, then the bottom has been reached 
        if(diff == 0) 
        { 
         // notify that we have reached the bottom 
         // Add code here to start scrolling the ListView 
         Log.d(ScrollTest.LOG_TAG, "MyScrollView: Bottom has been reached"); 
        } 
    
        super.onScrollChanged(l, t, oldl, oldt); 
    } 
    
  2. kontrol etmek onScrollChanged kaydol. firstVisibleItem 0 olup olmadığını kontrol edin: -

    tableListView.setOnScrollListener(new OnScrollListener() { 
    
         public void onScrollStateChanged(AbsListView view, int scrollState) { 
    
         } 
    
         public void onScroll(AbsListView view, int firstVisibleItem, 
           int visibleItemCount, int totalItemCount) { 
          if (visibleItemCount == 0) 
          // you have reached at top of lustView 
          { 
           java.lang.System.out.println("you have reached at top of lustView!"); 
          } 
          else { 
           if ((firstVisibleItem + visibleItemCount) == totalItemCount) { 
            // put your stuff here 
            java.lang.System.out.println("end of the line reached!"); 
           } 
          } 
    
         } 
        }); 
    

Bunun sizin için işe yarar. Herhangi bir sorunla karşılaşırsanız lütfen bana bildirin.

+0

En üst veya en alt noktaya ulaşıp ulaşmadığımı algılamak benim kodumun zaten yaptığı şeydir, ancak bu duruma bağlı olarak hareketli olayları ana kaydırma görünümüne iletmek istiyorum. – Gooey

4

ListView'i ScrollView içine koymamalısınız, ancak gereksiniminizi ExpandableHeightListView kullanarak gerçekleştirebilirsiniz. Bu ScrollView içinde tam yükseklik Listview yapacak. TouchListener'a gerek yok. senin şartı sağlamak için

<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical"> 

    <LinearLayout 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content" 
     android:orientation="vertical"> 

     <RelativeLayout 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" > 
      <!-- your content --> 
     </RelativeLayout> 

     <my.widget.ExpandableHeightListView 
      android:layout_width="match_parent" 
      android:layout_height="wrap_content" /> 
    </LinearLayout> 
</ScrollView> 

Ve başka yolu başlığıyla RecyclerView olduğunu.

+0

Çalışırken, gerçekten istediğim şey bu değil. Bu sadece içeriğin altındaki tüm öğeleri gösterir, o zaman bir LinearLayout içinde görünümleri de atabilir. – Gooey