Larphoid
Larphoid

Reputation: 1005

overscroll listview bottom not working

EDIT: been working on it recently again and got it working, so don't need an answer anymore. link

I've made an overscrollable listview and everything works except when you scroll beyond the last item with the direction pad/trackball. When scrolling with finger on screen, all the checking for top and bottom overscrolling work, even when scrolling with d-pad/trackball beyond the first item in the list... but just not the bottom side. That's why it's freaking me out, cuz the other checks all work... i'm not posting the whole activity cuz it's pretty big, i'll just post what i think is necesarry. All the checking is done in the OverscrollListview class.

Activity:

package com.somepackage;

public class SomeActivity extends ListActivity
{
  private OverscrollListview mNotesList;
    protected void onCreate(Bundle savedInstanceState)
    {
      mNotesList = (OverscrollListview) findViewById(android.R.id.list);
      /* just a view in xml that can be sized so that the header and footer are always
         the height of the complete screen no matter what device it runs on ...
      */
      header = LayoutInflater.from(this).inflate(R.layout.listview_overscrollview, null);
      header.findViewById(R.id.overscroll)
        .setMinimumHeight(getWindowManager()
        .getDefaultDisplay()
        .getHeight());
      mNotesList.addHeaderView(header, null, false);
      mNotesList.addFooterView(header, null, false);
      mNotesList.setOnScrollListener(mNotesList);
      mNotesList.setAdapter(mainadapter);
      populateNotesList();
    }
  ...
}

public void populateNotesList()
{
  ...
  // whenever the listview gets populated, these values need to be 0 again
  mNotesList.item = mNotesList.itemOffset = 0;
}

The overscrollview class:

package com.somepackage;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import android.widget.AbsListView;
import android.widget.ListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.Toast;

public class OverscrollListview extends ListView implements OnScrollListener
{
    public int item = 0, itemOffset = 0, first = 0, count = 0, total = 0;
    private int currentScrollState = OnScrollListener.SCROLL_STATE_IDLE;
    private Handler mHandler = new Handler();
    private Toast toast;
    private View  listitem;


    public OverscrollListview(Context context, AttributeSet attrs, int defStyle)
    {
        super(context, attrs, defStyle);
        toast = Toast.makeText(context, "", Toast.LENGTH_LONG);
    }

    public OverscrollListview(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        toast = Toast.makeText(context, "", Toast.LENGTH_LONG);
    }

    public OverscrollListview(Context context)
    {
    super(context);
        toast = Toast.makeText(context, "", Toast.LENGTH_SHORT);
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)
    {
    first = firstVisibleItem;
    count = visibleItemCount;
    total = totalItemCount;
      mHandler.postDelayed(checkListviewTopAndBottom, 100);
    }

    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState)
    {
    currentScrollState = scrollState;
      mHandler.postDelayed(checkListviewTopAndBottom, 100);
    }

    private final Runnable checkListviewTopAndBottom = new Runnable()
    {
    @Override
    public void run() {
        toast.setText("first="+first+"\ncount="+count+"\nlast="+getLastVisiblePosition()+"\ntotal="+total+"\nitem="+item);
        toast.show();
        if ( getCount() <= 2 ) return; // do nothing, listview has no items, only header & footer
        if ( currentScrollState != OnScrollListener.SCROLL_STATE_IDLE ) return; // do nothing, still scrolling
        if ( getFirstVisiblePosition() < 1 ) {
        setSelectionFromTop(1, getDividerHeight());
        return;
        }
        if ( getLastVisiblePosition() == getCount()-getHeaderViewsCount() ) {
        if ( item == 0 ) {
            if ( getFirstVisiblePosition() < 1 ) {
            item  = 1;
            itemOffset = getDividerHeight();
            } else {
            item  = getCount()-getHeaderViewsCount();
            listitem = getChildAt(item);
            if ( listitem != null ) {
                itemOffset = getHeight()-listitem.getHeight()+getDividerHeight();
            } else {
                itemOffset = getHeight()+getDividerHeight();
            }
            }
            }
        //toast.setText("LastVisPos()==getCount()-1\nitem="+item+"\nitemOffset="+itemOffset);
        //toast.show();
            if ( item == getCount()-getHeaderViewsCount() || (item == 1 && getFirstVisiblePosition() < 1) ) {
                setSelectionFromTop(item, itemOffset);
            }
        }
    }
    };
}

Although the majority of it works, which i can live with, i'd appreciate if somebody could see what's going wrong cuz it's just buggin' me...

thanks.

Upvotes: 2

Views: 1783

Answers (1)

Prizoff
Prizoff

Reputation: 4575

This is not answers your main quesion, just wanted to leave some notes.

The height of the header/footer may be set in this way:

public class OverscrollListview extends ListView implements OnScrollListener
{
    // ...

    @Override
    protected void layoutChildren() {
        View v = findViewById(R.id.HEADER_VIEW_ID);
        ViewGroup.LayoutParams lp = v.getLayoutParams();
        lp.height = getHeight();
        v.setLayoutParams(lp);

        v = findViewById(R.id.FOOTER_VIEW_ID);
        v.setLayoutParams(lp);

        super.layoutChildren();
    }
}

It seems this is more convenient way. In this way the height of header/footer can be set to the height of its LsitView.

Upvotes: 1

Related Questions