我遇到了以下问题,
在RecyclerView中使用AndroidPlot XYPlot时。
像这样的AndroidPlot:<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"
androidplot.renderMode="use_background_thread"
android:visibility="visible"
ap:lineLabels="left"
android:minHeight="100dp" />
最重要的是renderMode =“use_background_thread” 设置Plot应该在后台线程中绘制。
我必须将ViewHolder设置为不是RecycleAble
ViewHolder vh = new ViewHolder(v,parentContext);
vh.setIsRecyclable(true);
因为当仅绑定RecyclerView时,Plot变为灰色。 原因是存在问题,回想起用于绘制元素的背景线程。 通过将Viewholders设置为不可循环使用,每次新项目进入Focus时,都会创建一个新的ViewHolder。不是很有效,我比使用不带Backgroud_Thread的Plots更快。 Link to my previous post
然后没有背景线程滚动真的停滞不前并且不是很漂亮。
Stack-Trace:
java.lang.IllegalThreadStateException: Thread already started
at java.lang.Thread.checkNotStarted(Thread.java:849)
at java.lang.Thread.start(Thread.java:1059)
at com.androidplot.Plot.onSizeChanged(Plot.java:780)
at android.view.View.sizeChange(View.java:16748)
at android.view.View.setFrame(View.java:16710)
at android.view.View.layout(View.java:16627)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1732)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1497)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.v7.widget.RecyclerView$LayoutManager.layoutDecoratedWithMargins(RecyclerView.java:8968)
at android.support.v7.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1614)
at android.support.v7.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1516)
at android.support.v7.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:608)
at android.support.v7.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:3693)
at android.support.v7.widget.RecyclerView.dispatchLayout(RecyclerView.java:3410)
at android.support.v7.widget.RecyclerView.onLayout(RecyclerView.java:3962)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutHorizontal(LinearLayout.java:1732)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1497)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.support.v7.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:443)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1743)
at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1586)
at android.widget.LinearLayout.onLayout(LinearLayout.java:1495)
at android.view.View.layout(View.java:16630)
at android.view.ViewGroup.layout(ViewGroup.java:5437)
at android.widget.FrameLayout.layoutChildren(FrameLayout.java:336)
at android.widget.FrameLayout.onLayout(FrameLayout.java:273)
at com.android.internal.policy.PhoneWi
感谢您的帮助,
弗兰西
答案 0 :(得分:1)
Androidplot演示应用程序具有listview example,演示如何完成此任务。 (在这个级别上RecyclerView
并没有什么特别的或不同的。)我修改了代码以使用RecyclerView
代替并获得了非常平滑的结果,即使在模拟器上也没有背景线程(请记住这是低帧率gif):
可能需要了解更多关于系列数据的大小。根据数据的密集程度,有时需要采样。
FWIW,这是修改后的listview演示活动的来源:
import android.app.Activity;
import android.graphics.Color;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.androidplot.Plot;
import com.androidplot.ui.SeriesBundle;
import com.androidplot.util.PixelUtils;
import com.androidplot.xy.CatmullRomInterpolator;
import com.androidplot.xy.LineAndPointFormatter;
import com.androidplot.xy.SimpleXYSeries;
import com.androidplot.xy.XYSeries;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class RecyclerViewActivity extends Activity {
private static final int NUM_PLOTS = 10;
private static final int NUM_POINTS_PER_SERIES = 10;
private static final int NUM_SERIES_PER_PLOT = 5;
private RecyclerView recyclerView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.recyclerview_example);
PixelUtils.init(this);
generateData();
recyclerView = findViewById(R.id.recycler_view);
recyclerView.setLayoutManager(new LinearLayoutManager(this));
recyclerView.setHasFixedSize(true);
recyclerView.setAdapter(new MyRecyclerViewAdapter(generateData()));
}
static class PlotViewHolder extends RecyclerView.ViewHolder {
private Plot plot;
public PlotViewHolder(View itemView) {
super(itemView);
this.plot = itemView.findViewById(R.id.xyplot);
}
public void bind(List<SeriesBundle<XYSeries, LineAndPointFormatter>> seriesBundles, String title) {
plot.clear();
plot.getTitle().setText(title);
for(SeriesBundle<XYSeries, LineAndPointFormatter> bundle : seriesBundles) {
plot.addSeries(bundle.getSeries(), bundle.getFormatter());
}
plot.redraw();
}
}
static class MyRecyclerViewAdapter extends RecyclerView.Adapter<PlotViewHolder> {
private List<List<SeriesBundle<XYSeries, LineAndPointFormatter>>> seriesData;
public MyRecyclerViewAdapter(List<List<SeriesBundle<XYSeries, LineAndPointFormatter>>> seriesData) {
this.seriesData = seriesData;
}
@NonNull
@Override
public PlotViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View item = LayoutInflater.from(parent.getContext())
.inflate(R.layout.listview_example_item, parent, false);
return new PlotViewHolder(item);
}
@Override
public void onBindViewHolder(@NonNull PlotViewHolder holder, int position) {
holder.bind(seriesData.get(position), "S" + position);
}
@Override
public int getItemCount() {
return seriesData.size();
}
}
static List<List<SeriesBundle<XYSeries, LineAndPointFormatter>>> generateData() {
final List<List<SeriesBundle<XYSeries, LineAndPointFormatter>>> seriesData = new ArrayList<>(NUM_PLOTS);
final Random generator = new Random();
for(int i = 0; i < NUM_PLOTS; i++) {
List<SeriesBundle<XYSeries, LineAndPointFormatter>> seriesList
= new ArrayList<>(NUM_SERIES_PER_PLOT);
for (int k = 0; k < NUM_SERIES_PER_PLOT; k++) {
ArrayList<Number> nums = new ArrayList<>();
for (int j = 0; j < NUM_POINTS_PER_SERIES; j++) {
nums.add(generator.nextFloat());
}
double rl = Math.random();
double gl = Math.random();
double bl = Math.random();
double rp = Math.random();
double gp = Math.random();
double bp = Math.random();
LineAndPointFormatter format = new LineAndPointFormatter(
Color.rgb(Double.valueOf(rl * 255).intValue(),
Double.valueOf(gl * 255).intValue(), Double.valueOf(bl * 255).intValue()),
Color.rgb(Double.valueOf(rp * 255).intValue(),
Double.valueOf(gp * 255).intValue(), Double.valueOf(bp * 255).intValue()),
null, null);
// for fun, configure interpolation on the formatter:
format.setInterpolationParams(
new CatmullRomInterpolator.Params(20, CatmullRomInterpolator.Type.Centripetal));
seriesList.add(new SeriesBundle<XYSeries, LineAndPointFormatter>(
new SimpleXYSeries(nums, SimpleXYSeries.ArrayFormat.Y_VALS_ONLY, "S" + k),
format));
}
seriesData.add(seriesList);
}
return seriesData;
}
}