Переработка Просмотр 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
,