网易美聊效果的仿照实现

实现思路:自定义一个ScrollView,在scroll的时候将滑动到的位置,当前的手势回传处理:滑动的过程判断滑到那两个View之间,上边的View压缩(设置LayoutParams,其高为当前标准高*放大倍数-滑动距离+之前滑过View的总高度),下边的view拉伸(设置LayoutParams,其高为当前标准高+滑动距离-之前滑过的View的总高度)
记录在探索ScrollView控件使用过程的问题

  • 关于如何判断是否在Scroll的顶部和底部

    LinearLayout ll;//ll为ScrollView的唯一子控件
    
    public void onWindowFocusChanged(boolean hasWindowFocus) {
        if(hasWindowFocus){
             ll= (LinearLayout) getChildAt(0);
            //得到子View的高度
            android.util.Log.i("___+", "ll.getMeasuredHeight()"+ll.getMeasuredHeight()/3);
            //表示得到y轴的滚动距离
            android.util.Log.i("___+", "getScrollY()"+getScrollY()/3);
            //getHeight()为scrollView的高度。
            android.util.Log.i("___+", "getHeight()"+getHeight()/3);
            //当getScrollY()达到最大时加上scrollView的高度就的就等于它内容的高度了
    
        }
    };
    
    `protected void onScrollChanged(int l, int t, int oldl, int oldt) {`
    
        if(ll!=null&&ll.getMeasuredHeight()==getHeight()+getScrollY()&&!inBottom){
        //if(getScrollY()==computeVerticalScrollRange()){没生效
            inBottom=true;
            Toast.makeText(context, "到底了", 1000).show();
        }else if(getScrollY()==0){
            Toast.makeText(context, "到顶了", 1000).show();
        }else{
            inBottom = false;
        }
    };
    

- 自定义ScrollView,监听滑动,手势抬,手势落

   public class RankScrollView extends ScrollView implements View.OnTouchListener{

    @Override
    public void fling(int velocityY) {
        // TODO Auto-generated method stub
        // 减速,防止滑动过快
        super.fling(velocityY/8);
    }

    private Context context;
    private GestureDetector getsture;

    public RankScrollView(Context context, AttributeSet attrs,
            int defStyle) {
        super(context, attrs, defStyle);
        this.context = context;
        //代码中设置是否显示滚动条,在xml中设置android:scrollbars="horizontal"配合setVerticalScrollBarEnabled(true)效果起来。
        setVerticalScrollBarEnabled(true);
        setOnTouchListener(this);
        getsture = new GestureDetector(context,getstureListener);
    }

    private boolean BEFORE_UP_ACITION_UP = false;

    @Override
    public boolean onTouch(View v, MotionEvent event) {

        /**
         * 指定scrollView滚动到底部或者顶部
         */
        //scrollView.fullScroll(ScrollView.FOCUS_DOWN);滚动到底部
        //scrollView.fullScroll(ScrollView.FOCUS_UP);滚动到顶部
        switch (event.getAction()) {
        case MotionEvent.ACTION_UP:
            onScrollChangeListener.onaction_Up(BEFORE_UP_ACITION_UP);
            break;
        case MotionEvent.ACTION_DOWN:
            onScrollChangeListener.onaction_Down();
            break;
        case MotionEvent.ACTION_MOVE:
            onScrollChangeListener.onaction_Down();
            break;
        default:
            break;
        }
        return getsture.onTouchEvent(event);
    }

    private onScrollChange onScrollChangeListener;

    public interface onScrollChange{
        public void onUp(int oldt,int t);
        public void onDown(int oldt,int t);
        public void currentIndex(int scrollY);
        public void onaction_Up(boolean isUp);
        public void onaction_Down();
    }

    public void setOnScrollChange(onScrollChange onScrollChangeListener){
        this.onScrollChangeListener = onScrollChangeListener;
    }

    GestureDetector.SimpleOnGestureListener getstureListener = new SimpleOnGestureListener(){

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
            // TODO Auto-generated method stub
            if(distanceY>0){
                //下滑
                BEFORE_UP_ACITION_UP = false;
                android.util.Log.i("","distanceY"+distanceY);
            }else{
                //上滑
                BEFORE_UP_ACITION_UP = true;
                android.util.Log.i("","distanceY"+distanceY);
            }
            return super.onScroll(e1, e2, distanceX, distanceY);
        }

    };
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        onScrollChangeListener.currentIndex(getScrollY());
        android.util.Log.i("","getScrollY"+getScrollY());
        if(oldt<t){
            onScrollChangeListener.onDown(oldt,t);
        }else{
            onScrollChangeListener.onUp(oldt,t);
        }
    };

