2012-02-27 5 views

risposta

9

Sono stato in grado di risolvere questo problema utilizzando il listener di scorrimento in listview. (testato su 2.1)

Diciamo che per ogni riga di elenco ho un layout come quello qui sotto. C'è una parte di contenuto e una parte di intestazione. Non importa quale tipo di vista usi per intestazione o contenuto.

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" android:background="#FFFFFF"> 

    <ImageView 
     android:id="@+id/content" 
     android:layout_width="fill_parent" 
     android:layout_height="300dp" 
     android:scaleType="centerCrop" 
     android:src="@drawable/pic" 
     android:background="#aaaaff" 
     android:layout_marginTop="40dp"/> 

    <TextView 
     android:id="@+id/header" 
     android:layout_width="fill_parent" 
     android:layout_height="40dp" 
     android:padding="12dp" 
     android:text="Deneme Row" 
     android:textColor="#000000" 
     android:background="#99ffffff"/> 
</RelativeLayout> 

Il dispositivo di controllo per l'attività è come il seguente:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical" > 

    <ListView 
     android:id="@+id/list" 
     android:layout_width="fill_parent" 
     android:layout_height="fill_parent" > 
    </ListView> 
</LinearLayout> 

Infine il codice per l'attività è riportata qui sotto. Qui dovevo avere un adattatore che utilizza ViewHolder per memorizzare la vista dell'intestazione e anche una variabile per tenere traccia del cambiamento nello scroll per ogni evento di scorrimento successivo (precedenteTop). Ciò è dovuto al fatto che offsetTopAndBottom() modifica l'offset della vista relativa alla posizione precedente di esso.

public class TestActivity extends Activity implements AbsListView.OnScrollListener{ 

    ListView list; 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 
     list = (ListView) findViewById(R.id.list); 
     list.setAdapter(new Adapter(this));   
     list.setOnScrollListener(this); 
    } 

    @Override 
    public void onScroll(AbsListView view, int firstVisibleItem, 
      int visibleItemCount, int totalItemCount) {  
     //the listview has only few children (of course according to the height of each child) who are visible 
     for(int i=0; i < list.getChildCount(); i++){ 
      View child = list.getChildAt(i); 
      ViewHolder holder = (ViewHolder) child.getTag(); 

      //if the view is the first item at the top we will do some processing 
      if(i == 0){    
       boolean isAtBottom = child.getHeight() <= holder.header.getBottom(); 
       int offset = holder.previousTop - child.getTop(); 
       if(!(isAtBottom && offset > 0)){      
        holder.previousTop = child.getTop(); 
        holder.header.offsetTopAndBottom(offset);     
        holder.header.invalidate(); 
       } 
      } //if the view is not the first item it "may" need some correction because of view re-use 
      else if (holder.header.getTop() != 0) { 
       int offset = -1 * holder.header.getTop(); 
       holder.header.offsetTopAndBottom(offset); 
       holder.previousTop = 0; 
       holder.header.invalidate(); 
      } 
     } 
    } 

    @Override 
    public void onScrollStateChanged(AbsListView view, int scrollState) {} 

    private static class Adapter extends ArrayAdapter<String> { 
     public Adapter(Context context) { 
      super(context, R.layout.row, R.id.header); 
      for(int i=0; i < 50; i++){ 
       add(Integer.toString(i)); 
      } 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 
      if(convertView == null){ 
       convertView = LayoutInflater.from(getContext()).inflate(R.layout.row, parent, false); 
       ViewHolder holder = new ViewHolder(); 
       holder.header = (TextView) convertView.findViewById(R.id.header); 
       convertView.setTag(holder);    
      } 
      ViewHolder holder = (ViewHolder) convertView.getTag(); 
      holder.header.setText(getItem(position)); 
      return convertView; 
     } 
    } 

    private static class ViewHolder { 
     TextView header; 
     int previousTop = 0; 
    } 
} 
+0

Hey siyamed, Questo è molto utile. Nel mio caso ho un altro ListView (figlio) all'interno di ListView (Parent). quindi l'intestazione non funziona correttamente quando si scorre-Down .... – ashish2py

+0

Se non ci sono dati in child-listview, allora funziona correttamente .. > sample app https://bitbucket.org/ashish2py/instagramheader – ashish2py

+0

Lo proverò. Grazie! –

0

Se si utilizza la visualizzazione elenco, sono disponibili 2 viste all'interno dell'elemento dell'elenco. Uno è intestazione e altro è in realtà oggetto.

Nascondere inizialmente la vista dell'intestazione e mentre lo stato di scorrimento cambia o l'utente tocca la voce dell'elenco modifica la visibilità dell'intestazione.

0

Dopo il setcontentview fare qualcosa come il codice qui sotto.

ListView list = getListView(); 
    View footer = getLayoutInflater().inflate(R.layout.footerlayout, list, false); 
    View header = getLayoutInflater().inflate(R.layout.headerlayout, list, false); 
    list.addHeaderView(header); 
    list.addFooterView(footer); 
1

ho migliorato la domanda di Siyamed un po 'in modo che l'intestazione non è andato quando la vista viene ridisegnato per esempio se una bitmap nella voce di ListView è cambiato.

Invece di utilizzare le coordinate relative all'ultima posizione, utilizzo le coordinate relative alla parte superiore della vista e utilizzo il riempimento anziché gli offset.

@Override 
public void onScroll(AbsListView absListView, int firstVisibleItem, int visibleItemCount, int totalItemCount) { 

    for(int i=0; i < list.getChildCount(); i++){ 
     View child = list.getChildAt(i); 
     ViewHolder holder = (ViewHolder) child.getTag(); 

     if(i == 0){ 
      try { 
       boolean isAtBottom = child.getHeight() <= holder.movingHeader.getBottom(); 
       if(!(isAtBottom)){ 
        if (child.getTop() >= 0){} 
        else if (child.getHeight() - movingHeader.getHeight() - 1 > -child.getTop()) 
        { 
         holder.movingHeader.setPadding(0, -child.getTop(), 0, 0); 
         holder.movingHeader.invalidate(); 
        } 
        else { 
         holder.movingHeader.setPadding(0, child.getHeight() - movingHeader.getHeight(), 0, 0); 
         holder.movingHeader.invalidate(); 
        } 
       } 
      } 
      catch (Exception e) 
      { 
       e.printStackTrace(); 
      } 
     } 
     else if (holder.movingHeader.getPaddingTop() != 0) 
     { 
      holder.movingHeader.setPadding(0, 0, 0, 0); 
      holder.movingHeader.invalidate(); 
     } 
    } 
}