| /* |
| * 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; |
| |
| import android.view.View; |
| import android.view.ViewGroup; |
| |
| import com.taobao.weex.WXEnvironment; |
| import com.taobao.weex.common.WXThread; |
| import com.taobao.weex.utils.WXLogUtils; |
| |
| import java.util.ArrayList; |
| import java.util.HashMap; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| |
| /** |
| * Created by sospartan on 17/03/2017. |
| */ |
| |
| public class StickyHeaderHelper { |
| private final ViewGroup mParent; |
| private Map<String,View> mHeaderViews = new HashMap<>(); // map for <ref,view> |
| private Map<String,WXCell> mHeaderComps = new HashMap<>(); // map for <ref,comp> |
| private String mCurrentStickyRef = null; |
| |
| public StickyHeaderHelper(ViewGroup parent){ |
| this.mParent = parent; |
| } |
| |
| /** |
| * @param component |
| */ |
| public void notifyStickyShow(WXCell component) { |
| if (component == null) |
| return; |
| mHeaderComps.put(component.getRef(),component); |
| if(mCurrentStickyRef != null){ |
| WXCell cell = mHeaderComps.get(mCurrentStickyRef); |
| if(cell ==null || component.getScrollPositon() > cell.getScrollPositon()){ |
| mCurrentStickyRef = component.getRef(); |
| } |
| }else{ |
| mCurrentStickyRef = component.getRef(); |
| } |
| |
| { |
| if(mCurrentStickyRef==null){ |
| WXLogUtils.e("Current Sticky ref is null."); |
| return; |
| } |
| |
| WXCell headComponent = mHeaderComps.get(mCurrentStickyRef); |
| final View headerView = headComponent.getRealView(); |
| if (headerView == null) { |
| WXLogUtils.e("Sticky header's real view is null."); |
| return; |
| } |
| View header = mHeaderViews.get(headComponent.getRef()); |
| if( header != null){ |
| //already there |
| header.bringToFront(); |
| }else { |
| mHeaderViews.put(headComponent.getRef(), headerView); |
| //record translation, it should not change after transformation |
| final float translationX = headerView.getTranslationX(); |
| final float translationY = headerView.getTranslationY(); |
| headComponent.removeSticky(); |
| |
| ViewGroup existedParent; |
| if ((existedParent = (ViewGroup) headerView.getParent()) != null) { |
| existedParent.removeView(headerView); |
| } |
| headerView.setTag(headComponent.getRef()); |
| mParent.addView(headerView); |
| headerView.setTag(this); |
| if(headComponent.getStickyOffset() > 0) { |
| ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) headerView.getLayoutParams(); |
| if(headComponent.getStickyOffset() != params.topMargin) { |
| params.topMargin = headComponent.getStickyOffset(); |
| } |
| } |
| //recover translation, sometimes it will be changed on fling |
| headerView.setTranslationX(translationX); |
| headerView.setTranslationY(translationY); |
| } |
| changeFrontStickyVisible(); |
| if (headComponent.getDomObject().getEvents().contains("sticky")) { |
| headComponent.fireEvent("sticky"); |
| } |
| } |
| } |
| |
| |
| public void notifyStickyRemove(WXCell compToRemove) { |
| if (compToRemove == null) |
| return; |
| final WXCell component = mHeaderComps.remove(compToRemove.getRef()); |
| final View headerView = mHeaderViews.remove(compToRemove.getRef()); |
| |
| |
| if(component == null || headerView == null){ |
| if(WXEnvironment.isApkDebugable()) { |
| } |
| return; |
| } |
| if(mCurrentStickyRef != null && mCurrentStickyRef.equals(compToRemove.getRef())){ |
| mCurrentStickyRef = null; |
| } |
| mParent.post(WXThread.secure(new Runnable() { |
| @Override |
| public void run() { |
| mParent.removeView(headerView); |
| if(headerView.getVisibility() != View.VISIBLE){ |
| headerView.setVisibility(View.VISIBLE); |
| } |
| component.recoverySticky(); |
| changeFrontStickyVisible(); |
| |
| } |
| })); |
| if (component.getDomObject().getEvents().contains("unsticky")) { |
| component.fireEvent("unsticky"); |
| } |
| } |
| |
| |
| public void updateStickyView(int currentStickyPos) { |
| Iterator<Map.Entry<String, WXCell>> iterator = mHeaderComps.entrySet().iterator(); |
| List<WXCell> toRemove = new ArrayList<>(); |
| while(iterator.hasNext()){ |
| Map.Entry<String, WXCell> next = iterator.next(); |
| WXCell cell = next.getValue(); |
| int pos = cell.getScrollPositon(); |
| if(pos > currentStickyPos){ |
| toRemove.add(cell); |
| }else if(pos == currentStickyPos){ |
| mCurrentStickyRef = cell.getRef(); |
| View view = mHeaderViews.get(cell.getRef()); |
| if(view != null){ |
| view.bringToFront(); |
| changeFrontStickyVisible(); |
| } |
| } |
| } |
| for(WXCell cell:toRemove){ |
| notifyStickyRemove(cell); |
| } |
| } |
| |
| |
| private void changeFrontStickyVisible(){ |
| if(mHeaderViews.size() <= 0){ |
| return; |
| } |
| boolean fontVisible = false; |
| for(int i=mParent.getChildCount()-1; i>=0; i--){ |
| View view = mParent.getChildAt(i); |
| if(fontVisible && view.getTag() instanceof StickyHeaderHelper){ |
| if(view.getVisibility() != View.GONE){ |
| view.setVisibility(View.GONE); |
| } |
| }else{ |
| if(view.getTag() instanceof StickyHeaderHelper){ |
| fontVisible = true; |
| if(view != null && view.getVisibility() != View.VISIBLE){ |
| view.setVisibility(View.VISIBLE); |
| } |
| } |
| } |
| } |
| } |
| } |