- 在自定义的ScrollView中加入若干等高的布局,滑动过程中临近的子布局有缩放效果

public class RankActivity extends Activity implements RankScrollView.onScrollChange,View.OnClickListener{
RankScrollView mScrollView;
LinearLayout rankHot,rankRich,rankCharm,rankSuperStar,rankWeekStar;
LinearLayout collectLin,expendLin;
LayoutParams collectParams;
LayoutParams expendParams;
LayoutParams normalParams;
private int SINGLE_ITEM_HEIGHT;
private int Double_Item_Height_index = 0;
private final int SCALE =2;//放大倍数和正常高度的比例。
private int mScrollY = 0;
private LinearLayout llImageViews;
private int totalHeight;
private int disableScrollHeight=0;
private boolean isLastItem = false;
private boolean isDownDirection = true;
private int mPostion = 0;
private int contentTop;
private int t;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_rank);
    SINGLE_ITEM_HEIGHT = DisplayUtils.dp2px(100);
    mScrollView = (RankScrollView) findViewById(R.id.id_scroll_contain);
    mScrollView.setOnScrollChange(this);
    rankHot = (LinearLayout) findViewById(R.id.id_rank_hot);
    rankRich = (LinearLayout) findViewById(R.id.id_rank_rich);
    rankCharm = (LinearLayout) findViewById(R.id.id_rank_charm);
    rankSuperStar = (LinearLayout) findViewById(R.id.id_rank_superstar);
    rankWeekStar = (LinearLayout) findViewById(R.id.id_rank_weekstar);
    rankHot.setOnClickListener(this);
    rankRich.setOnClickListener(this);
    rankCharm.setOnClickListener(this);
    rankSuperStar.setOnClickListener(this);
    rankWeekStar.setOnClickListener(this);
    expendParams = new LayoutParams(LayoutParams.MATCH_PARENT,SINGLE_ITEM_HEIGHT*SCALE);
    rankHot.setLayoutParams(expendParams);
    llImageViews = (LinearLayout) findViewById(R.id.child1);
    normalParams = new LayoutParams(LayoutParams.MATCH_PARENT,SINGLE_ITEM_HEIGHT);
    requestTopThreeHead();
}

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (hasFocus) {
        //设置填充view的高度,scrollView高度除了子项外还需要一个空的布局,使最后一个子项能滑动到顶部
        totalHeight = llImageViews.getHeight();
        contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT,getResources().getDisplayMetrics().heightPixels-getTitleLayerHeight()-getStatusLayerHeight()-SCALE*SINGLE_ITEM_HEIGHT);
        findViewById(R.id.id_fill_in_view).setLayoutParams(params);
    }
}

// 得到状态栏高度
private int getStatusLayerHeight() {
    Rect frame = new Rect();
    getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
    int statusBarHeight = frame.top;// 60px
    return statusBarHeight;
}

// 得到标题栏高度
private int getTitleLayerHeight() {
    int contentTop = getWindow().findViewById(Window.ID_ANDROID_CONTENT).getTop();
    // statusBarHeight是上面所求的状态栏的高度
    int titleBarHeight = contentTop - getStatusLayerHeight();// 144px\
    return titleBarHeight;
}


@Override
public void onUp(int oldt, int t) {
    this.t = t;
    onUpImplements(oldt, t);
}

