iOSアプリApplauzeのようなカスタムListviewを作ろうとしています.
リストビュー クラスを拡張し、onTouchEvent の助けを借りて、子行の動きを検出し、動きに合わせて高さを変更しようとしました。一番上の子が他の行と比較して最大の高さを持つようにします。
public class CustView extends ListView{
private float mLastTouchY;
private int mActivePointerId;
private boolean up=false;
private boolean down=false;
private final Camera mCamera = new Camera();
private final Matrix mMatrix = new Matrix();
private Context context;
private Paint mPaint;
public CustView(Context context, AttributeSet attrs) {
super(context, attrs);
this.context = context;
this.setChildrenDrawingOrderEnabled(true);
}
public CustView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
// TODO Auto-generated constructor stub
}
@Override
protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
// get top left coordinates
boolean isTop = false;
final int top = child.getTop();
final int bottom = child.getBottom();
child.setMinimumHeight(getHeight()/3);
Bitmap bitmap = child.getDrawingCache();
Bitmap cropBitmap;
if (bitmap == null) {
child.setDrawingCacheEnabled(true);
child.buildDrawingCache();
bitmap = child.getDrawingCache();
}
int belowE = (child.getHeight()*2/3)+getPaddingTop();
int aboveE = (child.getHeight())+getPaddingTop();
mCamera.save();
if(up){
if (top>=belowE) {
//make all small
isTop = true;
//canvas.scale(1.0f, 0.5f);
cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()/2);
child.setMinimumHeight(2);
//child.setLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
child.setPressed(true);
Log.e("Chota", child.getMeasuredHeight()+"True"+top);
}
else {
//canvas.scale(1.0f,xy);
cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
//child.setLayoutParams(LayoutParams.WRAP_CONTENT,LayoutParams.WRAP_CONTENT));
//child.setMinimumHeight(4);
Log.e("Bada", child.getMeasuredHeight()+"False"+top);
child.setPressed(false);
};
}
else{
if (bottom>aboveE) {
//make center row bigger
isTop = true;
//canvas.scale(1.0f, 0.5f);
cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight()/2);
child.setMinimumHeight(2);
child.setPressed(true);
Log.e("Bada", child.getMeasuredHeight()+"True"+top);
}
else {
//canvas.scale(1.0f,xy);
cropBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight());
//child.setMinimumHeight(getHeight()/4);
Log.e("Chota", child.getMeasuredHeight()+"False"+top);
child.setPressed(false);
};
}
mCamera.getMatrix(mMatrix);
mCamera.restore();
// create and initialize the paint object
if (mPaint == null) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setFilterBitmap(true);
}
mMatrix.postScale(1.0f, 1.5f);
mMatrix.postTranslate(child.getLeft(), top);
canvas.drawBitmap(cropBitmap, mMatrix, mPaint);
//Log.e("Up", "Child"+top+" "+getTop());
return false;
}
/* (non-Javadoc)
* @see android.widget.AbsListView#onTouchEvent(android.view.MotionEvent)
*/
@Override
public boolean onTouchEvent(MotionEvent ev) {
// TODO Auto-generated method stub
final int action = MotionEventCompat.getActionMasked(ev);
int INVALID_POINTER_ID=65421385;
switch (action) {
case MotionEvent.ACTION_DOWN: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
// Remember where we started (for dragging)
mLastTouchY = MotionEventCompat.getY(ev, pointerIndex);
// Save the ID of this pointer (for dragging)
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
Log.e("Down", "Down");
break;
}
case MotionEvent.ACTION_MOVE: {
// Find the index of the active pointer and fetch its position
final int pointerIndex =
MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float y = MotionEventCompat.getY(ev, pointerIndex);
// Calculate the distance moved
final float dy = y - mLastTouchY;
up = dy<0;
down = dy>0;
//((MyAdapter)getListAdapter()).animate(fVI,top,bottom,getChildCount());
if(Math.abs(dy)>10){
Log.e("Dist", "D-"+Math.abs(dy));
invalidate();
}
// Remember this touch position for the next move event
mLastTouchY = y;
Log.e("Move", "Move");
break;
}
case MotionEvent.ACTION_UP: {
mActivePointerId = INVALID_POINTER_ID;
Log.e("Up", "Up");
break;
}
case MotionEvent.ACTION_CANCEL: {
mActivePointerId = INVALID_POINTER_ID;
break;
}
case MotionEvent.ACTION_POINTER_UP: {
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
// This was our active pointer going up. Choose a new
// active pointer and adjust accordingly.
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mLastTouchY = MotionEventCompat.getY(ev, newPointerIndex);
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
break;
}
}
return super.onTouchEvent(ev);
}
/* (non-Javadoc)
* @see android.view.View#onScrollChanged(int, int, int, int)
*/
@Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
// TODO Auto-generated method stub
super.onScrollChanged(l, t, oldl, oldt);
}
}
しかし問題は、ログで見たように drawchild 関数が繰り返し呼び出されているため、リストビューの応答性が低下していることです。また、各行にアニメーションを適用する最良の方法は何ですか?? 理由がわかる方教えてください!!!ありがとう。