I am trying to make a custom Listview like in the ios app Applauze.
I extended the listview class and with the help of onTouchEvent tried to detect the movement of the child rows and change their heights on movement. So that the topmost child has the largest height as compared to other rows.
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);
}
}
But the problem is that the drawchild function is being called repeatedly as i saw in my logs which is making the listview less responsive. And also what would be the best way to apply animation to each row?? If anyone knows the reason please let me know!!! Thanks.
As you are doing lot of work in drawChild() function which is called repeatedly will obviously insert lagging thereby making your listview less responsive. So, possibly you can skip some of the drawChild() function calls based on some timer or other logic. This we normally do when we handle sensor events in the application. Implementing this should be simple only.
For list view row animations you can follow the below link. Best way to animate will be to write animation xmls and then use them to animate rows in listview:
http://karnshah8890.blogspot.kr/2013/04/listview-animation-tutorial.html
Hope this helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With