handle sticky mode
I've created following class to handle sticky mode for wheelView.
use this if you need sticky mode for your wheelView.
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.util.AttributeSet;
import android.view.MotionEvent;
import com.lukedeighton.wheelview.WheelView;
import java.util.Timer;
import java.util.TimerTask;
/**
* Created by shayan on 10/20/17.
*/
public class StickyWheelView extends WheelView implements WheelView.OnWheelAngleChangeListener {
Timer timer;
TimerTask timerTask;
boolean handleSticky;
Handler uiHandler;
OnWheelAngleChangeListener onWheelAngleChangeListener;
public StickyWheelView(Context context) {
super(context);
init();
}
public StickyWheelView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public StickyWheelView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init() {
super.setOnWheelAngleChangeListener(this);
uiHandler = new Handler(Looper.getMainLooper());
}
@Override
public void setOnWheelAngleChangeListener(OnWheelAngleChangeListener listener) {
this.onWheelAngleChangeListener = listener;
}
@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
handleSticky = false;
} else if (event.getAction() == MotionEvent.ACTION_UP) {
handleSticky = true;
onWheelAngleChange(getAngle());
}
return super.onTouchEvent(event);
}
@Override
public void onWheelAngleChange(float angle) {
timer = invalidateTimerAndCreateNew(timer, timerTask);
timerTask = new TimerTask() {
@Override
public void run() {
goToNearestFixItem();
}
};
timer.schedule(timerTask, 100);
// call listener if is not null
if (onWheelAngleChangeListener != null) {
onWheelAngleChangeListener.onWheelAngleChange(angle);
}
}
private void goToNearestFixItem() {
if (!handleSticky) {
return;
}
// getAngle is wide range, we map it too 0 - 360
float correctAngle = Math.abs(getAngle()) % 360;
// each item angle
float itemAngle = 360 / getWheelItemCount();
// item is currently sticky.
if (correctAngle % itemAngle == 0) {
return;
}
int power = Math.abs((int) (getAngle() / 360));
float nextAngle = ((int) (correctAngle / itemAngle) + 1) * itemAngle + (360 * power);
float preAngle = ((int) (correctAngle / itemAngle)) * itemAngle + (360 * power);
int sign = getAngle() < 0 ? -1 : 1;
if (correctAngle % itemAngle > itemAngle / 2) {
goToAngleWithAnimation(nextAngle * sign);
} else {
goToAngleWithAnimation(preAngle * sign);
}
}
private float temporaryFinalAngel;
private void goToAngleWithAnimation(float angle) {
temporaryFinalAngel = angle;
final boolean increase;
increase = getAngle() <= angle;
uiHandler.post(new Runnable() {
@Override
public void run() {
if (temporaryFinalAngel == getAngle()) {
return;
}
// user changed angle again, don't set angle again
if (!handleSticky) {
return;
}
float nextAngle;
if (increase) {
nextAngle = Math.min(getAngle() + 3, temporaryFinalAngel);
} else {
nextAngle = Math.max(getAngle() - 3, temporaryFinalAngel);
}
setAngle(nextAngle);
uiHandler.postDelayed(this, 10);
}
});
}
private Timer invalidateTimerAndCreateNew(Timer timer, TimerTask timerTask) {
if (timer != null) {
timer.cancel();
timer.purge();
}
if (timerTask != null) {
timerTask.cancel();
}
timer = new Timer();
return timer;
}
}
for use this class add StickyWheelView instead of WheelView in your xml or java code
I know this is kind of a late time, but were you able to test this with an odd number of items? I found a bug where it doesn't sticks properly with in this case
@shayanpourvatan For which purpose it is used and how to use this component? Can you please share some more info about StickyWheelView.
@jinchuika Sorry for the late answer: I don't remind this class actually, in one project we need to show one item as sticky, the project started in the hackathon and I write this code, actually, I don't test it in the real application with the dynamic case,
@prem-p-simform For using this class you need to replace it with default wheelView, in XML or Java class, everywhere you have wheelView, simply replace it with this class, but as Jinchuika mentioned, this class might have some issue in the odd number of the items.
I can spend some time fixing it for odd number items, if it's an emergency to you tell me, I will fix issues.
@shayanpourvatan I have requirement of sticky item, For example sticky headers. I want to stick item at start of the list.
@prem-p-simform I think you need to search for other libraries, this library as shown on the start page, used for wheel items, I think you need a recyclerView sticky header.
I searched for that, Could not find RecyclerView LayoutManager which satisfy my needs. I need half cirlce layout and it should start from bottom and end in right side. Also item at bottom can be sticky, other can be scrolled.
@prem-p-simform This library is not what you want, I think you must write it by your self or do some hacky way ( I don't have an idea right now )