Переработка Просмотр Android-график становится серым после прокрутки

Я получил следующую проблему.

При включении Android-XYPlot в Recycle-View графики не отображаются после прокрутки элементов на экране. Мне кажется, если Androidplot нужно перекачать, но это не очень эффективно.

Ссылки, которые я уже нашел:

XYPlot (библиотека AndroidPlot) в ScrollView не отображается

Есть ли лучшее решение:

Вот мой код:

Деятельность:

package at.fs.recycleviewerdemo;

import android.graphics.Color;
import android.graphics.Paint;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;

import com.androidplot.ui.SizeMode;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.StepMode;
import com.androidplot.xy.XYGraphWidget;

import java.text.DecimalFormat;

public class MainActivity extends AppCompatActivity {

    private RecyclerView mRecyclerView;
    private RecyclerView.Adapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;
    private String[] myDataset;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mRecyclerView = (RecyclerView) findViewById(R.id.RecyListItems);

        // use this setting to improve performance if you know that changes
        // in content do not change the layout size of the RecyclerView
        mRecyclerView.setHasFixedSize(true);

        // use a linear layout manager
        mLayoutManager = new LinearLayoutManager(this);
        mRecyclerView.setLayoutManager(mLayoutManager);

        // specify an adapter (see also next example)
        myDataset  = new String[100];
        fillDataSet(myDataset);
        mAdapter = new MyAdapter(this,myDataset);
        mRecyclerView.setAdapter(mAdapter);
        myDataset[9]="A";
        myDataset[99]="64";

    }
    private void fillDataSet(String[] dataset){
        if(dataset==null) return;
        for(int l=0;l<dataset.length;l++){
            dataset[l]=""+(l+1);
        }
    }

}

MyAdapter:

package at.fs.recycleviewerdemo;

import android.content.Context;
import android.graphics.Color;
import android.graphics.Paint;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import com.androidplot.ui.SizeMetric;
import com.androidplot.ui.SizeMode;
import com.androidplot.xy.BoundaryMode;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.StepMode;
import com.androidplot.xy.XYGraphWidget;
import com.androidplot.xy.XYPlot;

import org.w3c.dom.Text;

import java.text.DecimalFormat;
import java.util.Date;

/**
 * Author User
 * Date:25.01.2018
 * Class: ${CLASS}
 * Description:
 */

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.ViewHolder> {
    private String[] mDataset;
    private Date[] mDateSet;
    private double[] sample;
    Context parentContext;

    // Provide a reference to the views for each data item
    // Complex data items may need more than one view per item, and
    // you provide access to all the views for a data item in a view holder
    public static class ViewHolder extends RecyclerView.ViewHolder {
        // each data item is just a string in this case
        public View mView;
        public TextView txtDateTime;
        public TextView txtResult;
        public TextView txtEntryInfo;

        private XYPlot mPlot;
        private SimpleXYSeries sPulsSeries;

        public ViewHolder(View v) {
            super(v);
            mView = v;
            txtDateTime = (TextView) mView.findViewById(R.id.txtDateTime);
            txtResult = (TextView) mView.findViewById(R.id.txtResult);
            txtEntryInfo = (TextView) mView.findViewById(R.id.txtEntryInfo);
            mPlot = (XYPlot) mView.findViewById(R.id.mPlot);
            //addSampleData();
            //mPlot.redraw();
            Log.d(this.getClass().getSimpleName(),"ViewHolder(View v)");
        }
        private void InitDiagramm(){
            SetHRPlot_Boundaries();
            SetHRPlot_Grid();
            setHRPlot_Texts();

            //Set Line Format
            mPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new DecimalFormat("##"));
            mPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).setFormat(new DecimalFormat("##"));

        }
        private void SetHRPlot_Boundaries(){
            //Set Y Boundaries
            mPlot.setRangeBoundaries(40,120, BoundaryMode.FIXED);
            mPlot.setRangeStepMode(StepMode.INCREMENT_BY_VAL);
            mPlot.setRangeStepValue(20.0);
            //Set X Boundaries
            mPlot.setDomainStepMode(StepMode.INCREMENT_BY_VAL);
            mPlot.setDomainStepValue(10);
            mPlot.setDomainBoundaries(0,60000,BoundaryMode.FIXED);

        }
        private void SetHRPlot_Grid(){
            //Set horizontal Grid
            //Set Grid Lines
            mPlot.getGraph().getDomainGridLinePaint().setColor(Color.rgb(255,255,255));
            //Set Archor Line
            mPlot.getGraph().getDomainOriginLinePaint().setColor(Color.rgb(0,110,104));
            mPlot.getGraph().getDomainOriginLinePaint().setStrokeWidth(10);
            //Set vertical Grid
            //Set Grid Lines
            mPlot.getGraph().getRangeGridLinePaint().setColor(Color.rgb(192,192,192));
            //Set Grid Borders
            mPlot.getGraph().getRangeOriginLinePaint().setColor(Color.rgb(0,110,104));
            mPlot.getGraph().getRangeOriginLinePaint().setStrokeWidth(5);
            mPlot.getLegend().setVisible(false);


            mPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.BOTTOM).setFormat(new DecimalFormat("##"));
            mPlot.getGraph().getLineLabelStyle(XYGraphWidget.Edge.LEFT).setFormat(new DecimalFormat("##"));

        }
        private void setHRPlot_Texts(){
            mPlot.getDomainTitle().setWidth(mPlot.getWidth(), SizeMode.FILL);
            mPlot.getDomainTitle().getLabelPaint().setTextAlign(Paint.Align.CENTER);
            mPlot.getDomainTitle().getLabelPaint().setColor(Color.BLACK);
            mPlot.getRangeTitle().getLabelPaint().setColor(Color.BLACK);
            mPlot.getDomainTitle().setVisible(false);
            mPlot.getTitle().setVisible(false);
            mPlot.getRangeTitle().setVisible(false);
            mPlot.getRangeTitle().setHeight(0);
            mPlot.getDomainTitle().setHeight(0);
        }
        private void addSampleData(){
            LineAndPointFormatter formatter1 = new LineAndPointFormatter(
                    Color.rgb(153, 102, 204), null, null, null);
            formatter1.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
            formatter1.getLinePaint().setStrokeWidth(5);
            sPulsSeries = new SimpleXYSeries("Puls");
            mPlot.addSeries(formatter1,sPulsSeries);
            for(int l=0;l<1200;l+=1) {
                sPulsSeries.addFirst(l * 50, 70 + 30 * Math.sin(l*Math.PI/180));
            }
            mPlot.redraw();
        }
    }

    // Provide a suitable constructor (depends on the kind of dataset)
    public MyAdapter(Context context,String[] myDataset) {
        mDataset = myDataset;
        parentContext=context;
        //mDateSet = mDates;
    }

    // Create new views (invoked by the layout manager)
    @Override
    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) {

        // create a new view
        View v = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.my_text_view, parent, false);
        // set the view's size, margins, paddings and layout parameters
        //...
        ViewHolder vh = new ViewHolder(v);
        return vh;
    }

    // Replace the contents of a view (invoked by the layout manager)
    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        // - get element from your dataset at this position
        // - replace the contents of the view with that element
        holder.InitDiagramm();
        holder.txtEntryInfo.setText(mDataset[position]);
        //holder.InitDiagramm();
        holder.mPlot.clear();
        Log.d(this.getClass().getSimpleName(),"onBindViewHolder():"+mDataset[position]);
        holder.addSampleData();
        holder.mPlot.redraw();
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return mDataset.length;
    }

}

