滑动缩放的GridView

转载请标明出处:https://blog.csdn.net/hj_key/article/details/102812987

 

最近项目中变态需求,要在滑动列表中加入滑动缩放效果;

上滑顶部缩小,底部放大;下滑底部缩小,顶部放大。

所以自定义GridView,实现动画效果

package com.test.gridview.ui.widget;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.GridView;
import android.widget.ImageView;
import android.view.MotionEvent;
import android.widget.AdapterView;
import android.content.Intent;


public class XunGridView extends GridView {
    private static final String TAG = "zhj";
    private int width;
    private int height;
    private int gridViewHeight;
    private int diff;
    private int bdiff;
    private int visibleCount;
    private int sourceWidth = 113;
    private View topView1, topView2, topView3, bottomView1, bottomView2, bottomView3;
    private int lastView1Left, lastView1Right, lastView2Left, lastView2Right, lastView3Left, lastView3Right;
    private View tempLastView2, tempLastView3;
    private boolean isAlreadMove;//防止点击的时候滑动
    boolean isTopTop = false;
    boolean CouldDismiss  = false;
    private Context mContext;
    private boolean isScroll = false;
    private int mScrollState = -1;

    public XunGridView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mContext = context;
        initListener();
    }

    public XunGridView(Context context) {
        super(context);
        mContext = context;
        initListener();
    }


	/**private void toTellAppStoreUIDismiss(){
	    Intent intent = new Intent();
	    intent.setAction("com.xiaoxun.appstore.task.dismiss_self");
	    intent.setPackage("com.xxun.xunlauncher");
	    mContext.sendBroadcast(intent);
	}*/


    public boolean  CouldDismiss(){
        if(diff == 0 && getFirstVisiblePosition() == 0 && !isScroll){
            CouldDismiss = true;
        }
        if(diff < 0){
            CouldDismiss = false;
        }
        return CouldDismiss;
    }

    private void initListener() {
        setOnScrollListener(new OnScrollListener() {
            @Override
            public void onScrollStateChanged(AbsListView view, int scrollState) {
                //Log.d("zhj","isTopTop = "+ isTopTop + ",  33 scrollState = " + scrollState);
                if(scrollState == 1){
                    isScroll = true;
                }else{
                    isScroll = false;
                }
                mScrollState = scrollState;

                if(isTopTop && scrollState == 0){
                    //toTellAppStoreUIDismiss();
                    CouldDismiss  = true;
                }else{
                    CouldDismiss  = false; 
                }
            }

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

                visibleCount = visibleItemCount;
                int position = 0;
                View view1 = getChildAt(position);
                if (view1 != null && height != 0) {
                    int top = view1.getTop();
                    diff = (int)top /2;
                    //Log.d(TAG, "onScroll: top = " + top + " height = " + height + " diff = " + diff);
                }
                if (diff > 0) {
                    diff = 0;
                }
                //Log.d("zhj","diff = " + diff);
                if(firstVisibleItem == 0){
                    isTopTop = true;
                }
                if(visibleItemCount + firstVisibleItem == totalItemCount){
                    isTopTop = false;
                }

                int half = (int)sourceWidth / 3;
                if(-diff >= half){
                    diff = -half;
                }
                View view2 = getChildAt(visibleCount - 1);
                if (view2 != null && gridViewHeight != 0) {
                    int bottom = view2.getBottom();
                    bdiff = gridViewHeight - bottom;
                    //Log.i(TAG, "onScroll: getBottom = " + bottom + " getHeight() = " + gridViewHeight + " bdiff = " + bdiff);
                }
                if (bdiff > 0) {
                    bdiff = 0;
                }
                if(-bdiff >= half){
                    bdiff = -half;
                }
                requestLayout();
            }
        });

    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        isAlreadMove = false;
        doOnMeasure();
    }

    private void doOnMeasure() {

        if (gridViewHeight == 0) {
            gridViewHeight = getHeight();
        }
        // ===== first line ======//
        int tw = width + diff;
        int th = height + diff;
        for (int i = 0; i < 3; i++) {
            View view = getChildAt(i);
            if (view != null && (width == 0 || height == 0)) {
                width = view.getMeasuredWidth();
                height = view.getMeasuredHeight();
                tw = width + diff;
                th = height + diff;
            }
            //更改高度
            updateWidth(view, tw, th, true);
            //恢复上一个控件的高宽 用于快速滑动时恢复
            /**if (i == 0) {
                resetWidth(view, topView1, true);
            } else if (i == 1) {
                resetWidth(view, topView2, true);
            } else {
                resetWidth(view, topView3, true);
            }*/
        }
        // ===== last line ======//
        int lastLineCount = visibleCount % 3;
        if (lastLineCount == 0) {
            lastLineCount = 3;
        }

        int bw = width + bdiff;
        int bh = height + bdiff;
        for (int i = 1; i <= lastLineCount; i++) {
            View view = getChildAt(visibleCount - i);
            updateWidth(view, bw, bh, false);

            /**if (lastLineCount == 3) {
                if (i == 1) {
                    resetWidth(view, bottomView3, false);
                } else if (i == 2) {
                    resetWidth(view, bottomView2, false);
                } else {
                    resetWidth(view, bottomView1, false);
                }
            } else if (lastLineCount == 2) {
                if (i == 1) {
                    resetWidth(view, bottomView2, false);
                } else {
                    resetWidth(view, bottomView1, false);
                }
                resetWidth(view, tempLastView3, false);
            } else {
                resetWidth(view, bottomView1, false);
                resetWidth(view, tempLastView2, false);
                resetWidth(view, tempLastView3, false);
            }*/
        }
        resetAllViewWidth();
    }



    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        super.onLayout(changed, l, t, r, b);

        //Log.d("zhj","======= ****   onLayout  **** ========= ");

        //doOnMeasure();
        // ===== modify  first line && first view place======//
        View view1 = getChildAt(0);
        if (view1 != null) {
            if (lastView1Left == 0 || lastView1Right == 0) {
                lastView1Left = view1.getLeft();
                lastView1Right = view1.getRight();
            }

            int lf = lastView1Left - 2 * Math.round(diff / 2f);
            if (lf <= lastView1Left) {
                lf = lastView1Left;
            }

            int rg = lastView1Right - 2 * Math.round(diff / 2f);
            if (rg <= lastView1Right) {
                rg = lastView1Right;
            }
            //Log.d(TAG, "onLayout: 1111  lf = " + lf + ",  rg = " + rg + ",  width = " + view1.getMeasuredWidth());

            view1.layout(lf, view1.getTop(), rg, view1.getBottom());
        }else{
            Log.d("zhj","view1  is exception  null ");
        }

        /**if (topView1 != null && topView1 != view1) {
            Log.d(TAG, "onLayout: topView11  lastView1Left = " + lastView1Left + ",  lastView1Right = " + lastView1Right);
            topView1.layout(lastView1Left, topView1.getTop(), lastView1Right, topView1.getBottom());
        }
        topView1 = view1;*/

        // ===== modify  first line && second view  place======//
        View view2 = getChildAt(1);
        if (view2 != null) {
            if (lastView2Left == 0 || lastView2Right == 0) {
                lastView2Left = view2.getLeft();
                lastView2Right = view2.getRight();
            }
            //Log.d(TAG, "onLayout: 222  lastView2Left = " + lastView2Left + ",  lastView2Right =" + lastView2Right);

            int lf = lastView2Left - Math.round(diff / 2f);
            if (lf >= lastView2Left) {
                lf = lastView2Left;
            }

            int rg = lastView2Right + Math.round(diff / 2f);
            if (rg >= lastView2Right) {
                rg = lastView2Right;
            }
            //Log.d(TAG, "onLayout: 222  lf = " + lf + ",  rg = " + rg + ",  width = " + view2.getMeasuredWidth());
            view2.layout(lf, view2.getTop(), rg, view2.getBottom());
        }else{
        Log.d("zhj","view2  is exception  null ");

        }

        /**if (topView2 != null && topView2 != view2) {
            topView2.layout(lastView2Left, topView2.getTop(), lastView2Right, topView2.getBottom());
        }
        topView2 = view2;*/

        // ===== modify  first line && third view  place======//
        View view3 = getChildAt(2);

        if(view3 == view2){
            Log.d("zhj","is exception  " + view3.getLeft());
        }

        if (view3 != null) {
            if (lastView3Left == 0 || lastView3Right == 0) {
                lastView3Left = view3.getLeft();
                lastView3Right = view3.getRight();
            }
            //Log.d(TAG, "onLayout: 333  lastView3Left = " + lastView3Left + ",  lastView3Right =" + lastView3Right);

            int lf = lastView3Left + 2 * Math.round(diff / 2f);
            if (lf >= lastView3Left) {
                lf = lastView3Left;
            }

            int rg = lastView3Right + 2 * Math.round(diff / 2f);
            if (rg >= lastView3Right) {
                rg = lastView3Right;
            }
            //Log.d(TAG, "onLayout: 333  lf = " + lf + ",  rg = " + rg + ",  width = " + view3.getMeasuredWidth());
            view3.layout(lf, view3.getTop(), rg, view3.getBottom());
        }else{
            Log.d("zhj","view3  is exception  null ");
        }

        /**if (topView3 != null && topView3 != view3) {
            Log.d(TAG, "onLayout: topView3  lastView3Left = " + lastView3Left + ",  lastView3Right = " + lastView3Right);
            topView3.layout(lastView3Left, topView3.getTop(), lastView3Right, topView3.getBottom());
        }
        topView3 = view3;*/


        ///==================================================================================================

        int lastLineCount = visibleCount % 3;
        //Log.d(TAG, "onLayout: lastLineCount =  " + lastLineCount);
        if (lastLineCount == 0) {
            lastLineCount = 3;
        }
        for (int i = 1; i <= lastLineCount; i++) {
            View view = getChildAt(visibleCount - i);

            if (lastLineCount == 1) {
                if (view != null) {
                    int x = 2 * Math.round(bdiff / 2f);
                    int lf = lastView1Left - x;
                    if (lf <= lastView1Left) {
                        lf = lastView1Left;
                    }
                    int rg = lastView1Right - x;
                    if (rg <= lastView1Right) {
                        rg = lastView1Right;
                    }
                    view.layout(lf, view.getTop(), rg, view.getBottom());
                }
                /**if (bottomView1 != null && bottomView1 != view) {
                    bottomView1.layout(lastView1Left, bottomView1.getTop(), lastView1Right, bottomView1.getBottom());
                }
                bottomView1 = view;*/
            } else if (lastLineCount == 2) {
                if (i == 1) {
                    if (view != null) {
                        int x = Math.round(bdiff / 2f);
                        int lf = lastView2Left - x;
                        if (lf <= lastView2Left) {
                            lf = lastView2Left;
                        }
                        int rg = lastView2Right + x;
                        if (rg <= lastView2Right) {
                            rg = lastView2Right;
                        }

                        view.layout(lf, view.getTop(), rg, view.getBottom());
                    }
                    /**if (bottomView2 != null && bottomView2 != view) {
                        bottomView2.layout(lastView2Left, bottomView2.getTop(), lastView2Right, bottomView2.getBottom());
                    }
                    bottomView2 = view;*/

                } else if (i == 2) {
                    if (view != null) {
                        int x = 2 * Math.round(bdiff / 2f);
                        int lf = lastView1Left - x;
                        if (lf <= lastView1Left) {
                            lf = lastView1Left;
                        }
                        int rg = lastView1Right - x;
                        if (rg <= lastView1Right) {
                            rg = lastView1Right;
                        }
                        view.layout(lf, view.getTop(), rg, view.getBottom());
                    }

                    /**if (bottomView1 != null && bottomView1 != view) {
                        bottomView1.layout(lastView1Left, bottomView1.getTop(), lastView1Right, bottomView1.getBottom());
                    }
                    bottomView1 = view;*/
                }

                /**if (bottomView3 != null && bottomView3 != view) {
                    bottomView3.layout(lastView3Left, bottomView3.getTop(), lastView3Right, bottomView3.getBottom());
                }*/
            } else {
                if (i == 1) {
                    if (view != null) {
                        int x = 2 * Math.round(bdiff / 2f);
                        int lf = lastView3Left + x;
                        if (lf >= lastView3Left) {
                            lf = lastView3Left;
                        }
                        int rg = lastView3Right + x;
                        if (rg >= lastView3Right) {
                            rg = lastView3Right;
                        }
                        //Log.d(TAG, "bottomView3  x =" + x + ", lf = " + lf + ", rg =" + rg);
                        view.layout(lf, view.getTop(), rg, view.getBottom());
                    }
                    /**if (bottomView3 != null && bottomView3 != view) {
                        bottomView3.layout(lastView3Left, bottomView3.getTop(), lastView3Right, bottomView3.getBottom());
                    }
                    bottomView3 = view;*/
                    tempLastView3 = view;
                } else if (i == 2) {
                    if (view != null) {
                        int x = Math.round(bdiff / 2f);
                        int lf = lastView2Left - x;
                        if (lf >= lastView2Left) {
                            lf = lastView2Left;
                        }
                        int rg = lastView2Right + x;
                        if (rg >= lastView2Right) {
                            rg = lastView2Right;
                        }
                        //Log.d(TAG, "bottomView2  x =" + x + ", lf = " + lf + ", rg =" + rg);
                        view.layout(lf, view.getTop(), rg, view.getBottom());
                    }

                    /**if (bottomView2 != null && bottomView2 != view) {
                        bottomView2.layout(lastView2Left, bottomView2.getTop(), lastView2Right, bottomView2.getBottom());
                    }
                    bottomView2 = view;*/
                    tempLastView2 = view;
                } else {
                    if (view != null) {
                        int x = 2 * Math.round(bdiff / 2f);
                        int lf = lastView1Left - x;
                        if (lf <= lastView1Left) {
                            lf = lastView1Left;
                        }
                        int rg = lastView1Right - x;
                        if (rg <= lastView1Right) {
                            rg = lastView1Right;
                        }
                        view.layout(lf, view.getTop(), rg, view.getBottom());
                    }

                    /**if (bottomView1 != null && bottomView1 != view) {
                        bottomView1.layout(lastView1Left, bottomView1.getTop(), lastView1Right, bottomView1.getBottom());
                    }
                    bottomView1 = view;*/

                }
            }
        }

        resetAllViewLayout();
    }


    public void resetAllViewWidth() {
        int count = getChildCount();
        if (count > 0) {
            for (int i = 0; i < count; i++) {
                int lastLineCount = count % 3;
                if (lastLineCount == 0) {
                    lastLineCount = 3;
                }
                View view = getChildAt(i);
                if (i != 0 && i != 1 && i != 2 && lastLineSureReset(i, lastLineCount, count)) {
                    updateWidth(view, 112, 112, true);
                }
            }
        }
    }

    public void resetAllViewLayout() {
        int count = getChildCount();
        if (count > 0) {
            for (int i = 0; i < count; i++) {
                int lastLineCount = count % 3;
                if (lastLineCount == 0) {
                    lastLineCount = 3;
                }
                View view = getChildAt(i);
                int diff  = view.getTop();
                //Log.d("zhj","Lauout  view diff = " + diff );
                if (i != 0 && i != 1 && i != 2 && lastLineSureReset(i, lastLineCount, count)) {
                    //Log.d("zhj","count = " + count + ",  i = " + i  + "  ,  i % 3  = " + (i % 3));
                    if(i % 3 == 0){
                       view.layout(5, view.getTop(), 117, view.getBottom());
                    }else if(i % 3 == 1){
                       view.layout(127, view.getTop(), 239, view.getBottom());
                    }else if(i % 3 == 2){
                       view.layout(249, view.getTop(), 361, view.getBottom());
                    }
                }

            }
        }
    }


    private boolean lastLineSureReset(int index, int lastLineCount, int count) {
        //Log.d("zhj","index = " + index + ",  lastLineCount = " + lastLineCount  + ", count = " + count);
        if (lastLineCount == 3) {
            if(count < 3) return false;
            if (index != (count - 1) && index != (count - 2) && index != (count - 3)) {
                return true;
            }
        } else if (lastLineCount == 2) {
            if(count < 2) return false;
            if (index != (count - 1) && index != (count - 2)) {
                return true;
            }
        } else {
            if (index != (count - 1)) {
                return true;
            }
        }
        return false;
    }

    @Override
    protected void layoutChildren() {
        // TODO Auto-generated method stub
        if(!isAlreadMove){
            super.layoutChildren();
        }
        isAlreadMove = true;
    }

    /**
     * 重置恢复控件大小
     *
     * @param view     当前行控件
     * @param lastView 需要恢复大小的控件
     */
    private void resetWidth(View view, View lastView, boolean isTop) {
        if (lastView != null && lastView != view) {
            //Log.d("zhj"," ===== resetWidth  ====");
            updateWidth(lastView, width, height, isTop);
        }
    }

    /**
     * 更新控件大小
     *
     * @param view  需要更新的控件
     * @param width 更新宽度
     */
    private void updateWidth(View view, int width, int height, boolean isTop) {
        if (view == null) {
            //Log.d("zhj","====   updateWidth   view is null   =======");
            return;
        }

        ImageView tempView = (ImageView)view.findViewById(R.id.mAppImage);
        if (tempView == null) {
            return;
        }
        if(isTop){
            tempView.setScaleType(ImageView.ScaleType.FIT_END);
        }else{
            tempView.setScaleType(ImageView.ScaleType.FIT_START);
        }
        ViewGroup.LayoutParams lp = tempView.getLayoutParams();
        //lp.height = height;
        //Log.d("zhj","updateWidth >>>   width = " + width);
        if (width > this.width) {
            width = this.width;
        } else if (width < 0) {
            width = this.width;
        }
        lp.width = width;
        tempView.setLayoutParams(lp);
    }
}

猜你喜欢

转载自blog.csdn.net/hj_key/article/details/102812987