2016-08-01 8 views
-2

このpictureには、CardViewが表示され、各項目は一度に1つずつ表示されます。データセットをスクロールするタッチ機能を実装しました。私は今、ランダムにアイテムを選択する機能を実装したいと思います。 CardViewが設定されているのはここれる:CardViewでランダムな項目を選択

package com.chiemy.cardview.view; 

import android.content.Context; 
import android.database.DataSetObserver; 
import android.graphics.Rect; 
import android.util.AttributeSet; 
import android.util.SparseArray; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.ViewConfiguration; 
import android.view.animation.AccelerateInterpolator; 
import android.widget.FrameLayout; 
import android.widget.ListAdapter; 

import com.nineoldandroids.animation.Animator; 
import com.nineoldandroids.animation.AnimatorListenerAdapter; 
import com.nineoldandroids.view.ViewHelper; 
import com.nineoldandroids.view.ViewPropertyAnimator; 

/** 
* @author chiemy 
* 
*/ 
public class CardView extends FrameLayout { 
    private static final int ITEM_SPACE = 40; 
    private static final int DEF_MAX_VISIBLE = 4; 

    private int mMaxVisible = DEF_MAX_VISIBLE; 
    private int itemSpace = ITEM_SPACE; 

    private float mTouchSlop; 
    private ListAdapter mListAdapter; 
    private int mNextAdapterPosition; 
    private SparseArray<View> viewHolder = new SparseArray<View>(); 
    private OnCardClickListener mListener; 
    private int topPosition; 
    private Rect topRect; 

    public interface OnCardClickListener { 
     void onCardClick(View view, int position); 
    } 

    public CardView(Context context, AttributeSet attrs, int defStyle) { 
     super(context, attrs, defStyle); 
     init(); 
    } 

    public CardView(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     init(); 
    } 

    public CardView(Context context) { 
     super(context); 
     init(); 
    } 

    private void init() { 
     topRect = new Rect(); 
     ViewConfiguration con = ViewConfiguration.get(getContext()); 
     mTouchSlop = con.getScaledTouchSlop(); 
    } 

    public void setMaxVisibleCount(int count) { 
     mMaxVisible = count; 
    } 

    public int getMaxVisibleCount() { 
     return mMaxVisible; 
    } 

    public void setItemSpace(int itemSpace) { 
     this.itemSpace = itemSpace; 
    } 

    public int getItemSpace() { 
     return itemSpace; 
    } 

    public ListAdapter getAdapter() { 
     return mListAdapter; 
    } 

    public void setAdapter(ListAdapter adapter) { 
     if (mListAdapter != null) { 
      mListAdapter.unregisterDataSetObserver(mDataSetObserver); 
     } 
     mNextAdapterPosition = 0; 
     mListAdapter = adapter; 
     adapter.registerDataSetObserver(mDataSetObserver); 
     removeAllViews(); 
     ensureFull(); 
    } 

    public void setOnCardClickListener(OnCardClickListener listener) { 
     mListener = listener; 
    } 

    private void ensureFull() { 
     while (mNextAdapterPosition < mListAdapter.getCount() 
       && getChildCount() < mMaxVisible) { 
      int index = mNextAdapterPosition % mMaxVisible; 
      View convertView = viewHolder.get(index); 
      final View view = mListAdapter.getView(mNextAdapterPosition, 
        convertView, this); 
      view.setOnClickListener(null); 
      viewHolder.put(index, view); 

      index = Math.min(mNextAdapterPosition, mMaxVisible - 1); 
      ViewHelper.setScaleX(view,((mMaxVisible - index - 1)/(float) mMaxVisible) * 0.2f + 0.8f); 
      int topMargin = (mMaxVisible - index - 1) * itemSpace; 
      ViewHelper.setTranslationY(view, topMargin); 
      ViewHelper.setAlpha(view, mNextAdapterPosition == 0 ? 1 : 0.5f); 

      LayoutParams params = (LayoutParams) view.getLayoutParams(); 
      if (params == null) { 
       params = new LayoutParams(LayoutParams.MATCH_PARENT, 
         LayoutParams.WRAP_CONTENT); 
      } 
      addViewInLayout(view, 0, params); 

      mNextAdapterPosition += 1; 
     } 
     // requestLayout(); 
    } 

