android GridView滑动选择框的实现

一、实现原理

获取GridView原有选择框,替换为一个动画选择框。

将GridView的Selector设置为透明,自定义一个imageView覆盖在GirdView上模拟选择框。

详细代码请查看Github,https://github.com/Ada0mm/viewDemo

二、基于模块

Drawable

ValueAnimator

TypeEvaluator 

三、实现步骤

1、布局文件

将GridView本身的selector设置为透明,自定义一个ImageView模拟焦点框,对其实现动画

<GridView 
        android:id="@+id/my_gridview"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:cacheColorHint="#00000000"
        android:fadingEdge="none"
        android:focusable="true"
        android:gravity="center"
        android:horizontalSpacing="19dp"
        设置选择框为透明
        android:listSelector="@android:color/transparent"
        android:descendantFocusability="blocksDescendants"
        android:numColumns="5"
        android:scrollbars="none"
        android:stretchMode="columnWidth"
        android:verticalSpacing="39dp"
        />
    <!-- 自定义焦点框,模拟selector-->
	   <ImageView
	       android:id="@+id/selector"
	       android:layout_width="206dp"
    		android:layout_height="106dp"
	       android:background="@drawable/ada_focus"
	       android:visibility="invisible" />

2、自定义选择框

继承drawable,扩展Animatable接口

定义TypeEvaluator,这里以drawable的起始位置及结束位置为参数区间。

private static class PositionEvaluator implements TypeEvaluator {

		private IntEvaluator mEvaluator;

		public PositionEvaluator() {
			mEvaluator = new IntEvaluator();
		}

		@Override
		public Object evaluate(float fraction, Object startValue,
				Object endValue) {
			Rect startRect = (Rect) startValue;
			Rect endRect = (Rect) endValue;
			int left = (Integer) mEvaluator.evaluate(fraction, startRect.left,
					endRect.left);
			int top = (Integer) mEvaluator.evaluate(fraction, startRect.top,
					endRect.top);
			return new Rect(left, top, left + startRect.width(), top
					+ startRect.height());
		}
	}

定义动画参数

    //这里为自定义的imageVie用来显示选择框
    //焦点框的ImageView,通过实现这个view的滑动动画,模拟selector的移动。
    mView = view;
                //原有选择框的selector
		mDrawable = drawable;
		//定义移动类型为object,根据drawable的原始位置、结束位置以及时长来决定动画
		mPositionEvaluator = new PositionEvaluator();
		mAnimator = ValueAnimator.ofObject(mPositionEvaluator);
		mAnimator.setDuration(MOVE_DURATION_MS);
		mAnimator.setInterpolator(new DecelerateInterpolator(2.0f));
		mAnimator.addUpdateListener(new AnimatorUpdateListener() {

			@Override
			public void onAnimationUpdate(ValueAnimator animation) {
				Rect bounds = getBounds();
				Rect newBounds = (Rect) animation.getAnimatedValue();
				if (!bounds.equals(newBounds)) {
					AnimatedSelector.super.setBounds(newBounds.left,
							newBounds.top, newBounds.right, newBounds.bottom);
					mView.setX(newBounds.left + mLeftOffset);
					mView.setY(newBounds.top + mTopOffset);
				};
			}
		});

重写setBounds实现焦点框的移动。

@Override
	public void setBounds(int left, int top, int right, int bottom) {
		// Animate setting the bounds.
		Rect bounds = getBounds();
		if (bounds.isEmpty()) {
			super.setBounds(left, top, right, bottom);
			mView.setX(left + mLeftOffset);
			mView.setY(left + mTopOffset);
			setSelectorDimensions(right - left, bottom - top + 8);
			ensureViewVisible();
		} else if (bounds.left != left || bounds.top != top) {
			if (mAnimator.isRunning()) {
				mAnimator.cancel();
				mAnimator.setDuration(MOVE_DURATION_MS- ((long) mAnimator.
				    getAnimatedFraction() * MOVE_DURATION_MS));
//				System.out.println(">>>>>>"+mAnimator.getDuration());
			} else {
				mAnimator.setDuration(MOVE_DURATION_MS);
			}
			mAnimator.setObjectValues(copyBounds(), new Rect(left, top, right,
					bottom));
			mAnimator.setEvaluator(mPositionEvaluator);
			mAnimator.start();
		}
	}

3. 初始化Gridview,替换为自定义选择框drawable

public void setSelector(GridView gridView) {
        private AnimatedSelector animatedSelector;
	animatedSelector = new AnimatedSelector(mContext,selector,
				gridView.getSelector());
	animatedSelector.hideView();
	gridView.setSelector(animatedSelector);
	}

详细代码请查看Github,https://github.com/Ada0mm/viewDemo

你可能感兴趣的:(GridView,selector,滑动)