GridView选中放大, 主要是在GridView中添加了一个新的FrameLayout, 然后copy GridView item的镜像出来,绘制到FrameLayout中去
package com.kookong.tv.view; import com.kookong.tv.R; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.view.animation.AccelerateInterpolator; import android.view.animation.DecelerateInterpolator; public class MetroCursorView extends View { private View mFocusView; private View mUnFocusView; private int[] mFocusLocation = new int[2]; private int[] mLocation = new int[2]; private Drawable mDrawableWhite; private Drawable mDrawableShadow; private float mScaleUp = 1.0f; private float mScaleDown = 1.1f; private Paint mPaint = new Paint(); private Rect mRect = new Rect(); private boolean mMirror = false; ObjectAnimator anim = ObjectAnimator.ofFloat(this, "ScaleUp", new float[] { 1.0F, 1.1F }).setDuration(getResources().getInteger(R.integer.scale_up_duration)); ObjectAnimator anim1 = ObjectAnimator.ofFloat(this, "ScaleDown", new float[] { 1.1F, 1.0F }).setDuration(getResources().getInteger(R.integer.scale_down_duration)); ObjectAnimator animShime = ObjectAnimator.ofFloat(this, "ScaleUp", new float[] { 1.1F, 1.15F, 1.1F }).setDuration(150); ObjectAnimator animUpdate = ObjectAnimator.ofFloat(this, "Update", new float[] { 1.0F, 1.0F }).setDuration(getResources().getInteger(R.integer.update_duration)); public MetroCursorView(Context context) { super(context); init(context); } public MetroCursorView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } void init(Context context) { mDrawableWhite = getResources().getDrawable(R.drawable.item_highlight); mDrawableShadow = getResources().getDrawable(R.drawable.item_shadow); mPaint.setColor(0xff000000); anim.setInterpolator(new DecelerateInterpolator()); anim1.setInterpolator(new DecelerateInterpolator()); animShime.setInterpolator(new AccelerateInterpolator()); } @Override protected void onDraw(Canvas canvas) { drawCursorView(canvas, mFocusView, mScaleUp, true); } public void drawCursorView(Canvas canvas, View view, float scale, boolean focus) { if (view != null) { canvas.save(); if (null == mLocation) { mLocation = new int[2]; } if (null == mFocusLocation) { mFocusLocation = new int[2]; } getLocationInWindow(mLocation); view.getLocationInWindow(mFocusLocation); int width = view.getWidth(); int height = view.getHeight(); int left = (int) (mFocusLocation[0] - mLocation[0] - width * (scale - 1) / 2); int top = (int) (mFocusLocation[1] - mLocation[1] - height * (scale - 1) / 2); canvas.translate(left, top); canvas.scale(scale, scale); if (focus) { Rect padding = new Rect(); mDrawableShadow.getPadding(padding); mDrawableShadow.setBounds(-padding.left, -padding.top, width + padding.right, height + padding.bottom); mDrawableShadow.setAlpha((int) (255 * (scale - 1) * 10)); mDrawableShadow.draw(canvas); mDrawableWhite.getPadding(padding); mDrawableWhite.setBounds(-padding.left - 1, -padding.top - 1, width + padding.right + 1, height + padding.bottom + 1); mDrawableWhite.setAlpha((int) (255 * (scale - 1) * 10)); mDrawableWhite.draw(canvas); } view.draw(canvas); canvas.restore(); } } public void setFocusView(View view) { if (mFocusView != view) { mFocusView = view; mScaleUp = 1.0f; anim.start(); animUpdate.start(); } } public void showIndicator() { animShime.start(); } public void setUnFocusView(View view) { mFocusView = null; if (mUnFocusView != view) { mUnFocusView = view; anim1.start(); } invalidate(); } /** * 该方法不能被混淆 * * @param scale */ public void setScaleUp(float scale) { mScaleUp = scale; invalidate(); } public void setScaleDown(float scale) { mScaleDown = scale; invalidate(); } public void setUpdate(float scale) { invalidate(); } }
<?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <LinearLayout android:id="@+id/tvwallv2_left_nav_contaner" android:layout_width="100dp" android:layout_height="match_parent" android:background="#193646" android:orientation="vertical" android:paddingTop="30dp" > </LinearLayout> <com.kookong.tv.view.ZoomGridView android:id="@+id/tvwallv2_gridview" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@drawable/channelactivity_bg" android:clipChildren="false" android:clipToPadding="false" android:horizontalSpacing="20dp" android:numColumns="3" android:paddingBottom="30dp" android:paddingTop="30dp" android:paddingLeft="20dp" android:paddingRight="20dp" android:scrollbars="none" android:verticalSpacing="20dp" /> </LinearLayout> <com.kookong.tv.view.MetroCursorView //和gridview平级 android:id="@+id/mcursorview" android:layout_width="wrap_content" android:layout_height="match_parent" > </com.kookong.tv.view.MetroCursorView> <View android:id="@+id/tvwallv2_left_nav_cursor" android:layout_width="100dp" android:layout_height="50dp" android:background="#552DABFF" > </View> </FrameLayout>
另外, 为Listview添加选中的另一种方式, 也可以在listview的平级放一个View, listview变化的时候, 不断的更改
和这个View的坐标位置
Rect rect = new Rect(0, 0, 0, 0); containerView.getGlobalVisibleRect(rect);//获取containerView的位置 FrameLayout.LayoutParams layoutParams = (FrameLayout.LayoutParams) mTvwallv2_left_nav_cursor.getLayoutParams(); layoutParams.leftMargin = rect.left; if (mStatusBarHeight == -1) { mStatusBarHeight = SystemUtil.getStatusBarHeight(TVWallActivityV2.this); } layoutParams.topMargin = rect.top - mStatusBarHeight; //位置需要去点StatusBar的高度 mTvwallv2_left_nav_cursor.setLayoutParams(layoutParams);