    @Override 
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 
     int widthMode = MeasureSpec.getMode(widthMeasureSpec); 
     int heightMode = MeasureSpec.getMode(heightMeasureSpec); 
     int widthSize = MeasureSpec.getSize(widthMeasureSpec); 
     int heightSize = MeasureSpec.getSize(heightMeasureSpec); 

     int childCount = getChildCount(); 
     int maxHeight = 0; 
     int maxWidth = 0; 
     for (int i = 0; i < childCount; i++) { 
      View child = getChildAt(i); 
      this.measureChild(child, widthMeasureSpec, heightMeasureSpec); 
      int height = child.getMeasuredHeight(); 
      int width = child.getMeasuredWidth(); 
      if (height > maxHeight) { 
       maxHeight = height; 
      } 
      if (width > maxWidth) { 
       maxWidth = width; 
      } 
     } 
     int desireWidth = widthSize; 
     int desireHeight = heightSize; 
     if (widthMode == MeasureSpec.AT_MOST) { 
      desireWidth = maxWidth + getPaddingLeft() + getPaddingRight(); 
     } 
     if (heightMode == MeasureSpec.AT_MOST) { 
      desireHeight = maxHeight + (mMaxVisible - 1) * itemSpace + getPaddingTop() + getPaddingBottom(); 
     } 
     setMeasuredDimension(desireWidth, desireHeight); 
    } 

    @Override 
    protected void onLayout(boolean changed, int left, int top, int right, 
      int bottom) { 
     super.onLayout(changed, left, top, right, bottom); 
     View topView = getChildAt(getChildCount() - 1); 
     if (topView != null) { 
      topView.setOnClickListener(listener); 
     } 
    } 

    float downX, downY; 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
     switch (event.getAction()) { 
     case MotionEvent.ACTION_MOVE: 
      if (goDown()) { 
       downY = -1; 
      } 
      break; 
     } 
     return super.onTouchEvent(event); 
    } 

    /** 
    * 下移所有视图 
    */ 
    private boolean goDown() { 
     final View topView = getChildAt(getChildCount() - 1); 
     if(!topView.isEnabled()){ 
      return false; 
     } 
     // topView.getHitRect(topRect); 在4.3以前有bug,用以下方法代替 
     topRect = getHitRect(topRect, topView); 
     // 如果按下的位置不在顶部视图上,则不移动 
     if (!topRect.contains((int) downX, (int) downY)) { 
      return false; 
     } 
     topView.setEnabled(false); 
     ViewPropertyAnimator anim = ViewPropertyAnimator 
       .animate(topView) 
       .translationY(
         ViewHelper.getTranslationY(topView) 
           + topView.getHeight()).alpha(0).scaleX(1) 
       .setListener(null).setDuration(200); 
     anim.setListener(new AnimatorListenerAdapter() { 
      @Override 
      public void onAnimationEnd(Animator animation) { 
       topView.setEnabled(true); 
       removeView(topView); 
       ensureFull(); 
       final int count = getChildCount(); 
       for (int i = 0; i < count; i++) { 
        final View view = getChildAt(i); 
        float scaleX = ViewHelper.getScaleX(view) 
          + ((float) 1/mMaxVisible) * 0.2f; 
        float tranlateY = ViewHelper.getTranslationY(view) 
          + itemSpace; 
        if (i == count - 1) { 
         bringToTop(view); 
        } else { 
         if ((count == mMaxVisible && i != 0) 
           || count < mMaxVisible) { 
          ViewPropertyAnimator 
            .animate(view) 
            .translationY(tranlateY) 
            .setInterpolator(
              new AccelerateInterpolator()) 
            .setListener(null).scaleX(scaleX) 
            .setDuration(200); 
         } 
        } 
       } 
      } 
     }); 
     return true; 
    } 

    private void bringToTop(final View view) { 
     topPosition++; 
     float scaleX = ViewHelper.getScaleX(view) + ((float) 1/mMaxVisible) 
       * 0.2f; 
     float tranlateY = ViewHelper.getTranslationY(view) + itemSpace; 
     ViewPropertyAnimator.animate(view).translationY(tranlateY) 
       .scaleX(scaleX).setDuration(200).alpha(1) 
       .setInterpolator(new AccelerateInterpolator()); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent ev) { 
     float currentY = ev.getY(); 
     switch (ev.getAction()) { 
     case MotionEvent.ACTION_DOWN: 
      downX = ev.getX(); 
      downY = ev.getY(); 
      break; 
     case MotionEvent.ACTION_MOVE: 
      float distance = currentY - downY; 
      if (distance > mTouchSlop) { 
       return true; 
      } 
      break; 
     } 
     return false; 
    } 

    public static Rect getHitRect(Rect rect, View child) { 
     rect.left = child.getLeft(); 
     rect.right = child.getRight(); 
     rect.top = (int) (child.getTop() + ViewHelper.getTranslationY(child)); 
     rect.bottom = (int) (child.getBottom() + ViewHelper 
       .getTranslationY(child)); 
     return rect; 
    } 

    private final DataSetObserver mDataSetObserver = new DataSetObserver() { 
     @Override 
     public void onChanged() { 
      super.onChanged(); 
     } 

     @Override 
     public void onInvalidated() { 
      super.onInvalidated(); 
     } 
    }; 

    private OnClickListener listener = new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      if (mListener != null) { 
       mListener.onCardClick(v, topPosition); 
      } 
     } 
    }; 
} 

