1. 程式人生 > >GridView 條目選中後放大或縮小

GridView 條目選中後放大或縮小

前言:客戶要做一個需求,使用者相簿的照片選中後放大,這種需求在電視上有很多的應用場景,例如 應用圖示獲得焦點放大,視訊頁面的列表,於是先上github找了找(畢竟別人寫好了,直接就拿來用,省事),但沒找到合適,資源太少了,找到了庫很大。於是決定自己弄一個


繪製

此時GridView已經繪製完成了,需要在getChildStaticTransformation((View child, Transformation t)做一些轉換,在構造方法初始化設定

	public ZoomGridView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		//設定為true,才能呼叫getChildStaticTransformation()
		setStaticTransformationsEnabled(true);
		// 允許子類修改繪製順序
		setChildrenDrawingOrderEnabled(true);
	}
對選中item進行縮放及縮放過程動畫的業務處理
@Override
	protected boolean getChildStaticTransformation(View child, Transformation t) {
		t.setTransformationType(Transformation.TYPE_MATRIX);
		if (child == getSelectedView() && child.isSelected()) {
			final int selectedPosition = getSelectedItemPosition();
			if (selectedPosition != mSelectedPosition) {

				mSelectedPosition = selectedPosition;
				mItemScale = 1.0f;
			} else {
				// 這裡會呼叫多次,直到縮放到指定倍數
				mItemScale += (mItemSelectedScale - 1) * 0.1f;
				if (mItemSelectedScale < 1) {
					if (mItemScale <= mItemSelectedScale) {
						mItemScale = mItemSelectedScale;
					} else {
						// 每次間隔80毫秒繪製,是為了使用者看到縮放過程沒那麼突兀
						child.postInvalidateDelayed(80);
					}
				} else {
					if (mItemScale >= mItemSelectedScale) {
						mItemScale = mItemSelectedScale;
					} else {
						child.postInvalidateDelayed(80);
					}
				}
			}
			// 對item進行縮放
			t.getMatrix().setScale(mItemScale, mItemScale, child.getWidth() / 2.0f, child.getHeight() / 2.0f);
		} else {
			// 設定未選中item為原來的大小
			t.getMatrix().setScale(1.0f, 1.0f);
		}
		return true;
	}

衝突:繪製完後,放大item會覆蓋傍邊條目,所以我們需要改變繪製條目的順序
	// 改變繪製的順序,避免放大後會覆蓋其他的item
	@Override
	protected int getChildDrawingOrder(int childCount, int i) {
		final int selectedIndex = getSelectedItemPosition() - getFirstVisiblePosition();
		if (selectedIndex < 0) {
			return i;
		}
		if (i < selectedIndex) {
			return i;
		}
		if (i == childCount - 1) {
			return selectedIndex;
		}
		return i + 1;
	}
效果