在自定义的ScrollView中更改视图高度的onScrollChanged方法

3

我正在尝试制作以下效果:

example

我有一个自定义的ScrollView(为了获得onScrollChanged监听器),以及其中的一个自定义View。在自定义View中,我成功地将项目放置在我想要的位置。

这是我的customView:

public class CustomView extends FrameLayout {

private TextView nameView;
private TextView emailView;
private ImageView addressView;
private Tracks track ;
private double scrollProgress = 0.0;
private double topViewScaleFactor = 2.0;
private double collapsedViewHeight = 200.0;
private double expandedViewHeight = 700.0; 
private double scrollProgressPerView = expandedViewHeight;

View v;
View firstItem;
View secondView;


          int itemMinHeight = 200;
          int itemMaxHeight = 700;

public CustomView(MyScrollView paramEventListView, Context paramContext){

           super(paramContext);
}        



public CustomView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub

}


public CustomView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    // TODO Auto-generated constructor stub

}


public CustomView(Context context, AttributeSet attrs) {
    super(context, attrs);
    // TODO Auto-generated constructor stub

}

    @Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
    // TODO Auto-generated method stub
    int m = getMeasuredWidth();


         int itemWidth = (r-l)/getChildCount();
       //  int itemHeight = (b-t)/getChildCount();


         firstItem = getChildAt(0);
        //firstItem.layout(0, 0, r-l, itemMaxHeight);
         firstItem.measure(View.MeasureSpec.makeMeasureSpec(m, MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(itemMaxHeight, MeasureSpec.EXACTLY));
         firstItem.layout(0, 0, r-l, itemMaxHeight);

         secondView = getChildAt(1);
         secondView.measure(View.MeasureSpec.makeMeasureSpec(m, MeasureSpec.EXACTLY), View.MeasureSpec.makeMeasureSpec(itemMinHeight, MeasureSpec.EXACTLY));
         secondView.layout(0, itemMaxHeight, r-l, itemMinHeight+itemMaxHeight);

         int FirstAndSEcondItemHeight = firstItem.getHeight() + secondView.getHeight();
         for(int i=2; i< this.getChildCount(); i++){
              v = getChildAt(i);
          //  v.layout(itemWidth*i, 0, (i+1)*itemWidth, b-t); 

             v.layout(0, FirstAndSEcondItemHeight + (itemMinHeight*(i-2)), r-l, FirstAndSEcondItemHeight + ((i-1)*itemMinHeight)); 
         }


}


    @Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    // TODO Auto-generated method stub
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);



    int heightMeasured = 0;
    /*for each child get height and
    heightMeasured += childHeight;*/
     for(int i=0; i< this.getChildCount(); i++){
         heightMeasured += getChildAt(i).getHeight();
     }

    //If I am in a scrollview i got heightmeasurespec == 0, so
    if(heightMeasureSpec == 0){
    heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightMeasured, MeasureSpec.EXACTLY);
    }

    setMeasuredDimension(getDefaultSize(getSuggestedMinimumWidth(), widthMeasureSpec), getDefaultSize(this.getSuggestedMinimumHeight(), heightMeasureSpec));
}

以下是我的自定义ScrollView代码:

public class MyScrollView extends ScrollView{



public MyScrollView(Context context) {
    super(context);

}

public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    add(context);
} 

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

public void setScrollViewListener(ScrollViewListener scrollViewListener) {
    this.scrollViewListener = scrollViewListener;


}
@Override
protected void onScrollChanged(int x, int y, int oldx, int oldy) {
    super.onScrollChanged(x, y, oldx, oldy);

 // How can I acces to each child in the customView class, and change their height depending on the scrollChanged


}

现在,我需要在滚动scrollview时更改项目的高度。我不知道在onScrollChanged中应该放什么...... 如果有人有想法,请告诉我,谢谢。


嘿!我也需要实现同样的东西。你能告诉我你最终做了什么吗? - gitter
1个回答

0
也许你想通过调用invalidate()来强制重绘视图?
从评论中:我认为你需要将代码移到onMeasure方法中,以替换“TODO”存根,这样在操作之后才会调用super.onMeasure()。并确保将新的宽度/高度计算传递给它。

也许 :) 我需要把invalidate()放在哪里? 是放在OnScrollChanged还是覆盖onDraw()方法中? - Chol
Invalidate会自己调用onDraw,所以你不想把它放在那里。我建议在onScrollChanged中执行此操作。当然,这是假设视图在重新绘制时会重新计算每个子元素的高度。 - JstnPwll
实际上,我成功地改变了一个项目视图的高度;但是包含所有项目的视图组,我无法改变它的高度,即使其中一个子元素的高度比开始时更大,它也不会移动... 我需要在onSizeChanged(..)上做些什么吗? - Chol
我认为你需要将代码移动到onMeasure方法中,以替换“TODO”存根,这样在你的操作之后才会调用super.onMeasure()。并确保将新的宽度/高度计算传递给它。 - JstnPwll
实际上我做了一些不太好的事情,我的意思是没有回收。所以它只适用于少量项目(大约10个)。我的custoView是一个viewGroup,我只是将项目添加到其中。对于动画效果:我知道总共有10个项目x itemMaxHeight。根据scrollY,我检查所有项目位置,并使当前显示的项目的线性布局变大。很难解释,但我知道这不是正确的方法,我仍在寻找更好的解决方案。 - Chol
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接