ここに私のCardViewアダプタクラスは次のようになります。これを実現する方法について

package com.chiemy.cardview.view; 

import java.util.ArrayList; 
import java.util.Collection; 
import java.util.List; 

import android.content.Context; 
import android.view.View; 
import android.view.ViewGroup; 
import android.widget.FrameLayout; 

import com.chiemy.cardview.R; 

public abstract class CardAdapter<T> extends BaseCardAdapter { 
    private final Context mContext; 

    private ArrayList<T> mData; 

    public CardAdapter(Context context) { 
     mContext = context; 
     mData = new ArrayList<T>(); 
    } 

    public CardAdapter(Context context, Collection<? extends T> items) { 
     mContext = context; 
     mData = new ArrayList<T>(items); 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     FrameLayout wrapper = (FrameLayout) convertView; 
     View cardView; 
     View convertedCardView; 
     if (wrapper == null) { 
      wrapper = new FrameLayout(mContext); 
      wrapper.setBackgroundResource(R.drawable.card_background_shadow); 
      cardView = getCardView(position, null, wrapper); 
      wrapper.addView(cardView); 
     } else { 
      cardView = wrapper.getChildAt(0); 
      convertedCardView = getCardView(position, cardView, wrapper); 

      wrapper.removeView(cardView); 
      wrapper.addView(convertedCardView); 
      if (convertedCardView != cardView) { 
      } 
     } 
     return wrapper; 
    } 

    protected abstract View getCardView(int position, View convertView, ViewGroup parent); 

    public void addAll(List<T> items){ 
     mData.addAll(items); 
    } 

    @Override 
    public T getItem(int position) { 
     return mData.get(position); 
    } 

    @Override 
    public int getCount() { 
     return mData.size(); 
    } 

    @Override 
    public long getItemId(int position) { 
     return getItem(position).hashCode(); 
    } 

    public Context getContext() { 
     return mContext; 
    } 

    public void clear(){ 
     if(mData != null){ 
      mData.clear(); 
     } 
    } 
} 

任意の提案ですか? ArrayList<>をランダム化

+0

は、この質問に関連するすべての情報を入れて、それがまた – HCarrasko

+0

へのリンクを追加aviod、あなたは私は私の質問を編集した@Razor – Razor

+0

少し不明確であるとして、あなたの質問に明確にしてくださいすることができ、他の外部リソース – Razor

答えて

1

は、あなたのケースで、これはシャッフル解決策になる、あなたはこのコードを使用することができます:

long seed = System.nanoTime(); 
Collections.shuffle(list_of_items, new Random(seed)); 

あなたはCardViewArrayList<>バックを設定する必要がありますし、あなたのアイテムがランダムになりますシャッフル。ランダムアイテムを取得するには、ArrayList<>からランダムアイテムを取得する方法についてはthisページをご覧ください。あなたがどうやって行って、必要に応じてもっと助けを求めるかを見てください。

+0

答えが少し急いでいる場合は申し訳ありません。私はタブレットから入力しており、コードを追加するのは少し難しいです。 – Razor

+0

ありがとうございます。しかし、私が最初に持っている問題は、自動スクロールしたいアイテムがあるということです。http://i.stack.imgur.com/WXyzC.gif @Razor – hosein

+0

あなたが望むなら、非常に難しいアニメーションを実装する必要がありますスクロールの種類。あなたのシャッフル能力の点では、アイテムの 'ArrayList <>'をランダム化し、上記のようにランダムに選択することをお勧めします。 – Razor

関連する問題