Java tutorial
/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package com.taobao.weex.ui.component.list.template; import android.support.v4.util.ArrayMap; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.support.v7.widget.StaggeredGridLayoutManager; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import com.taobao.weex.common.Constants; import com.taobao.weex.ui.view.refresh.wrapper.BounceRecyclerView; import java.util.ArrayList; import java.util.List; /** * StickyHelper For Template List * Created by furture on 2017/8/24. */ public class TemplateStickyHelper { private WXRecyclerTemplateList recyclerTemplateList; private List<Integer> stickyPositions; private ArrayMap<Integer, TemplateViewHolder> stickyHolderCache; private List<String> mStickyTypes; public TemplateStickyHelper(WXRecyclerTemplateList recyclerTemplateList) { this.recyclerTemplateList = recyclerTemplateList; this.stickyPositions = new ArrayList<>(); this.stickyHolderCache = new ArrayMap(); this.mStickyTypes = new ArrayList<>(8); } /** * dispatch scroll event, sticky header * */ public void onBeforeScroll(int dx, int dy) { if (stickyPositions == null || stickyPositions.size() == 0) { return; } BounceRecyclerView bounceRecyclerView = recyclerTemplateList.getHostView(); RecyclerView recyclerView = recyclerTemplateList.getHostView().getInnerView(); RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager(); int firstVisiblePosition = -1; int lastVisiblePosition = -1; if (layoutManager instanceof LinearLayoutManager) { firstVisiblePosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); lastVisiblePosition = ((LinearLayoutManager) layoutManager).findLastVisibleItemPosition(); } else if (layoutManager instanceof StaggeredGridLayoutManager) { int[] firstVisibleItemPositions = new int[3];//max 3 column firstVisiblePosition = ((StaggeredGridLayoutManager) layoutManager) .findFirstVisibleItemPositions(firstVisibleItemPositions)[0]; lastVisiblePosition = ((StaggeredGridLayoutManager) layoutManager) .findLastVisibleItemPositions(firstVisibleItemPositions)[0]; } if (firstVisiblePosition < 0) { return; } TemplateViewHolder firstVisibleItemHolder = (TemplateViewHolder) recyclerView .findViewHolderForAdapterPosition(firstVisiblePosition); if (firstVisibleItemHolder == null) { return; } //find match sticky position int matchStickyPosition = -1; for (Integer headerPosition : stickyPositions) { if (headerPosition == null) { continue; } if (headerPosition <= firstVisiblePosition) { matchStickyPosition = Math.max(matchStickyPosition, headerPosition); } else { break; } } if (matchStickyPosition < 0) { //remove holder for match position not found View stickyFakeView = bounceRecyclerView.getChildAt(bounceRecyclerView.getChildCount() - 1); if (stickyFakeView.getTag() instanceof TemplateViewHolder) { TemplateViewHolder stickyFakeViewHolder = (TemplateViewHolder) stickyFakeView.getTag(); bounceRecyclerView.removeView(stickyFakeViewHolder.itemView); stickyFakeViewHolder.itemView.setTranslationY(0); if (stickyFakeViewHolder.getComponent() != null && stickyFakeViewHolder.getComponent().getDomObject() != null && stickyFakeViewHolder .getComponent().getDomObject().getEvents().contains(Constants.Event.UNSTICKY)) { stickyFakeViewHolder.getComponent().fireEvent(Constants.Event.UNSTICKY); } } /**check has sticky cell not visible */ for (int i = 0; i < recyclerView.getChildCount(); i++) { View itemView = recyclerView.getChildAt(i); TemplateViewHolder itemHolder = (TemplateViewHolder) recyclerView.getChildViewHolder(itemView); if (itemHolder == null) { continue; } int adapterPosition = itemHolder.getAdapterPosition(); if (!stickyPositions.contains(adapterPosition)) { continue; } if (itemView.getVisibility() != View.VISIBLE) { itemView.setVisibility(View.VISIBLE); } } return; } //onCreate holder for match position if not exist View stickyFakeView = bounceRecyclerView.getChildAt(bounceRecyclerView.getChildCount() - 1); if (!(stickyFakeView.getTag() instanceof TemplateViewHolder) || ((TemplateViewHolder) stickyFakeView.getTag()).getHolderPosition() != matchStickyPosition) { //remove previous sticky header if (stickyFakeView.getTag() instanceof TemplateViewHolder && ((TemplateViewHolder) stickyFakeView.getTag()).getHolderPosition() != matchStickyPosition) { TemplateViewHolder stickyFakeViewHolder = (TemplateViewHolder) stickyFakeView.getTag(); bounceRecyclerView.removeView(stickyFakeViewHolder.itemView); stickyFakeViewHolder.itemView.setTranslationY(0); if (stickyFakeViewHolder.getComponent() != null && stickyFakeViewHolder.getComponent().getDomObject() != null && stickyFakeViewHolder .getComponent().getDomObject().getEvents().contains(Constants.Event.UNSTICKY)) { stickyFakeViewHolder.getComponent().fireEvent(Constants.Event.UNSTICKY); } } //onCreate new sticky int stickyHolderType = recyclerTemplateList.getItemViewType(matchStickyPosition); TemplateViewHolder fakeStickyHolder = stickyHolderCache.get(stickyHolderType); if (fakeStickyHolder == null) { fakeStickyHolder = recyclerTemplateList.onCreateViewHolder(recyclerView, stickyHolderType); stickyHolderCache.put(stickyHolderType, fakeStickyHolder); } recyclerTemplateList.onBindViewHolder(fakeStickyHolder, matchStickyPosition); fakeStickyHolder.itemView.setTranslationY(0); fakeStickyHolder.itemView.setTag(fakeStickyHolder); FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); fakeStickyHolder.getComponent().clearPreLayout(); if (fakeStickyHolder.itemView.getParent() != null) { ViewGroup parent = (ViewGroup) fakeStickyHolder.itemView.getParent(); parent.removeView(fakeStickyHolder.itemView); } bounceRecyclerView.addView(fakeStickyHolder.itemView, params); fakeStickyHolder.getComponent().setLayout(fakeStickyHolder.getComponent().getDomObject()); stickyFakeView = fakeStickyHolder.itemView; if (fakeStickyHolder.getComponent() != null && fakeStickyHolder.getComponent().getDomObject() != null && fakeStickyHolder.getComponent().getDomObject().getEvents() .contains(Constants.Event.STICKY)) { fakeStickyHolder.getComponent().fireEvent(Constants.Event.STICKY); } } TemplateViewHolder stickyFakeViewHolder = (TemplateViewHolder) stickyFakeView.getTag(); for (int i = 0; i < recyclerView.getChildCount(); i++) { View itemView = recyclerView.getChildAt(i); TemplateViewHolder itemHolder = (TemplateViewHolder) recyclerView.getChildViewHolder(itemView); if (itemHolder == null) { continue; } int adapterPosition = itemHolder.getAdapterPosition(); if (!stickyPositions.contains(adapterPosition)) { continue; } if (adapterPosition == stickyFakeViewHolder.getHolderPosition()) { if (itemView.getVisibility() != View.INVISIBLE) { itemView.setVisibility(View.INVISIBLE); } } else { if (itemView.getVisibility() != View.VISIBLE) { itemView.setVisibility(View.VISIBLE); } } } if (firstVisibleItemHolder.getComponent().isSticky()) { if (firstVisibleItemHolder.itemView.getY() < 0) { if (firstVisibleItemHolder.itemView.getVisibility() != View.INVISIBLE) { firstVisibleItemHolder.itemView.setVisibility(View.INVISIBLE); } if (stickyFakeView.getVisibility() != View.VISIBLE) { stickyFakeView.setVisibility(View.VISIBLE); } stickyFakeView.bringToFront(); } else { if (firstVisibleItemHolder.itemView.getVisibility() != View.VISIBLE) { firstVisibleItemHolder.itemView.setVisibility(View.VISIBLE); } if (stickyFakeView.getVisibility() != View.GONE) { stickyFakeView.setVisibility(View.GONE); } } } else { if (stickyFakeView.getVisibility() != View.VISIBLE) { stickyFakeView.setVisibility(View.VISIBLE); } } //handle sticky is related, find next sticky position on screen int nextVisiblePostion = firstVisiblePosition + 1; if (lastVisiblePosition > 0) { for (int i = nextVisiblePostion; i <= lastVisiblePosition; i++) { if (stickyPositions.contains(i)) { nextVisiblePostion = i; break; } } } if (!stickyPositions.contains(nextVisiblePostion)) { if (stickyFakeViewHolder.itemView.getTranslationY() < 0) { stickyFakeViewHolder.itemView.setTranslationY(0); } return; } TemplateViewHolder nextStickyHolder = (TemplateViewHolder) recyclerView .findViewHolderForAdapterPosition(nextVisiblePostion); if (nextStickyHolder == null || nextStickyHolder.getComponent() == null) { return; } int translationY = (int) (nextStickyHolder.itemView.getY() - stickyFakeViewHolder.itemView.getMeasuredHeight()); if (translationY <= 0) { stickyFakeViewHolder.itemView.setTranslationY(translationY); } else { stickyFakeViewHolder.itemView.setTranslationY(0); } } public List<Integer> getStickyPositions() { if (stickyPositions == null) { stickyPositions = new ArrayList<>(); } return stickyPositions; } public List<String> getStickyTypes() { return mStickyTypes; } }