План мероприятий:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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="match_parent"
    android:orientation="vertical"
    tools:context="at.fs.recycleviewerdemo.MainActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_weight="0.01">
        <TextView
        android:id="@+id/textView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:text="TextView"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        tools:layout_editor_absoluteY="0dp" />
    </LinearLayout>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/RecyListItems"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fillViewport="true"/>
    </LinearLayout>
</LinearLayout>

Адаптер CardView:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_height="wrap_content"
    android:layout_width="match_parent"
    xmlns:ap="http://schemas.android.com/apk/res-auto"
    android:orientation="vertical"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:background="@drawable/my_custom_background">
    <!-- A CardView that contains a TextView -->
    <android.support.v7.widget.CardView
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    card_view:cardCornerRadius="4dp">
        <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
            <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">
                <TextView
                android:id="@+id/txtDateTime"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                android:text="20.Aug.2018"/>
                <TextView
                android:id="@+id/txtResult"
                android:layout_width="0dp"
                android:layout_weight="1"
                android:layout_height="match_parent"
                android:text="98 %"/>
            </LinearLayout>
            <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="200dp">

                <com.androidplot.xy.XYPlot
                android:id="@+id/mPlot"
                style="@style/APDefacto.Light"
                androidplot.renderMode="use_background_thread"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:visibility="visible"
                ap:lineLabels="left"
                android:minHeight="100dp"/>
            </LinearLayout>
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content">
            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:id="@+id/txtEntryInfo"
                android:text="Time (TYPE) Quality "
                android:textAlignment="textEnd"/>
        </LinearLayout>
    </LinearLayout>
    </android.support.v7.widget.CardView>
    </LinearLayout>

Некоторые картинки для описания ситуации:

Спасибо за помощь

2 ответа

Решение

Проблема заключалась в том, что я использовал фоновый поток, после удаления проблема была решена

До:

<com.androidplot.xy.XYPlot
                android:id="@+id/mPlot"
                style="@style/APDefacto.Light"
                androidplot.renderMode="use_background_thread"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:visibility="visible"
                ap:lineLabels="left"
                android:minHeight="100dp"/>

После:

<com.androidplot.xy.XYPlot
                android:id="@+id/mPlot"
                style="@style/APDefacto.Light"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_weight="1"
                android:visibility="visible"
                ap:lineLabels="left"
                android:minHeight="100dp"/>

Похоже, вы делаете некоторые вещи в конструкторе вашего ViewHolder что вы, вероятно, не должны. Особенно:

InitDiagramm();
addSampleData();
mPlot.redraw();

RecyclerView только содержит несколько View экземпляры, которые динамически привязываются к данным вашей модели при прокрутке пользователя, что означает, что вам нужно задавать данные модели и т. д. каждый раз, когда привязывается представление. Это означает, что addSampleData а также plot.Redraw должно быть сделано в onBindView,

У вас есть логика, которая на самом деле добавляет данные серии, смешанные между InitDiagramm а также addSampleData, Я бы посоветовал немного изменить рефакторинг, чтобы ваша настройка стиля графика была отделена от кода, который фактически устанавливает данные на графике. По крайней мере, addSeries вызывать InitDiagram должно происходить каждый раз, после вашего вызова plot.clear но до вашего вызова plot.redraw,

Другие вопросы по тегам