Пользовательский вид с рисованием холста в Recyclerview не работает - PullRequest
0 голосов
/ 21 апреля 2020

Я пытаюсь нарисовать ар c из одного вида в другой (рисование на холсте) в представлении реселлера. Поэтому я добавил пользовательский вид в макет повторного просмотра. Но это не получается правильно. Это Dr aws случайно для некоторых предметов в переработке. Вот мой код:

ArcView

public class ArcView extends View {

    final RectF oval = new RectF();
    Path myPath = new Path();
    Paint paint;
    float left, top, right, bottom;

    /**/
    private float mCanvasCenterX;

    private float mCenterCircleWidth, mCenterCircleHeight;

    /**/
    public ArcView(Context context) {
        super(context);
    }
    public ArcView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(attrs);
    }
    public ArcView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(attrs);
    }

    private void init(AttributeSet set) {
        if (set == null)
            return;
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
        /*TypedArray typedArray = getContext().obtainStyledAttributes(set, R.styleable.FlightStatusArcView);
        typedArray.recycle();*/
    }

    public void setArcProperties(float l, float t, float r, float b) {
        left = l;
        top = t;
        right = r;
        bottom = b;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        oval.set(left, top, right, bottom);
        paint.setColor(Color.WHITE);
        paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeWidth(5f);

        canvas.drawArc(oval, 180f, 180f, false, paint);
        drawArc(canvas);




    }



    private void drawArc(Canvas canvas) {

        canvas.save();

        Paint p = new Paint();
        p.setColor(Color.WHITE);
        p.setStyle(Paint.Style.FILL);
        p.setStrokeWidth(4f);

        float startX = oval.left + 20;
        float startY = oval.top + (oval.centerY() - oval.top)/ 2;

        Path path = new Path();
        path.moveTo(startX, startY);
        path.lineTo(startX + 20, startY + 20);
        path.lineTo(startX + 20, startY);
        path.lineTo(startX + 20, startY);
        path.close();

        canvas.drawPath(path, p);

        canvas.restore();
    }


}

activity_main , макет MainActivity, в котором хранится представление переработчика

<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">

    <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"/>


    <androidx.recyclerview.widget.RecyclerView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:id="@+id/recycler_view"
            android:paddingEnd="5dp"
            android:paddingStart="5dp"
            android:scrollbars="vertical">

    </androidx.recyclerview.widget.RecyclerView>

</androidx.constraintlayout.widget.ConstraintLayout>

MyAdapter , класс адаптера для переработчика. Здесь я пытаюсь нарисовать холст. Но он ничего не рисует.

class MyAdapter(var items: ArrayList<Item>) :
    RecyclerView.Adapter<MyAdapter.MyViewHolder>() {
    fun updateItems(newItems: List<Item>) {
        items.clear()
        items.addAll(newItems)
        notifyDataSetChanged()
    }
    override fun onCreateViewHolder(parent: ViewGroup, p1: Int) = MyViewHolder(
        LayoutInflater.from(parent.context).inflate(R.layout.activity_arc_view, parent, false)
    )
    override fun getItemCount() = items.size
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(items[position])
        val handler = Handler()
        handler.postDelayed(Runnable {
            setPropertiesAndDrawArc(holder)
        }, 1500)
    }
    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view) {
        val from = view.from_airport
        val to = view.to_airport
        val customView = view.customView
        val circleStart = view.circle_start
        val circleEnd = view.circle_end
        val inFlight = view.in_flight
        val flyingTime = view.flying_time
        fun bind(item: Item) {
            from.text = item.from
            to.text = item.to
        }
    }
    private fun setPropertiesAndDrawArc(holder: MyViewHolder) {
        val circleStartLocation = IntArray(2)
        holder.circleStart.getLocationOnScreen(circleStartLocation)
        val circleEndLocation = IntArray(2)
        holder.circleEnd.getLocationOnScreen(circleEndLocation)
        val inFlightLocation = IntArray(2)
        holder.inFlight.getLocationOnScreen(inFlightLocation)
        val fromAirportLocation = IntArray(2)
        holder.from.getLocationOnScreen(fromAirportLocation)
        val flyingTimeLocation = IntArray(2)
        holder.flyingTime.getLocationOnScreen(flyingTimeLocation)
        val toAirportLocation = IntArray(2)
        holder.to.getLocationOnScreen(toAirportLocation)
        holder.flyingTime.measure(0, 0)
        val flyingTimeHeight = holder.flyingTime.getMeasuredHeight()
        val flyingTimeTop = flyingTimeLocation[1] - flyingTimeHeight
        val left = circleStartLocation[0] + holder.circleStart.getWidth() / 2
        val top = inFlightLocation[1] + (flyingTimeTop - inFlightLocation[1]) / 2
        val right = circleEndLocation[0] + holder.circleEnd.getWidth() / 2
        val bottom = circleStartLocation[1] + (circleStartLocation[1] - inFlightLocation[1]) / 2
        holder.customView.setArcProperties(left.toFloat(), top.toFloat(), right.toFloat(), bottom.toFloat())
        holder.customView.invalidate()
    }
}

