package com.wasu.cs.widget.mediacontrol; import android.animation.Animator; import android.animation.Animator.AnimatorListener; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.KeyEvent; import android.view.View; import android.view.animation.AccelerateDecelerateInterpolator; import android.widget.BaseAdapter; import android.widget.FrameLayout; import com.wasu.cs.widget.ViewPackage; import com.wasu.widget.util.UIUtil; import java.util.ArrayList; import java.util.List; import java.util.Stack; import cn.com.wasu.main.AppUtil; import cn.com.wasu.main.R; public class RecommendContainer extends FrameLayout { private Context context; public RecommendContainer(Context context) { super(context); init(context); } public RecommendContainer(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public RecommendContainer(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context); } private void init(Context c) { context = c; setChildrenDrawingOrderEnabled(true); setClipChildren(false); setClipToPadding(false); } private Stack viewPackages = new Stack(); private BaseAdapter adapter; private boolean isFirstLoad = true; private int showItemCount; private int currentIndex = 0; public int getShowItemCount() { return showItemCount; } public void setShowItemCount(int showItemCount) { this.showItemCount = showItemCount; } public void setAdapter(BaseAdapter adapter) { this.viewPackages.clear(); this.adapter = adapter; if (isFirstLoad) { firstLoadViews(); isFirstLoad = false; } else { reloadAllView(); } } private ViewPackage createViewPackage(int position, View preItem) { View view = adapter.getView(position, null, null); if (view == null) { return null; } LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); lp.leftMargin = 0; view.setLayoutParams(lp); ViewPackage vp = new ViewPackage(view); vp.setPosition(position); vp.setId(AppUtil.createId()); if (preItem != null) { preItem.setNextFocusRightId(view.getId()); view.setNextFocusLeftId(preItem.getId()); } return vp; } private void firstLoadViews() { if (adapter == null) { return; } removeAllViews(); int count = adapter.getCount(); int index = count; View preView = null; ViewPackage vp = null; if (count > showItemCount) { index = showItemCount; vp = createViewPackage(count - 1, preView); if (vp != null) { addView(vp.getView()); viewPackages.add(vp); preView = vp.getView(); } } for (int i = 0; i < index; i++) { vp = createViewPackage(i, preView); if (vp != null) { addView(vp.getView()); viewPackages.add(vp); preView = vp.getView(); } } if (count > showItemCount) { int position = 0; if (count > showItemCount + 1) { position = showItemCount; } vp = createViewPackage(position, preView); if (vp != null) { addView(vp.getView()); viewPackages.add(vp); preView = vp.getView(); } } } private void reloadAllView() { } private boolean isInitLayout = false; private int mSpacing = 46; @Override protected void onLayout(boolean changed, int l, int t, int r, int b) { if (isInitLayout || this.adapter == null || this.adapter.getCount() == 0) { return; } int i = 0; View child = null; int left = 0; int pHeight = b - t; if (adapter.getCount() > showItemCount) { child = viewPackages.get(i).getView(); left = -child.getMeasuredWidth(); int top = (pHeight - child.getMeasuredHeight()) / 2; int right = left + child.getMeasuredWidth(); int bottom = top + child.getMeasuredHeight(); child.layout(left, top, right, bottom); i++; } left = getPaddingLeft(); while (i < viewPackages.size()) { child = viewPackages.get(i).getView(); int top = (pHeight - child.getMeasuredHeight()) / 2; int right = left + child.getMeasuredWidth(); int bottom = top + child.getMeasuredHeight(); child.layout(left, top, right, bottom); left += child.getMeasuredWidth() + mSpacing; i++; } isInitLayout = true; } private View newItem = null; private void fillLeft() { ViewPackage firstVp = viewPackages.firstElement(); int firstPosition = firstVp.getPosition(); View firstView = firstVp.getView(); ViewPackage vp = viewPackages.pop(); View view = vp.getView(); int position = firstPosition - 1; if (position < 0) { position = adapter.getCount() - 1; } View newView = adapter.getView(position, view, null); if (newView == null) return; vp.setView(newView); vp.setPosition(position); viewPackages.insertElementAt(vp, 0); firstView.setNextFocusLeftId(newView.getId()); newView.setNextFocusRightId(firstView.getId()); int left = -newView.getMeasuredWidth(); int top = newView.getTop(); int right = left + newView.getMeasuredWidth(); int bottom = newView.getBottom(); newView.layout(left, top, right, bottom); newView.setX(left); newView.setFocusable(false); newItem = newView; } private void fillRight() { ViewPackage lastVp = viewPackages.lastElement(); int lastPosition = lastVp.getPosition(); View lastView = lastVp.getView(); ViewPackage vp = viewPackages.get(0); View view = vp.getView(); viewPackages.remove(0); int position = lastPosition + 1; if (position + 1 > adapter.getCount()) { position = 0; } View newView = adapter.getView(position, view, null); if (newView == null) return; vp.setView(newView); vp.setPosition(position); viewPackages.add(vp); lastView.setNextFocusRightId(newView.getId()); newView.setNextFocusLeftId(lastView.getId()); int left = (int) (lastView.getLeft() + lastView.getMeasuredWidth()) + mSpacing; int top = newView.getTop(); int right = left + newView.getMeasuredWidth(); int bottom = newView.getBottom(); newView.layout(left, top, right, bottom); newView.setX(left); newView.setFocusable(false); newItem = newView; } private void scrollPreItem() { fillLeft(); animViews(false); } private void scrollNextItem() { fillRight(); animViews(true); } private int anim_duration = 200; private void animViews(boolean scrollLeft) { int count = viewPackages.size(); if (count > showItemCount) { List animators = new ArrayList(); AnimatorSet animatorSet = new AnimatorSet(); int i = 0; View child = viewPackages.get(i).getView(); ObjectAnimator viewAnim = null; if (scrollLeft) { viewAnim = ObjectAnimator.ofFloat(child, "X", -child.getMeasuredWidth()); viewAnim.setDuration(anim_duration); viewAnim.setInterpolator(new AccelerateDecelerateInterpolator()); animators.add(viewAnim); } i++; int x = 0; View tempView = null; for (; i < count; i++) { child = viewPackages.get(i).getView(); if (tempView == null) { x = getPaddingLeft(); } else { x += tempView.getMeasuredWidth() + mSpacing; } viewAnim = ObjectAnimator.ofFloat(child, "X", x); viewAnim.setDuration(anim_duration); viewAnim.setInterpolator(new AccelerateDecelerateInterpolator()); animators.add(viewAnim); tempView = child; } animatorSet.playTogether(animators); animatorSet.addListener(new AnimatorListener() { @Override public void onAnimationStart(Animator animation) { // mIsScrolling = true; // selectedView(getSelectedView(), false); } @Override public void onAnimationRepeat(Animator animation) { } @Override public void onAnimationEnd(Animator animation) { isDrawFocusItem = true; if (newItem != null) { newItem.setFocusable(true); } postInvalidate(); } @Override public void onAnimationCancel(Animator animation) { } }); animatorSet.start(); } } private int keyCode = 0; @Override public boolean dispatchKeyEvent(KeyEvent event) { if (!isInitLayout || this.adapter == null || this.adapter.getCount() == 0) { return true; } this.keyCode = event.getKeyCode(); if (this.focusItem == null) { return true; } switch (keyCode) { case KeyEvent.KEYCODE_DPAD_LEFT: { View v = findViewById(this.focusItem.getNextFocusLeftId()); if (v != null) { v.requestFocus(); invalidate(); } else {//用于处理推荐资产数量小于showItemCount向左循环滚动到最后一个位置 v = viewPackages.get(viewPackages.size() - 1).getView(); v.requestFocus(); invalidate(); } break; } case KeyEvent.KEYCODE_DPAD_RIGHT: { View v = findViewById(this.focusItem.getNextFocusRightId()); if (v != null) { v.requestFocus(); invalidate(); } else {//用于处理推荐资产数量小于showItemCount向右循环滚动到第一个位置 v = viewPackages.get(0).getView(); v.requestFocus(); invalidate(); } break; } case KeyEvent.KEYCODE_DPAD_CENTER: this.focusItem.performClick(); break; case KeyEvent.KEYCODE_ENTER: //部分盒子的home按键的键值并不是KEYCODE_DPAD_CENTER this.focusItem.performClick(); break; default: //对于无法识别的按键键值默认直接返回 break; } return true; } private Drawable focusShadowDrawable; private boolean isDrawFocusItem = true; private int mFocusEdgeOffset = getResources().getDimensionPixelSize(R.dimen.d_0dp); @Override protected void dispatchDraw(Canvas canvas) { super.dispatchDraw(canvas); if (focusItem != null && focusItem.isFocused() && isDrawFocusItem) { if (focusShadowDrawable == null) { focusShadowDrawable = context.getResources().getDrawable(R.drawable.main_page_item_selected); } Rect toFocusedViewRect = UIUtil.createViewRect(this, focusItem, mFocusEdgeOffset); UIUtil.drawDrawableAt(canvas, toFocusedViewRect, focusShadowDrawable, true); } } private int focusedItemIndex = -1; private View focusItem = null; @Override protected int getChildDrawingOrder(int childCount, int i) { if (focusedItemIndex < 0) return i; if (i < (childCount - 1)) { if (focusedItemIndex == i) i = childCount - 1; } else { if (focusedItemIndex < childCount) i = focusedItemIndex; } return i; } public void setFocusedItemIndex(View focusItem) { this.focusItem = focusItem; this.focusedItemIndex = indexOfChild(focusItem); if (focusItem == null) { return; } if (adapter == null || adapter.getCount() <= showItemCount) { return; } String TAG="chenming"; if (KeyEvent.KEYCODE_DPAD_RIGHT == keyCode) { if (currentIndex < 0) { currentIndex = 0; } if (currentIndex <= showItemCount - 1) { currentIndex++; } } else if (KeyEvent.KEYCODE_DPAD_LEFT == keyCode) { if (currentIndex > showItemCount - 1) { currentIndex = showItemCount - 1; } if (currentIndex >=0) { currentIndex--; } } if (currentIndex < 0) { isDrawFocusItem = false; scrollPreItem(); } else if (currentIndex > showItemCount - 1) { isDrawFocusItem = false; scrollNextItem(); } else { postInvalidate(); } } }