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
这就是我的页面的样子
I want it to look like this when I scroll to see more items
当我滚动查看更多项目时,我希望它看起来像这样
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
}