您好,登錄后才能下訂單哦!
本篇內容介紹了“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動態屬性圖標聯動數據動態加載怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。