activity_arc_view , макет строки элемента вьюблера

<?xml version="1.0" encoding="utf-8"?>
<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"
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.example.customviewinrv.ArcView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/customView"
        android:elevation="2dp"
        android:layout_marginTop="0dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>


    <androidx.constraintlayout.widget.ConstraintLayout
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="170dp"
        android:background="@color/colorPrimaryDark"
        android:visibility="visible"
        android:layout_marginTop="20dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <View
            android:id="@+id/circle_start"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:background="@drawable/circle_white"
            app:layout_constraintBottom_toTopOf="@id/from_airport"
            app:layout_constraintEnd_toEndOf="@id/from_airport"
            app:layout_constraintStart_toStartOf="@id/from_airport" />

        <View
            android:id="@+id/circle_end"
            android:layout_width="12dp"
            android:layout_height="12dp"
            android:background="@drawable/circle_white"
            app:layout_constraintBottom_toTopOf="@id/to_airport"
            app:layout_constraintEnd_toEndOf="@id/to_airport"
            app:layout_constraintStart_toStartOf="@id/to_airport" />


        <TextView
            android:id="@+id/from_airport"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:gravity="center"
            android:text="Trivandrum\nInternational Airport"
            android:textColor="#FFFFFF"
            android:textSize="19sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent" />

        <TextView
            android:id="@+id/to_airport"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginBottom="10dp"
            android:gravity="center"
            android:text="Mineralnye Vody \nAirport"
            android:textColor="#FFFFFF"
            android:textSize="19sp"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintRight_toRightOf="parent" />

        <TextView
            android:id="@+id/in_flight"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="10dp"
            android:gravity="center"
            android:text="In-flight"
            android:textColor="#FFFFFF"
            android:textSize="19sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/flying_time"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="30dp"
            android:gravity="center"
            android:text="Flying Time\n03h 30m"
            android:textColor="#FFFFFF"
            android:textSize="11sp"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toBottomOf="@id/in_flight" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

Он работает хорошо, если он работает в обычном режиме без повторного просмотра. Интересно, как мне добиться этого в обзоре переработчиков? Пожалуйста, помогите.

Ответы [ 2 ]

0 голосов
/ 28 апреля 2020

Я понял, что вы пытаетесь сделать, но ваш код слишком сложен для понимания, но ваш подход неверен. Прежде всего вы должны использовать обратный вызов onSizeChanged () в вашем представлении, чтобы понять изменение в размере, чтобы вы могли правильно нарисовать ar c. Подумайте, как этот макет ограничения отрегулируйте размер вашего представления в соответствии с определением, которое вы определяете (от_порта и до аэропорта). Таким образом, ширина и высота вашего представления корректно корректируются, поэтому вы можете выполнить необходимые вычисления в этом обратном вызове, а затем выполнить операцию рисования в соответствии со значениями, которые вы только что рассчитали в onSizeChanged, так что вам даже не нужно вызывать invalidate, потому что система автоматически вызывает ваше представление перерисовать. Другой вариант - использовать пользовательскую группу представлений, но для вашей ситуации это не нужно.

0 голосов
/ 21 апреля 2020

Я не вижу супер-вызова функции onDraw, сделайте следующее:

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
....
....
...

update

вместо этого задайте для своего пользовательского вида высоту и ширину of wrap_content:

<com.example.customviewinrv.ArcView
    android:layout_width="....."
    android:layout_height="......"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...