问题
I got the following Problem.
When Including Android-XYPlot into Recycle-View, the Plots are not displayed after Scrolling Elements out of the Screen. It seems to me if Androidplot needs to be reinflated, but that's not really effective.
Links I have already found:
XYPlot (AndroidPlot library) in ScrollView does not appear
Is there any better Solution:
Here is my Code:
Activity:
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;
}
}
Activity Layout:
<?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 Adapter:
<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>
Some Pictures to describe the situation:
Thanks for Help
回答1:
It looks like you're doing some stuff in the constructor of your ViewHolder
that you probably shouldnt. In particular:
InitDiagramm();
addSampleData();
mPlot.redraw();
RecyclerView
only contains a few View
instances that are dynamically bound to your model data as the user scrolls, which means that you need to set the model data etc. every time the view is bound. This means that addSampleData
and plot.Redraw
should be done in onBindView
.
You have the logic that actually adds the series data mixed between InitDiagramm
and addSampleData
. I'd suggest refactoring that a bit so that your plot style setup is separate from the code that actually sets data on the plot. At the very least, the addSeries
call in InitDiagram
should happen every bind, after your invocation of plot.clear
but before your invocation of plot.redraw
.
回答2:
The Problem was that I used the background Thread, after removing the Problem was solved
Before:
<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"/>
After:
<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"/>
来源:https://stackoverflow.com/questions/48475145/recycling-view-android-plot-becomes-gray-after-scrolling