动画Listview增加大小

时间:2021-08-29 22:54:34

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.

当我滚动ListView时,我试图让动画工作。我想要的是当用户向下滚动以查看列表中的更多条目时,其上方的布局(A RelativeLayout)将缩小。我希望RelativeLayout只能小到屏幕的四分之一,滚动时只能达到屏幕的一半。

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

这就是我的页面的样子

动画Listview增加大小

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

当我滚动查看更多项目时,我希望它看起来像这样

动画Listview增加大小

2 个解决方案

#1


3  

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.

我在https://github.com/ramanadv/ShrinkingHeader上建立了一个示例项目。以下是我使用的逻辑,它有点不稳定,因为我实际上并没有那么在意。这只是为了给你一个方向。不要使用动画,因为OnScroll被调用足够的时间来为您提供平滑的高度变化过渡。

    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){

    }
}

#2


2  

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

在OnScroll中,从顶部获取子项的位置,然后根据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


}

#1


3  

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.

我在https://github.com/ramanadv/ShrinkingHeader上建立了一个示例项目。以下是我使用的逻辑,它有点不稳定,因为我实际上并没有那么在意。这只是为了给你一个方向。不要使用动画,因为OnScroll被调用足够的时间来为您提供平滑的高度变化过渡。

    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){

    }
}

#2


2  

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

在OnScroll中,从顶部获取子项的位置,然后根据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


}