RecyclerChart动态属性图标联动数据动态加载怎么实现
本篇内容介绍了“RecyclerChart动态属性图标联动数据动态加载怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
图表联动
类似于股票的K线跟底部成交量Barchat图表,这里也是上下两个Chart图表,笔者在写到这里的时候,突然间有个大胆的想法,就是完全可以在一个Chart里去绘制上下两部分的数据展现,这样的话也不会存在两个图表联动的问题,同时可能会因为少了一个Chart,性能更好。
好了,这里先讲目前的实现方式。MPAndroidChart中的两个上下两个图表也可以实现连动的方式实现,通过OnChartGestureListener接口实现。因为RecyclerChart是基于Recyclerview 实现的,所以其实只需实现两个Recylcerview的联动即可。
如下在recyclerBarChart 的滑动监听中 同步处理recyclerLineChart的滑动,同样包括回溯的滑动。
recyclerBarChart.addOnScrollListener(new RecyclerView.OnScrollListener() { private boolean isRightScrollInner; @Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { .... //回溯 if (mBarChartAttrs.enableScrollToScale) { int scrollToByDx = ChartComputeUtil.computeScrollByXOffset(recyclerView, displayNumber, getXAxisType()); recyclerView.scrollBy(scrollToByDx, 0); recyclerLineChart.scrollBy(scrollToByDx, 0); } ..... } } @Override public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); //判断左滑,右滑时,ScrollView的位置不一样。 isRightScrollInner = dx < 0; if (recyclerBarChart.getScrollState() != RecyclerView.SCROLL_STATE_IDLE) { mItemGestureListener.resetSelectedBarEntry();//清除recyclerLineChart的长按。 recyclerLineChart.scrollBy(dx, dy); } } });
同样的,在线性表 recyclerLineChart 的滑动监听里需要同步处理recyclerBarChart的滑动,代码类似。
数据动态加载
其实类似于分页加载数据,跟纵向vertical加载类似,这里是横向horizontal处理的,同样在上面的监听的Listener里面处理 当条件 !
recyclerView.canScrollHorizontally(-1) 左滑不动,加载数据到左边,这里LayoutManager因为 reverse的,所以是 DataList.addAll(list);
当!recyclerView.canScrollHorizontally(1) 右滑不动是,DataList.addAll(0, list)
@Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { //加载更多 if (!recyclerView.canScrollHorizontally(-1) && isRightScrollInner) {//左滑不动 loadData(updateUI(start)) } else if (!recyclerView.canScrollHorizontally(1)) {//右滑不动 loadData(updateUI(end)) } } }
回溯
这里先介绍一下实现方案:笔者在构建Entry的时候埋了一个type的钩子,当Entry属于日周月视图的边界,比如日视图的0点,周视图的周一,月视图的1号,通常情况下是这个Item的左边界;但是当RTL时需要特殊处理。
第二,当停下来的时候,遍历当前屏幕显示的Items时,当不对齐的时候,这里必定存在一个上述提到的特殊边界的Item,计算它到Chart边界的(不包含XAis)的距离,存到一个DistanceCompare的对象中。
第三, 在RecyclerView松手Fling停止的时候,计算上面的DistanceCompare对象中的,distanceLeft、distanceRight; 根据 isNearLeft() 去判断是向左,还是向右回弹,isNearLeft() true 向左,否则向右。
//月线靠近左边 public boolean isNearLeft(){ return distanceLeft < distanceRight; } //计算 DistanceCompare private static <T extends RecyclerBarEntry> DistanceCompare findDisplayFirstTypePosition(RecyclerView recyclerView, int displayNumbers) { LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager(); DistanceCompare distanceCompare = new DistanceCompare(0, 0); BaseBarChartAdapter adapter = (BaseBarChartAdapter) recyclerView.getAdapter(); if (null == manager || null == adapter) { return distanceCompare; } List<T> entries = adapter.getEntries(); int firstVisibleItemPosition = manager.findFirstVisibleItemPosition(); int position = firstVisibleItemPosition; //从右边的第一个View开始找 int parentRight = recyclerView.getWidth() - recyclerView.getPaddingRight(); int parentLeft = recyclerView.getPaddingLeft(); for (int i = 0; i < displayNumbers; i++) { if (i > 0) { position++; } if (position >= 0 && position < entries.size()) { T barEntry = entries.get(position); if (barEntry.type == RecyclerBarEntry.TYPE_XAXIS_FIRST || barEntry.type == RecyclerBarEntry.TYPE_XAXIS_SPECIAL) { distanceCompare.position = position; View positionView = manager.findViewByPosition(position); if (null != positionView){ int viewLeft = positionView.getLeft(); int viewRight = positionView.getRight(); distanceCompare.distanceRight = parentRight - viewRight; distanceCompare.distanceLeft = viewLeft - parentLeft; } distanceCompare.setBarEntry(barEntry); break; } } } return distanceCompare; }
根据 distanceCompare 计算 scrollByXOffset:简单的数学计算,不过需要仔细。
public static <T extends RecyclerBarEntry> int computeScrollByXOffset(RecyclerView recyclerView, int displayNumbers, int type) { DistanceCompare distanceCompare = findDisplayFirstTypePosition(recyclerView, displayNumbers); LinearLayoutManager manager = (LinearLayoutManager) recyclerView.getLayoutManager(); BaseBarChartAdapter adapter = (BaseBarChartAdapter) recyclerView.getAdapter(); if (null == adapter) { return 0; } List<T> entries = adapter.getEntries(); int positionCompare = distanceCompare.position; //T entry = entries.get(positionCompare); View compareView = manager.findViewByPosition(positionCompare); if (null == compareView) { return 0; } int compareViewRight = compareView.getRight(); int compareViewLeft = compareView.getLeft(); int childWidth = compareView.getWidth(); int parentLeft = recyclerView.getPaddingLeft(); int parentRight = recyclerView.getWidth() - recyclerView.getPaddingRight(); int scrollByXOffset; if (distanceCompare.isNearLeft()) { //靠近左边,content左移,recyclerView右移,取正。 //情况 1. int distance = AppUtils.isRTLDirection() ? compareViewLeft - parentLeft : compareViewRight - parentLeft;//原始调整距离 if (positionCompare < displayNumbers + 1) { //防止 positionCompare过大,计算firstViewRight时,int越界 int firstViewRight = compareViewRight + positionCompare * childWidth; int distanceRightBoundary = Math.abs(firstViewRight - parentRight);//右边界 if (distanceRightBoundary < distance) { //content左移不够,顶到头,用distanceRightBoundary distance = distanceRightBoundary; } } scrollByXOffset = distance; } else {//靠近右边,content右移,recyclerView左移,取负。 int distance = AppUtils.isRTLDirection()?parentRight - compareViewLeft : parentRight - compareViewRight;//原始调整距离 if (entries.size() - positionCompare < displayNumbers) { //这个值会为负的。 int lastViewLeft = compareViewLeft - (entries.size() - 1 - positionCompare) * childWidth; int distanceLeftBoundary = Math.abs(parentLeft - lastViewLeft); //右边 - 左边,因为 lastViewLeft是负值,实际上是两值相加。 if (distanceLeftBoundary < distance) {//content右移不够,顶到头,distanceLeftBoundary distance = distanceLeftBoundary; } } //记得取负, scrollBy的话f scrollByXOffset = distance - 2 * distance; } return scrollByXOffset; }
最终也在onScrollStateChanged 实现回溯:
@Override public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { super.onScrollStateChanged(recyclerView, newState); if (newState == RecyclerView.SCROLL_STATE_IDLE) { ..... //回溯 if (mBarChartAttrs.enableScrollToScale) { int scrollToByDx = ChartComputeUtil.computeScrollByXOffset( recyclerView, displayNumber, getXAxisType()); recyclerView.scrollBy(scrollToByDx, 0); recyclerLineChart.scrollBy(scrollToByDx, 0); } ...... } }
“RecyclerChart动态属性图标联动数据动态加载怎么实现”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注蜗牛博客网站,小编将为大家输出更多高质量的实用文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:niceseo99@gmail.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
评论