BigT
BigT

Reputation: 1433

Animate Listview to increase in size

I am trying to get an animation to work when I scroll my ListView. What I would like is when a user scrolls down to see more of the entries in the list the layout above it (A RelativeLayout) will shrink in size. I would like the RelativeLayout to only go as small as a quarter of the screen and only go as large as half the screen when scrolling.

The code I have now is jumpy and looks bad. I need a better solution to this issue

Here is the code I have so far

@Override
public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
    if(mLastFirstVisibleItem < firstVisibleItem){
        Display display = getActivity().getWindowManager().getDefaultDisplay();
        Point size = new Point();
        display.getSize(size);
        int screenHeight = size.y;

        System.out.println("Screen Height / 2: " + (screenHeight / 2));
        System.out.println("Balance Height 1: " + relBal.getHeight());
        if(relBal.getHeight() > (screenHeight / 2)){
            newBalHeight = (screenHeight / 2);
        }
        else {
            newBalHeight = relBal.getHeight() + 100;
        }

        System.out.println("Balance Height 2: " + newBalHeight);

        ResizeAnimation resize = new ResizeAnimation(relBal, relBal.getWidth(), relBal.getHeight(), relBal.getWidth(), newBalHeight);
        relBal.startAnimation(resize);
}
if(mLastFirstVisibleItem > firstVisibleItem){
    Display display = getActivity().getWindowManager().getDefaultDisplay();
    Point size = new Point();
    display.getSize(size);
    int screenHeight = size.y;

    System.out.println("Screen Height / 4: " + (screenHeight / 4));
    System.out.println("Balance Height: " + relBal.getHeight());
    if(relBal.getHeight() < (screenHeight / 4)){
                    newBalHeight = (screenHeight / 4);
    }
    else {
                    newBalHeight = relBal.getHeight() - 100;
    }

    System.out.println("Balance Height 2: " + newBalHeight);
    ResizeAnimation resize = new ResizeAnimation(relBal, relBal.getWidth(), relBal.getHeight(), relBal.getWidth(), newBalHeight);
    relBal.startAnimation(resize);
}
mLastFirstVisibleItem = firstVisibleItem;

}

This is what my page looks like

enter image description here

I want it to look like this when I scroll to see more items

enter image description here

Upvotes: 3

Views: 2077

Answers (2)

D V Ramana
D V Ramana

Reputation: 1176

I have put up an example project at https://github.com/ramanadv/ShrinkingHeader . Below is the logic I have used , its a little shaky because I haven't actually taken much care there. This is just to give you a direction . Don't use animation because OnScroll is called enough times to give you a smooth height change transition.

    list.setOnScrollListener(new OnScrollListener() {

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

        }

        @Override
        public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
            int scroll = getScroll(list);
            changeHeight(price,scroll);
            System.out.println("scroll "+scroll);
        }
    });

}

protected int getScroll(ListView listView) {// as list recycles views , getscrollY wont give us how much it has scrolled, hence we use this hack
    firstChildInList = listView.getChildAt(0);
    if(firstChildInList == null)return 0;
    return -firstChildInList.getTop() + listView.getFirstVisiblePosition() * firstChildInList.getHeight();
}

protected void setHeightForView(View v ,int h){ //  you need to set params to change height 
    LinearLayout.LayoutParams params = (LinearLayout.LayoutParams)v.getLayoutParams(); 
    params.height = h;
    v.setLayoutParams(params);
}
protected void changeHeight(View view,int scroll) { // this is a simple logic , this is a little shaky , but its simple , you can smoothen from here
    int priceHeight = price.getHeight();
    if(priceHeight>=screenHeight/4 && priceHeight<=screenHeight/2){
        setHeightForView(view, screenHeight/2-scroll);
    }
    else if(priceHeight < screenHeight/4){

    }
}

Upvotes: 3

Mikelis Kaneps
Mikelis Kaneps

Reputation: 4584

In OnScroll get the position of the child from the top and then according to the value change top margin for the headingView:

private OnScrollListener scrollListener = new OnScrollListener() {
        private boolean userScrolled = false;

        public void onScrollStateChanged(AbsListView view, int scrollState) {
            if (scrollState == 1) {
                userScrolled = true;
            }
        }

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

            if (userScrolled) {
                secondChildFromTop = view.getChildAt(1).getTop();// From this value it is going to be easy to know if the scrolling is happening up or down
             methodThatChangesTheTopMarginForYourView(secondChildFromTop);
}
}
}
private void methodThatChangesTheTopMarginForYourView(int value){
        ViewGroup.MarginLayoutParams params =
        (ViewGroup.MarginLayoutParams)yourHeadingView.getLayoutParams();
        //some mathematical logic with the value param.
        params.topMargin = //add negative value so the view goes outside of the screen, and the orginal value to get it back in original position


}

Upvotes: 2

Related Questions