blob: a30a1ac388d878eb25c814efcb6af1dfa2ad258d [file] [log] [blame]
/*
* 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.content.Context;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.RestrictTo;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import com.taobao.weex.WXSDKInstance;
import com.taobao.weex.annotation.Component;
import com.taobao.weex.common.Constants;
import com.taobao.weex.dom.WXAttr;
import com.taobao.weex.ui.action.BasicComponentData;
import com.taobao.weex.ui.component.WXVContainer;
import com.taobao.weex.ui.flat.WidgetContainer;
import com.taobao.weex.ui.view.WXFrameLayout;
import com.taobao.weex.utils.WXLogUtils;
import com.taobao.weex.utils.WXUtils;
import com.taobao.weex.utils.WXViewUtils;
import java.util.LinkedList;
import static com.taobao.weex.common.Constants.Name.STICKY_OFFSET;
/**
* Root component for components in {@link WXListComponent}
*/
@Component(lazyload = false)
public class WXCell extends WidgetContainer<WXFrameLayout> {
private int mLastLocationY = 0;
private ViewGroup mRealView;
private View mTempStickyView;
private View mHeadView;
/** used in list sticky detect **/
private int mScrollPosition = -1;
private boolean mFlatUIEnabled = false;
private Object renderData;
private boolean isSourceUsed = false;
private boolean isAppendTreeDone;
private CellAppendTreeListener cellAppendTreeListener;
@Deprecated
public WXCell(WXSDKInstance instance, WXVContainer parent, String instanceId, boolean isLazy, BasicComponentData basicComponentData) {
super(instance, parent, basicComponentData);
}
public WXCell(WXSDKInstance instance, WXVContainer parent, boolean isLazy, BasicComponentData basicComponentData) {
super(instance, parent, basicComponentData);
lazy(true);
if(Build.VERSION.SDK_INT< Build.VERSION_CODES.LOLLIPOP) {
try {
//TODO a WTF is necessary if anyone try to change the flat flag during update attrs.
WXAttr attr = getAttrs();
if (attr.containsKey(Constants.Name.FLAT)) {
mFlatUIEnabled = WXUtils.getBoolean(attr.get(Constants.Name.FLAT), false);
}
} catch (NullPointerException e) {
WXLogUtils.e("Cell", WXLogUtils.getStackTrace(e));
}
}
}
@Override
public boolean isLazy() {
return super.isLazy() && !isFixed();
}
@Override
@RestrictTo(RestrictTo.Scope.LIBRARY)
public boolean isFlatUIEnabled() {
return mFlatUIEnabled;
}
/**
* If Cell is Sticky, need wraped FrameLayout
*/
@Override
protected WXFrameLayout initComponentHostView(@NonNull Context context) {
if (isSticky()) {
WXFrameLayout view = new WXFrameLayout(context);
mRealView = new WXFrameLayout(context);
view.addView(mRealView);
//TODO Maybe there is a better solution for hardware-acceleration view's display list.
if (isFlatUIEnabled()) {
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
return view;
} else {
WXFrameLayout view = new WXFrameLayout(context);
mRealView = view;
if (isFlatUIEnabled()) {
view.setLayerType(View.LAYER_TYPE_HARDWARE, null);
}
return view;
}
}
public int getLocationFromStart(){
return mLastLocationY;
}
public void setLocationFromStart(int l){
mLastLocationY = l;
}
void setScrollPositon(int pos){
mScrollPosition = pos;
}
public int getScrollPositon() {
return mScrollPosition;
}
@Override
public ViewGroup getRealView() {
return mRealView;
}
public void removeSticky() {
if(getHostView().getChildCount() > 0) {
mHeadView = getHostView().getChildAt(0);
int[] location = new int[2];
int[] parentLocation = new int[2];
getHostView().getLocationOnScreen(location);
getParentScroller().getView().getLocationOnScreen(parentLocation);
int headerViewOffsetX = location[0] - parentLocation[0];
int headerViewOffsetY = getParent().getHostView().getTop();
getHostView().removeView(mHeadView);
mRealView = (ViewGroup) mHeadView;
mTempStickyView = new FrameLayout(getContext());
FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams((int) getLayoutWidth(),
(int) getLayoutHeight());
getHostView().addView(mTempStickyView, lp);
mHeadView.setTranslationX(headerViewOffsetX);
mHeadView.setTranslationY(headerViewOffsetY);
}
}
public void recoverySticky() {
if(mHeadView != null){
if(mHeadView.getLayoutParams() != null){
ViewGroup.MarginLayoutParams params = (ViewGroup.MarginLayoutParams) mHeadView.getLayoutParams();
if(params.topMargin > 0){
params.topMargin = 0;
}
}
if(mHeadView.getVisibility() != View.VISIBLE){
mHeadView.setVisibility(View.VISIBLE);
}
if(mHeadView.getParent() != null){
((ViewGroup)mHeadView.getParent()).removeView(mHeadView);
}
getHostView().removeView(mTempStickyView);
getHostView().addView(mHeadView);
mHeadView.setTranslationX(0);
mHeadView.setTranslationY(0);
}
}
@Override
protected void mountFlatGUI() {
if(getHostView()!=null) {
if(widgets == null){
widgets = new LinkedList<>();
}
getHostView().mountFlatGUI(widgets);
}
}
@Override
public void unmountFlatGUI() {
if (getHostView() != null) {
getHostView().unmountFlatGUI();
}
}
@Override
public boolean intendToBeFlatContainer() {
return getInstance().getFlatUIContext().isFlatUIEnabled(this) && WXCell.class.equals(getClass()) && !isSticky();
}
public int getStickyOffset(){
if(getAttrs().get(STICKY_OFFSET) == null){
return 0;
}
float offset = WXUtils.getFloat(getAttrs().get(STICKY_OFFSET));
return (int)(WXViewUtils.getRealPxByWidth(offset, getViewPortWidth()));
}
public Object getRenderData() {
return renderData;
}
public void setRenderData(Object renderData) {
this.renderData = renderData;
}
public boolean isSourceUsed() {
return isSourceUsed;
}
public void setSourceUsed(boolean sourceUsed) {
isSourceUsed = sourceUsed;
}
public boolean isAppendTreeDone(){
return isAppendTreeDone;
}
@Override
public void appendTreeCreateFinish() {
super.appendTreeCreateFinish();
isAppendTreeDone = true;
if(cellAppendTreeListener != null){
cellAppendTreeListener.onAppendTreeDone();
}
}
public void setCellAppendTreeListener(CellAppendTreeListener cellAppendTreeListener) {
this.cellAppendTreeListener = cellAppendTreeListener;
if(isAppendTreeDone){
cellAppendTreeListener.onAppendTreeDone();
}
}
public interface CellAppendTreeListener{
public void onAppendTreeDone();
}
}