private void onUpImplements(int oldt, int t) {
    isDownDirection = false;
    //使用scrollTo的时候注掉
    /**
     * if(mScrollY<=0){
        //防止第一个无限度放大
        return;
    }
     */

//      if(mScrollY>=disableScrollHeight+SINGLE_ITEM_HEIGHT){
//          //防止最后一个个无限度放大
//          return;
//      }
    reSetHeight();
    // 压缩第一个的比例
    collectParams = new LayoutParams(LayoutParams.MATCH_PARENT, SINGLE_ITEM_HEIGHT*SCALE - t + SINGLE_ITEM_HEIGHT*Double_Item_Height_index);
    collectLin.setLayoutParams(collectParams);
    // 拉伸第二个的比例
    expendParams = new LayoutParams(LayoutParams.MATCH_PARENT,SINGLE_ITEM_HEIGHT + t - SINGLE_ITEM_HEIGHT*Double_Item_Height_index);
    expendLin.setLayoutParams(expendParams);
}

@Override
public void onDown(int oldt, int t) {
    this.t = t;
    onDownImplements(oldt, t);
}

private void onDownImplements(int oldt, int t) {
    isDownDirection = true;
    if((mScrollY>=disableScrollHeight+SINGLE_ITEM_HEIGHT&&disableScrollHeight>0)||mScrollY>=4*SINGLE_ITEM_HEIGHT){
        //防止最后一个个无限度放大
        return;
    }
    reSetHeight();
    // 拉伸后一个的比例
    expendParams = new LayoutParams(LayoutParams.MATCH_PARENT,SINGLE_ITEM_HEIGHT + t-SINGLE_ITEM_HEIGHT*Double_Item_Height_index);
    expendLin.setLayoutParams(expendParams);
    // 压缩前一个的比例
    collectParams = new LayoutParams(LayoutParams.MATCH_PARENT,SINGLE_ITEM_HEIGHT*SCALE - t+SINGLE_ITEM_HEIGHT*Double_Item_Height_index);
    collectLin.setLayoutParams(collectParams);
}


@Override
public void currentIndex(int scrollY) {
    printf();
    mScrollY = scrollY;
    t = scrollY;
    if(scrollY<SINGLE_ITEM_HEIGHT){
        Double_Item_Height_index=0;
    }else if(SINGLE_ITEM_HEIGHT<=scrollY&&scrollY<SINGLE_ITEM_HEIGHT*2){
        Double_Item_Height_index=1;
    }else if(SINGLE_ITEM_HEIGHT*2<=scrollY&&scrollY<SINGLE_ITEM_HEIGHT*3){
        Double_Item_Height_index=2;
    }else if(SINGLE_ITEM_HEIGHT*3<=scrollY&&scrollY<SINGLE_ITEM_HEIGHT*4){
        Double_Item_Height_index=3;
    }
    if(SINGLE_ITEM_HEIGHT*4<=scrollY){
        Double_Item_Height_index=4;
        if(!isLastItem){
            isLastItem = true;
            disableScrollHeight = scrollY;
        }
    }
    //向上,
    if(!isDownDirection&&disableScrollHeight>0&&scrollY<=disableScrollHeight){
        isLastItem = false;
    }
    whichImageAnim(Double_Item_Height_index);
    android.util.Log.i("","Double_Item_Height_index"+Double_Item_Height_index+isLastItem);
}

private void reSetHeight(){
    rankHot.setLayoutParams(normalParams);
    rankRich.setLayoutParams(normalParams);
    rankCharm.setLayoutParams(normalParams);
    rankSuperStar.setLayoutParams(normalParams);
    rankWeekStar.setLayoutParams(normalParams);
}

private void whichImageAnim(int Double_Item_Height_index){
    switch (Double_Item_Height_index) {
    case 0:
        collectLin = rankHot;
        expendLin = rankRich;
        break;
    case 1:
        collectLin = rankRich;
        expendLin = rankCharm;
        break;
    case 2:
        collectLin = rankCharm;
        expendLin = rankSuperStar;
        break;
    case 3:
        collectLin = rankSuperStar;
        expendLin = rankWeekStar;
        break;
    default:
        break;
    }
}

