Проблема с рисованием линии холста в scrollView - PullRequest
1 голос
/ 15 марта 2020

Я пытаюсь нарисовать прокручиваемый график времени. Я реализую настраиваемое представление singleLine для рисования линии между окружностями ImageView представления переработчика:

public class SingleLine extends View {
    WeakReference<Context> ctx;
    Paint paint;
    PointF pointA, pointB;
    private int height_custom;

    public SingleLine(Context context) {
        super(context);
        ctx = new WeakReference<>(context);
        init();
    }

    public SingleLine(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        ctx = new WeakReference<>(context);
        init();
    }

    public void init() {
        paint = new Paint();
        pointA = new PointF();
        pointB = new PointF();
        paint.setStrokeWidth(10);
        paint.setColor(ctx.get().getResources().getColor(R.color.green));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawLine(pointA.x, pointA.y, pointB.x, pointB.y, paint);
        invalidate();
    }

    public PointF getPointA() {return pointA;}

    public void setPointA(PointF pointA) {this.pointA = pointA;}

    public PointF getPointB() {return pointB;}

    public void setPointB(PointF pointB) {this.pointB = pointB;}
}

А в методе onBindViewHolder () моего адаптера я использую интерфейс для измерения координат x / y первого и последнего видимого view of recyclerview:

@Override 
public void onBindViewHolder(@NonNull final TaskViewHolder holder, final int position) {
    Tasks tasks = datalist_tasks.get(position);
    String hour = "" + tasks.getHour() + ":" + tasks.getMinute();
    holder.tv_clock.setText(hour);
    holder.tv_title.setText(tasks.getTitle());
    holder.tv_comment.setText(tasks.getComment());

    holder.itemView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN)
                holder.itemView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            else
                holder.itemView.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            if (iOnMeasureCustomView != null)
                iOnMeasureCustomView.onMeasure(holder.iv_status, position);
        }
    });
}

И я реализую этот интерфейс в своей деятельности, как показано ниже:

LinearLayoutManager layoutManager1 = new LinearLayoutManager(_C.get(), RecyclerView.VERTICAL, false);
rv_tasks.setLayoutManager(layoutManager1);
tasksAdapter.setiOnMeasureCustomView(new IOnMeasureCustomView() {
    @Override
    public void onMeasure(ImageView iv_status, int position) {
        int[] screen = new int[2];
        iv_status.getLocationOnScreen(screen);
        int width = (int) ((iv_status.getWidth() / 2) + convertDpToPixel(8));
        if (position == layoutManager1.findFirstCompletelyVisibleItemPosition()) {
            pointA.set(iv_status.getX() + width, iv_status.getY() + convertDpToPixel(8));
        } 
        else if (position == layoutManager1.findLastCompletelyVisibleItemPosition()) {
            pointB.set(iv_status.getX() + width, screen[1] - convertDpToPixel(40));
            singleLine.setPointA(pointA);
            singleLine.setPointB(pointB);        
            singleLine.invalidate();
        }
    }
});

А также я реализую addOnScrollListener () для моего recyclerview и пишу этот фрагмент кода (I не знаю, что если эта реализация верна или нет):

rv_tasks.addOnScrollListener(new RecyclerView.OnScrollListener() {
    @Override
    public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
         PointF a = singleLine.getPointA();
         PointF b = singleLine.getPointB();
         if (dy > 0) {
            a.y -= dy;
            b.y -= dy;
            singleLine.setPointA(a);
            singleLine.setPointB(b);
            singleLine.invalidate();
        } else {
            a.y += Math.abs(dy);
            b.y += Math.abs(dy);
            singleLine.setPointA(a);
            singleLine.setPointB(b);
            singleLine.invalidate();
        }
    }
});

Моя проблема в том, что когда я прокручиваю активность, как показано на рисунке ниже, моя единственная строка выглядит как обрезка imageView и конец x / y строки становятся x / y конца экрана.

enter image description here

enter image description here

Квест ios

  1. Как я могу установить x / y линии, чтобы предотвратить это?
  2. А также мне нужна помощь в рисовании этой линии с анимация. Как я могу нарисовать эту линию с анимацией, которая начинается, когда начинается действие?
...