package com.wasu.cs.widget; import java.util.ArrayList; import java.util.List; import java.util.Stack; 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 cn.com.wasu.main.AppUtil; import cn.com.wasu.main.R; import com.wasu.widget.util.UIUtil; public class SpecialListView extends FrameLayout { private Context context; public SpecialListView(Context context) { super(context); init(context); } public SpecialListView(Context context, AttributeSet attrs) { super(context, attrs); init(context); } public SpecialListView(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 = 5; 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 FrameLayout.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.setNextFocusDownId(view.getId()); view.setNextFocusUpId(preItem.getId()); } return vp; } private void firstLoadViews() { if (adapter == null) return; removeAllViews(); int count = adapter.getCount(); View preView = null; ViewPackage vp = null; for (int i = 0; i < showItemCount+2; i++) { if(i+1 > count) break; vp = createViewPackage(i, preView); if (vp != null) { addView(vp.getView()); viewPackages.add(vp); preView = vp.getView(); } } } private void reloadAllView() { } private boolean isInitLayout = false; private int mSpacing = getResources().getDimensionPixelSize(R.dimen.d_21dp); @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 pWidth = r - l; int top = getPaddingTop(); while (i < viewPackages.size()) { child = viewPackages.get(i).getView(); int left = (pWidth - child.getMeasuredWidth()) / 2; int right = left + child.getMeasuredWidth(); int bottom = top + child.getMeasuredHeight(); child.layout(left, top, right, bottom); top += child.getMeasuredHeight() + mSpacing; i++; } modifyPosition(); isInitLayout = true; } private View newItem = null; private void fillTop() { 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; return; } View newView = adapter.getView(position, view, null); if (newView == null) return; newView.setVisibility(View.GONE); vp.setView(newView); vp.setPosition(position); viewPackages.insertElementAt(vp, 0); firstView.setNextFocusUpId(newView.getId()); newView.setNextFocusDownId(firstView.getId()); newView.setNextFocusUpId(newView.getId()); int top = firstView.getTop() - newView.getMeasuredHeight() - mSpacing; int left = newView.getLeft(); int right = newView.getRight(); int bottom = top + newView.getMeasuredHeight(); newView.layout(left, top, right, bottom); // newView.setY(top); newView.setVisibility(View.VISIBLE); newView.setFocusable(false); newItem = newView; modifyPosition(); } private void fillDown() { 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; return; } View newView = adapter.getView(position, view, null); if (newView == null) return; newView.setVisibility(View.GONE); vp.setView(newView); vp.setPosition(position); viewPackages.add(vp); lastView.setNextFocusDownId(newView.getId()); newView.setNextFocusUpId(lastView.getId()); newView.setNextFocusDownId(newView.getId()); int top = lastView.getTop() + lastView.getMeasuredHeight() + mSpacing; int left = newView.getLeft(); int right = newView.getRight(); int bottom = top + newView.getMeasuredHeight(); newView.layout(left, top, right, bottom); // newView.setY(top); newView.setVisibility(View.VISIBLE); newView.setFocusable(false); newItem = newView; modifyPosition(); } private void scrollPreItem() { int position = viewPackages.firstElement().getPosition(); if(focusedItemIndex<1 && position > 0) { fillTop(); } animViews(false); } private void scrollNextItem() { int position = viewPackages.lastElement().getPosition(); if(focusedItemIndex > showItemCount && position+1 < adapter.getCount()) { fillDown(); } animViews(true); } private int anim_duration = 200; private void animViews(boolean scrollLeft) { float y = focusItem.getY(); float paddingTop = getPaddingTop(); int maxY = getMeasuredHeight() - getPaddingBottom() - focusItem.getMeasuredHeight(); if(y >= paddingTop && y <= maxY) { isDrawFocusItem = true; return; } int count = viewPackages.size(); if(scrollLeft) { y = maxY - y; } else { y = paddingTop - y; } System.out.println("-------------iyadi y: " + y); if (y != 0) { List animators = new ArrayList(); AnimatorSet animatorSet = new AnimatorSet(); View child = viewPackages.get(0).getView(); System.out.println("-------------iyadi child.getY(): " + child.getY()); y = child.getY() + y; ObjectAnimator viewAnim = ObjectAnimator.ofFloat(child, "Y", y); viewAnim.setDuration(anim_duration); viewAnim.setInterpolator(new AccelerateDecelerateInterpolator()); animators.add(viewAnim); View tempView = child; for (int i=1; i < count; i++) { child = viewPackages.get(i).getView(); y += tempView.getMeasuredHeight() + mSpacing; viewAnim = ObjectAnimator.ofFloat(child, "Y", y); 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; postInvalidate(); if (newItem != null) { newItem.setFocusable(true); } } @Override public void onAnimationCancel(Animator animation) { } }); animatorSet.start(); } } private void modifyPosition() { ViewPackage vp = null; for (int i = 0; i < viewPackages.size(); i++) { vp = viewPackages.get(i); ShortVideoSpecialItem item = (ShortVideoSpecialItem) vp.getView(); item.setIndex(i); } } private int keyCode = 0; @Override public boolean onKeyDown(int keyCode, KeyEvent event) { this.keyCode = keyCode; return super.onKeyDown(keyCode, event); } 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 && 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 ShortVideoSpecialItem focusItem = null; /** * 获取子控件dispatchDraw的次序 */ @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; } /** * * @author 海迪 * @Title: setFocusedItemIndex * @Description: 设置当前获取焦点的Item及Index * @param @param focusItem 获取焦点的Item * @param @param focusedItemIndex 获取焦点Item的Index * @return void * @throws * * @param focusItem * @param focusedItemIndex */ public void setFocusedItemIndex(ShortVideoSpecialItem focusItem, int focusedItemIndex) { this.focusItem = focusItem; this.focusedItemIndex = focusedItemIndex; if(focusItem != null && onItemSelectedListener != null) { onItemSelectedListener.onItemSelected(focusItem, focusItem.getPosition()); } this.postInvalidate(); if (focusItem == null) { return; } if (adapter == null || adapter.getCount() < showItemCount) { return; } if (KeyEvent.KEYCODE_DPAD_DOWN == keyCode) { isDrawFocusItem = false; scrollNextItem(); } else if (KeyEvent.KEYCODE_DPAD_UP == keyCode) { isDrawFocusItem = false; scrollPreItem(); } } public interface OnItemSelectedListener { public void onItemSelected(View view, int position); } private OnItemSelectedListener onItemSelectedListener; public void setOnItemSelectedListener( OnItemSelectedListener onItemSelectedListener) { this.onItemSelectedListener = onItemSelectedListener; } }