@Override
public void onaction_Up(boolean isUp) {
    mScrollView.scrollTo((int)(mScrollView.getX()), SINGLE_ITEM_HEIGHT*Double_Item_Height_index);//mPostion
    printf();
    if(Double_Item_Height_index==0){
        findViewById(R.id.id_rank_hot_imgs).setVisibility(View.VISIBLE);
    }else if(Double_Item_Height_index==1){
        findViewById(R.id.id_rank_rich_imgs).setVisibility(View.VISIBLE);
    }else if(Double_Item_Height_index==2){
        findViewById(R.id.id_rank_charm_imgs).setVisibility(View.VISIBLE);
    }else if(Double_Item_Height_index==3){
        findViewById(R.id.id_rank_superstar_imgs).setVisibility(View.VISIBLE);
    }else if(Double_Item_Height_index==4){
        findViewById(R.id.id_rank_weekstar_imgs).setVisibility(View.VISIBLE);
    }
}

@Override
public void onaction_Down() {
    // TODO Auto-generated method stub
    findViewById(R.id.id_rank_hot_imgs).setVisibility(View.INVISIBLE);
    findViewById(R.id.id_rank_rich_imgs).setVisibility(View.INVISIBLE);
    findViewById(R.id.id_rank_charm_imgs).setVisibility(View.INVISIBLE);
    findViewById(R.id.id_rank_superstar_imgs).setVisibility(View.INVISIBLE);
    findViewById(R.id.id_rank_weekstar_imgs).setVisibility(View.INVISIBLE);
}

private void printf(){
    rankHot,rankRich,rankCharm,rankSuperStar,rankWeekStar
    android.util.Log.i("","____rank1 height"+rankHot.getHeight()+":scroll__"+mScrollY);
    android.util.Log.i("","____rank2 height"+rankRich.getHeight()+":scroll__"+mScrollY);
    android.util.Log.i("","____rank3 height"+rankCharm.getHeight()+":scroll__"+mScrollY);
    android.util.Log.i("","____rank4 height"+rankSuperStar.getHeight()+":scroll__"+mScrollY);
    android.util.Log.i("","____rank5 height"+rankWeekStar.getHeight()+":scroll__"+mScrollY);
}

@Override
public void onClick(View v) {
    // TODO Auto-generated method stub
    Intent intent=null;
    switch (v.getId()) {
    case R.id.id_rank_hot:
        //红人榜
        intent = new Intent(this, RankItemActivity.class);
        intent.putExtra("rank", R.layout.layout_rank_activity_hot);
        break;
    case R.id.id_rank_rich:
        //富豪榜
        intent = new Intent(this, RankItemActivity.class);
        intent.putExtra("rank", R.layout.layout_rank_activity_rich);
        break;
    case R.id.id_rank_charm:
        //魅力榜
        intent = new Intent(this, RankItemActivity.class);
        intent.putExtra("rank", R.layout.layout_rank_activity_charm);
        break;
    case R.id.id_rank_superstar:
        //超星榜
        intent = new Intent(this, RankItemActivity.class);
        intent.putExtra("rank", R.layout.layout_rank_activity_superstar);
        break;
    case R.id.id_rank_weekstar:
        //周星榜
        intent = new Intent(this, RankItemActivity.class);
        intent.putExtra("rank", R.layout.layout_rank_activity_weekstar);
        break;
    default:
        break;
    }
    startActivity(intent);
}

