package com.ifixit.android.sectionheaders;

import android.content.Context;

import android.util.AttributeSet;

import android.view.LayoutInflater;
import android.view.View;

import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.RelativeLayout;

public class SectionListView extends RelativeLayout implements
 AbsListView.OnScrollListener {
   private ListView mListView;
   private SectionHeadersAdapter mAdapter;
   private View mPinnedHeader;
   private int mHeaderPosition = -1;

   public SectionListView(Context context) {
      super(context);
      init(context);
   }

   public SectionListView(Context context, AttributeSet attrs) {
      super(context, attrs);
      init(context);
   }

   public SectionListView(Context context, AttributeSet attrs, int def) {
      super(context, attrs, def);
      init(context);
   }

   private void init(Context context) {
      LayoutInflater inflater = (LayoutInflater)context.getSystemService(
       Context.LAYOUT_INFLATER_SERVICE);

      inflater.inflate(R.layout.section_list_view, this, true);

      mListView = (ListView)findViewById(R.id.list_view);
   }

   public ListView getListView() {
      return mListView;
   }

   public void setAdapter(SectionHeadersAdapter adapter) {
      mAdapter = adapter;
      mListView.setAdapter(mAdapter);
      mListView.setOnScrollListener(this);
   }

   public void onScroll(AbsListView view, int firstVisibleItem,
    int visibleItemCount, int totalItemCount) {
      int headerPos;

      if ((headerPos = mAdapter.getHeaderPosition(firstVisibleItem)) !=
       mHeaderPosition) {
         mHeaderPosition = headerPos;
         injectPinnedHeader(mAdapter.getView(mHeaderPosition, mPinnedHeader,
          this));
      }

      int nextHeader = mAdapter.getNextHeaderPosition(firstVisibleItem);
      int nextHeaderChild = nextHeader - firstVisibleItem;
      int top;

      View nextView = mListView.getChildAt(nextHeaderChild);

      if (nextView == null) {
         return;
      }

      if (nextView.getTop() <= mPinnedHeader.getHeight()) {
         top = nextView.getTop();
      } else {
         top = mPinnedHeader.getHeight();
      }

      mPinnedHeader.layout(mPinnedHeader.getLeft(),
                           top - mPinnedHeader.getHeight(),
                           mPinnedHeader.getRight(),
                           top);
   }

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

   private void injectPinnedHeader(View header) {
      if (mPinnedHeader != null) {
         removeView(mPinnedHeader);
      }

      mPinnedHeader = header;
      RelativeLayout.LayoutParams layoutParams =
       new RelativeLayout.LayoutParams(
       RelativeLayout.LayoutParams.FILL_PARENT,
       RelativeLayout.LayoutParams.WRAP_CONTENT);

      addView(mPinnedHeader, layoutParams);
   }
}

@@ -1905,17 +1905,16 @@
 nt top;%0A
-%0A
       Vi
@@ -1971,74 +1971,171 @@
 );%0A%0A
+%0A
       
-if (nextView == null) %7B%0A         return;%0A      %7D%0A%0A      if (
+// Pin the header at the top if the next header is not in view or the%0A      // next header is %22pushing%22 the current header up%0A      if (nextView == null %7C%7C 
 next
@@ -2152,10 +2152,9 @@
 p() 
-%3C=
+%3E
  mPi
@@ -2194,31 +2194,39 @@
   top = 
-nextView.getTop
+mPinnedHeader.getHeight
 ();%0A    
@@ -2251,39 +2251,31 @@
   top = 
-mPinnedHeader.getHeight
+nextView.getTop
 ();%0A    

Fix header position bug when scrolling up