I have a fairly simple question which somehow I can't figure out. I'm using a FrameLayout with an own view (onDrawn is overriden) and another transparent view which extends LinearLayout. I want to add scrolling for the transparent view, but if I use ScrollView in the XML a Classcast exception is thrown.
My alternative was to implement scrolling on my own (e.g. with scrollTo in LinearLayout, where I can't find any example using that method), but the OnGestureListener doesn't trigger onScroll, while onShowPress and onLongPress are triggered. I then tried to use onTouchEvent in the LinearLayout, but it only recognises ACTION_DOWN, not ACTION_MOVE. In my own view all that works perfectly.
Here the XML:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/home_container" android:layout_width="fill_parent" android:layout_height="fill_parent"> <com.unimelb.pt2.ui.WaterfallView android:id="@+id/waterfall_view" android:layout_width="fill_parent" android:layout_height="fill_parent" android:apiKey="0DUEIIn35xtmfWC2DXprK5kqNF-aEaNgRJ4ONxw"/> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" android:gravity="bottom" android:paddingLeft="0px" android:paddingTop="0px" android:paddingRight="0px"> <com.unimelb.pt2.ui.TransparentPanel android:id="@+id/workbench" android:layout_width="fill_parent" android:layout_height="10px" android:paddingTop="0px" android:paddingLeft="0px" android:paddingBottom="0px" android:paddingRight="0px"> </com.unimelb.pt2.ui.TransparentPanel> </LinearLayout> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="horizontal" android:gravity="right" android:paddingLeft="0px" android:paddingTop="0px" android:paddingRight="0px"> <com.unimelb.pt2.ui.TransparentPanel android:id="@+id/tagarea" android:layout_width="50px" android:layout_height="fill_parent" android:paddingTop="0px" android:paddingLeft="0px" android:paddingBottom="0px" android:paddingRight="0px"> </com.unimelb.pt2.ui.TransparentPanel> </LinearLayout> </FrameLayout> Here the basic construct of the WaterfallView:
public class WaterfallView extends View { private GestureDetector gestureScanner; private Vector<PictureEntry> allPictures = new Vector<PictureEntry>(); public WaterfallView(Context context) { super(context); this.initialize(context); } public void initialize(Context context) { this.setFocusable(true); this.setClickable(true); this.context = context; allPictures.add(new PictureEntry(context, R.drawable.sample_0)); allPictures.add(new PictureEntry(context, R.drawable.sample_1)); allPictures.add(new PictureEntry(context, R.drawable.sample_2)); allPictures.add(new PictureEntry(context, R.drawable.sample_3)); allPictures.add(new PictureEntry(context, R.drawable.sample_4)); allPictures.add(new PictureEntry(context, R.drawable.sample_5)); allPictures.add(new PictureEntry(context, R.drawable.sample_6)); allPictures.add(new PictureEntry(context, R.drawable.sample_7)); } public void setGestureDetector(GlassPane gp) { gestureScanner = new GestureDetector(context, gp); } @Override protected void onDraw(Canvas canvas) { Iterator<PictureEntry> iter = allPictures.iterator(); int i = 0; while (iter.hasNext()) { PictureEntry pic = iter.next(); pic.draw(canvas) } invalidate(); } @Override public boolean onTouchEvent(MotionEvent event) { if (gestureScanner.onTouchEvent(event)) { return Prototype.glass.pictureTouch(event); } else return false; } } Here the basic construct of the GlassPane:
public class GlassPane implements OnGestureListener { public GlassPane(WaterfallView waterfall) { super(); waterfall.setGestureDetector(this); } public boolean pictureTouch(MotionEvent event) { // Handles drag and drop and zoom pinch } public boolean onDown(MotionEvent e) { Log.i("Test", "DOWN"); return false; } public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i("Test", "FLING"); return false; } @Override public void onLongPress(MotionEvent e) { Log.i("Test", "LONG PRESS"); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.i("Test", "SCROLL"); return true; } @Override public void onShowPress(MotionEvent e) { Log.i("Test", "SHOW PRESS"); } } And here the construct of the TransparentPanel:
public class TransparentPanel extends LinearLayout { private Paint innerPaint, borderPaint; private int width, height, scrollOffset; private Context mContext; public TransparentPanel(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; init(); } public TransparentPanel(Context context) { super(context); init(); } private void init() { innerPaint = new Paint(); innerPaint.setARGB(225, 75, 75, 75); // gray innerPaint.setAntiAlias(true); } public void setDimension(int w, int h) { width = w; height = h; this.setLayoutParams(new LayoutParams(width, height)); this.invalidate(); } @Override protected void dispatchDraw(Canvas canvas) { RectF drawRect = new RectF(); drawRect.set(0, 0, width, height); canvas.drawRect(drawRect, innerPaint); super.dispatchDraw(canvas); } private void measure() { if(this.getOrientation()==LinearLayout.VERTICAL) { int h = 0; for(int i=0; i<this.getChildCount(); i++) { View v = this.getChildAt(i); h += v.getMeasuredHeight(); } height = (h < height) ? height : h; Log.d(Prototype.TAG, "mW:"+width+", mH:"+height); } this.setMeasuredDimension(width, height); } }