private void requestTopThreeHead() {
    final String rankId = RankAPI.RANGE_DAY_ID;
    RankAPI.rankStar(rankId, 3).execute(new BaseRequestCallback<RankStarResult>() {
        @Override
        public void onRequestSucceed(RankStarResult rankStarResult) {
            if(rankStarResult.getData().size()<3){
                return;
            }
            ImageView tempImage;
            RankStarResult.Data tempData;
            int[] imgIds = {R.id.id_img_hot_head_first,R.id.id_img_hot_head_sencond,R.id.id_img_hot_head_third};
            for(int i=0;i<3;i++){
                tempData =rankStarResult.getData().get(i);
                tempImage = (ImageView) findViewById(imgIds[i]);
                ImageUtils.requestImage(tempImage, tempData.getPicUrl(),Config.COMMON_ICON_WIDTH_DP, Config.COMMON_ICON_HEIGHT_DP, R.drawable.default_user_bg);
            }
        }

        @Override
        public void onRequestFailed(RankStarResult rankWealthResult) {
        }
    });

    RankAPI.rankUser(rankId, 3).execute(new BaseRequestCallback<RankWealthResult>() {
        @Override
        public void onRequestSucceed(RankWealthResult rankWealthResult) {
            if(rankWealthResult.getDataList().size()<3){
                return;
            }
            ImageView tempImage;
            RankWealthResult.Data tempData;
            int[] imgIds = {R.id.id_img_rich_head_first,R.id.id_img_rich_head_sencond,R.id.id_img_rich_head_third};
            for(int i=0;i<3;i++){
                tempData =rankWealthResult.getDataList().get(i);
                tempImage = (ImageView) findViewById(imgIds[i]);
                ImageUtils.requestImage(tempImage, tempData.getPicUrl(),Config.COMMON_ICON_WIDTH_DP, Config.COMMON_ICON_HEIGHT_DP, R.drawable.default_user_bg);
            }
        }

        @Override
        public void onRequestFailed(RankWealthResult rankWealthResult) {
        }
    });

    RankAPI.featherUser(rankId, 3).execute(new BaseRequestCallback<RankStarResult>() {
        @Override
        public void onRequestSucceed(RankStarResult rankStarResult) {
            if(rankStarResult.getData().size()<3){
                return;
            }
            ImageView tempImage;
            RankStarResult.Data tempData;
            int[] imgIds = {R.id.id_img_charm_head_first,R.id.id_img_charm_head_sencond,R.id.id_img_charm_head_third};
            for(int i=0;i<3;i++){
                tempData =rankStarResult.getData().get(i);
                tempImage = (ImageView) findViewById(imgIds[i]);
                ImageUtils.requestImage(tempImage, tempData.getPicUrl(),Config.COMMON_ICON_WIDTH_DP, Config.COMMON_ICON_HEIGHT_DP, R.drawable.default_user_bg);
            }
        }

        @Override
        public void onRequestFailed(RankStarResult rankWealthResult) {
        }
    });

    RankAPI.superGiftWeekRank(3).execute(new BaseRequestCallback<RankGiftStarResult>() {
        @Override
        public void onRequestSucceed(RankGiftStarResult rankGiftStarResult) {
            if(rankGiftStarResult.getData().size()<3){
                return;
            }
            ImageView tempImage;
            RankGiftStarResult.Data tempData;
            int[] imgIds = {R.id.id_img_superstar_head_first,R.id.id_img_superstar_head_sencond,R.id.id_img_superstar_head_third};
            for(int i=0;i<3;i++){
                tempData =rankGiftStarResult.getData().get(i);
                tempImage = (ImageView) findViewById(imgIds[i]);
                ImageUtils.requestImage(tempImage, tempData.getGiftPicUrl(),Config.COMMON_ICON_WIDTH_DP, Config.COMMON_ICON_HEIGHT_DP, R.drawable.default_user_bg);
            }
        }

        @Override
        public void onRequestFailed(RankGiftStarResult rankGiftStarResult) {
        }
    });

    RankAPI.giftWeekRank(3).execute(new BaseRequestCallback<RankGiftStarResult>() {
        @Override
        public void onRequestSucceed(RankGiftStarResult rankGiftStarResult) {
            if(rankGiftStarResult.getData().size()<3){
                return;
            }
            ImageView tempImage;
            RankGiftStarResult.Data tempData;
            int[] imgIds = {R.id.id_img_weekstar_head_first,R.id.id_img_weekstar_head_sencond,R.id.id_img_weekstar_head_third};
            for(int i=0;i<3;i++){
                tempData =rankGiftStarResult.getData().get(i);
                tempImage = (ImageView) findViewById(imgIds[i]);
                ImageUtils.requestImage(tempImage, tempData.getGiftPicUrl(),Config.COMMON_ICON_WIDTH_DP, Config.COMMON_ICON_HEIGHT_DP, R.drawable.default_user_bg);
            }
        }

        @Override
        public void onRequestFailed(RankGiftStarResult rankGiftStarResult) {
        }
    });

}

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值