Thursday, January 27, 2011

Android wheel update: custom views for items

I'm glad to inform you about updating the wheel control. There has been implemented the main feature for this widget - the ability for using  custom views for wheel items, like in the ListView control.


Now it is possible to show anything in the wheel, as simple text items

... as images

Looks nice :)

How to use
For simple text items there can be used ArrayWheelAdapter and ArrayWheelAdapter adapters, like before. They work also with user defined layouts for items and the wheel label.
For complex wheel items there should be used user defined adapters by implementing the WheelViewAdapter interface. For text based adapters there can be used the AbstractWheelAdapter class as a base.

Constraints

All wheel items should have the same height to be corrected rendered. The label height should be less than the height of wheel item.
The label width should not be so big since items are show in the rest area.


Backward compatibility
All application using the wheel should work with new adapters, but with small fix: ArrayWheelAdapter and ArrayWheelAdapter adapters have been moved to the kankan.wheel.widget.adapters package.
The old WheelAdapter interface has been set as deprecated and will be removed in next builds, with  corresponding WheelView methods. There should be used the WheelViewAdapter interface instead.

Tuesday, January 18, 2011

Scrolling inside ScrollView

There was an issue with wheel view related to the scrolling functionality. It did not work if wheel is placed inside a ScrollView.

I've investigated standard controls and found a one that does work alike (multiline EditText) and a one working as expected (SeekBar). I would like to check also ScrollView inside a ScrollView, but fortunately I did find a solution for this issue only by using SeekBar sources from Android SDK (I have old ones, but it was enough).

The main problem was with WheelView.onTouchEvent() - it did not receive all touch events because they were processed by parent (scroll view). So it needed to ask the ScrollView to skip touch events and allow the wheel to perform them by onTouchEvent(). There is a corresponding method for a parent view called ViewParent.requestDisallowInterceptTouchEvent(). SeekBar calls it during handling the ACTION_MOVE touch event action. I've added this approach to the wheel view and it works too! :)

@Override
public boolean onTouchEvent(MotionEvent event) {
    if (getViewAdapter() == null) {
        return true;
    }
 
    if (!gestureDetector.onTouchEvent(event) && event.getAction() == MotionEvent.ACTION_UP) {
        justify();
    }
 
    // Fix scrolling
    if (event.getAction() == MotionEvent.ACTION_MOVE && getParent() != null) {
        getParent().requestDisallowInterceptTouchEvent(true);
    }
 
    return true;
}


I'm unable to commit this fix now because of working on custom views for wheel items; will do that later. So please fix your code manually. Thanks!