i want to drag and position a child in my Viewgroup. While dragging and scrolling my child shoud stay at top or bottom but i cant figure out how to do that.
Xml:
<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".ui.slideshow.SlideshowFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<CalendarView
android:id="@+id/calender_slideshow"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/blue_grey"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<de.littles.recipes.DaylyNotesLayout
android:id="@+id/daylynotes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/white"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/calender_slideshow"
app:layout_constraintStart_toStartOf="parent">
</de.littles.recipes.DaylyNotesLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</ScrollView>
My custom viewgroup
public class DaylyNotesLayout extends ViewGroup implements View.OnTouchListener, View.OnLongClickListener{
private List<DayScheduleData> dayScheduleData = new ArrayList<>();
int deviceWidth, deviceHeight;
float dX;
float dY;
int lastAction;
Point deviceDisplay = new Point();
private final int columnHeight = 115;
public DaylyNotesLayout(Context context) {
super(context);
init(context);
}
public DaylyNotesLayout(Context context, AttributeSet attrs) {
super(context, attrs);
init(context);
}
public DaylyNotesLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
public DaylyNotesLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(context);
}
private void init(Context context) {
final Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
display.getSize(deviceDisplay);
deviceWidth = deviceDisplay.x;
deviceHeight = deviceDisplay.y;
}
public void clear() {
dayScheduleData.clear();
super.removeAllViews();
}
public void addNewView(View child, int startTime, int length) {
DayScheduleData childViewData = new DayScheduleData(child.getTag().toString(), startTime, length);
dayScheduleData.add(childViewData);
child.setOnTouchListener(this);
super.addView(child);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int count = getChildCount();
int curHeight, curLeft, curTop, maxHeight;
int childLeft = this.getPaddingLeft() + 80;
int childTop = this.getPaddingTop();
int childRight = this.getMeasuredWidth() - 20;
int childBottom;
int childWidth = childRight;
int childHeight;
maxHeight = 0;
int height = 0;
for (int x = 0; x < count; x++) {
View child = getChildAt(x);
int start = dayScheduleData.get(x).getStartTime();
curTop = start * columnHeight - (height * columnHeight);
height = dayScheduleData.get(x).getLength();
childBottom = childTop + (columnHeight * height) + this.getPaddingBottom();
childHeight = childBottom - childTop;
if (child.getVisibility() == GONE) {
return;
}
child.measure(MeasureSpec.makeMeasureSpec(childWidth, MeasureSpec.AT_MOST), MeasureSpec.makeMeasureSpec(childHeight - 5, MeasureSpec.EXACTLY));
curHeight = childHeight;
curLeft = childLeft;
curTop += maxHeight;
maxHeight = 0;
child.layout(curLeft, curTop + 10, childRight, curTop + curHeight - 10);
if (maxHeight < curHeight) {
maxHeight = curHeight;
}
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
int count = getChildCount();
int maxHeight = columnHeight * 24;
int maxWidth = 0;
int childState = 0;
int mLeftWidth = 0;
int rowCount = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
measureChild(child, widthMeasureSpec, heightMeasureSpec);
maxWidth += Math.max(maxWidth, child.getMeasuredWidth());
mLeftWidth += child.getMeasuredWidth();
if ((mLeftWidth / deviceWidth) > rowCount) {
rowCount++;
} else {
maxHeight = Math.max(maxHeight, child.getMeasuredHeight());
}
childState = combineMeasuredStates(childState, child.getMeasuredState());
}
maxHeight = Math.max(maxHeight, getSuggestedMinimumHeight());
maxWidth = Math.max(maxWidth, getSuggestedMinimumWidth());
setMeasuredDimension(resolveSizeAndState(maxWidth, widthMeasureSpec, childState),
resolveSizeAndState(maxHeight, heightMeasureSpec, childState << MEASURED_HEIGHT_STATE_SHIFT));
}
@Override
protected void onDraw(Canvas canvas) {
final float height = columnHeight;
Paint paint = new Paint();
paint.setColor(Color.BLACK);
TextPaint textPaint = new TextPaint();
textPaint.setColor(Color.BLACK);
textPaint.setTextSize(24);
textPaint.setAntiAlias(true);
for (int x = 0; x < 24; x++) {
paint.setStrokeWidth(2f);
paint.setAlpha(255);
if (x < 10) {
canvas.drawText("0" + x + ":00", 10, x * height + textPaint.getTextSize(), textPaint);
} else {
canvas.drawText(x + ":00", 10, x * height + textPaint.getTextSize(), textPaint);
}
canvas.drawLine(0, x * height, getMeasuredWidth(), x * height, paint);
paint.setStrokeWidth(2f);
paint.setAlpha(50);
canvas.drawLine(0, x * height + (height / 2), getMeasuredWidth(), x * height + (height / 2), paint);
}
}
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
dX = view.getX() - event.getRawX();
dY = view.getY() - event.getRawY();
lastAction = MotionEvent.ACTION_DOWN;
break;
case MotionEvent.ACTION_MOVE:
ScrollView mainScrollView = getRootView().findViewById(R.id.scrollView);
int dragTop = (int) (event.getRawY() - view.getHeight()/2);
int dragBottom= (int) (event.getRawY() + view.getHeight()/2);
int scrollY =mainScrollView.getScrollY();
int scrollViewHeight = mainScrollView.getMeasuredHeight();
Log.d("RawPos ", "" + event.getRawY());
Log.d("ScrollY", scrollY + "");
mainScrollView.requestDisallowInterceptTouchEvent(true);
if (dragBottom > (scrollViewHeight -100)) {
mainScrollView.smoothScrollBy(0, 30);
}
if (dragTop< (200)) {
mainScrollView.smoothScrollBy(0, -30);
}
view.setY(event.getRawY() + dY);
lastAction = MotionEvent.ACTION_MOVE;
break;
case MotionEvent.ACTION_UP:
view.setY((Math.round(view.getY() / columnHeight) * columnHeight) + 10);
if (lastAction == MotionEvent.ACTION_DOWN)
break;
default:
return false;
}
return true;
}
@Override
public boolean onLongClick(View v) {
return true;
}
}
Tried to set the child pos to top/bottom of viewgroup, adding smootscroll's value as offset and looked at scrollY and measuredheight, but i cant figure out how to get the correct values.