Skip to content

Commit

Permalink
Merge pull request #4055 from vishalduggal/timob-13052
Browse files Browse the repository at this point in the history
[TIMOB-13052] (2_1_X) Android: TableViewRow index confused in row click
  • Loading branch information
ayeung committed Apr 1, 2013
2 parents 109b311 + c8a36e6 commit 245b50d
Show file tree
Hide file tree
Showing 5 changed files with 207 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.titanium.TiC;
import org.appcelerator.titanium.TiContext;
import org.appcelerator.titanium.proxy.TiViewProxy;
import org.appcelerator.titanium.util.TiConvert;
import org.appcelerator.titanium.util.TiFileHelper;
import org.appcelerator.titanium.util.TiPlatformHelper;
Expand Down Expand Up @@ -193,4 +194,14 @@ public void setBackgroundFromProxy(KrollProxy proxy) {
public void release() {
handler = null;
}

protected static void clearChildViews(TiViewProxy parent)
{
for (TiViewProxy childProxy : parent.getChildren()) {
childProxy.setView(null);
clearChildViews(childProxy);
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ public View getView(int position, View convertView, ViewGroup parent) {
if (v.getRowData() != item) {
v = null;
}
} else if (v.getClassName().equals(TableViewProxy.CLASSNAME_HEADERVIEW)) {
//Always recreate the header view
v = null;
} else {
// otherwise compare class names
if (!v.getClassName().equals(item.className)) {
Expand Down Expand Up @@ -421,8 +424,17 @@ protected boolean rowClicked(TiBaseTableViewItem rowView, int position, boolean

private View layoutHeaderOrFooter(TiViewProxy viewProxy)
{
TiUIView tiView = viewProxy.getOrCreateView();
View nativeView = tiView.getNativeView();
//We are always going to create a new view here. So detach outer view here and recreate
View outerView = (viewProxy.peekView() == null) ? null : viewProxy.peekView().getOuterView();
if (outerView != null) {
ViewParent vParent = outerView.getParent();
if ( vParent instanceof ViewGroup ) {
((ViewGroup)vParent).removeView(outerView);
}
}
TiBaseTableViewItem.clearChildViews(viewProxy);
TiUIView tiView = viewProxy.forceCreateView();
outerView = tiView.getOuterView();
TiCompositeLayout.LayoutParams params = tiView.getLayoutParams();

int width = AbsListView.LayoutParams.WRAP_CONTENT;
Expand All @@ -442,8 +454,8 @@ private View layoutHeaderOrFooter(TiViewProxy viewProxy)
width = params.optionWidth.getAsPixels(listView);
}
AbsListView.LayoutParams p = new AbsListView.LayoutParams(width, height);
nativeView.setLayoutParams(p);
return nativeView;
outerView.setLayoutParams(p);
return outerView;
}

public void dataSetChanged() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.titanium.TiContext;
import org.appcelerator.titanium.util.TiUIHelper;
import org.appcelerator.titanium.view.TiBorderWrapperView;

import ti.modules.titanium.ui.widget.tableview.TableViewModel.Item;
import android.app.Activity;
Expand All @@ -17,6 +18,7 @@
import android.os.Handler;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.RelativeLayout;
import android.widget.TextView;

Expand Down Expand Up @@ -118,6 +120,9 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
rowView.layout(left, 0, right, bottom - top);
} else {
headerView.layout(left, 0, right, bottom - top);
if (headerView instanceof TiBorderWrapperView) {
((ViewGroup)headerView).getChildAt(0).layout(left, 0, right, bottom - top);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@
package ti.modules.titanium.ui.widget.tableview;

import java.util.ArrayList;
import java.util.HashMap;

import org.appcelerator.kroll.KrollDict;
import org.appcelerator.kroll.KrollPropertyChange;
import org.appcelerator.kroll.common.Log;
import org.appcelerator.kroll.common.TiConfig;
import org.appcelerator.titanium.TiC;
Expand Down Expand Up @@ -79,7 +78,9 @@ protected TableViewRowProxy getRowProxy() {
public void setRowData(Item item) {
this.item = item;
TableViewRowProxy rp = getRowProxy();
rp.setTableViewItem(this);
if (this != rp.getTableViewRowProxyItem()) {
rp.setTableViewItem(this);
}
setRowData(rp);
}

Expand All @@ -101,58 +102,160 @@ protected TiViewProxy addViewToOldRow(int index, TiUIView titleView, TiViewProxy
views.add(newViewProxy.getOrCreateView());
return label;
}

protected void refreshControls()
{
ArrayList<TiViewProxy> proxies = getRowProxy().getControls();
int len = proxies.size();

if (views == null) {
views = new ArrayList<TiUIView>(len);
} else if (views.size() != len) {
for (TiUIView view : views) {
View v = view.getNativeView();
if (v != null && v.getParent().equals(content)) {
content.removeView(v);

/*
* Check if the two proxies are compatible outerView wise
*/
private boolean checkBorderProps(TiViewProxy oldProxy, TiViewProxy newProxy){
KrollDict oldProperties = oldProxy.getProperties();
KrollDict newProperties = newProxy.getProperties();
boolean oldHasBorder = oldProperties.containsKeyAndNotNull(TiC.PROPERTY_BORDER_COLOR)
|| oldProperties.containsKeyAndNotNull(TiC.PROPERTY_BORDER_RADIUS)
|| oldProperties.containsKeyAndNotNull(TiC.PROPERTY_BORDER_WIDTH);
boolean newHasBorder = newProperties.containsKeyAndNotNull(TiC.PROPERTY_BORDER_COLOR)
|| newProperties.containsKeyAndNotNull(TiC.PROPERTY_BORDER_RADIUS)
|| newProperties.containsKeyAndNotNull(TiC.PROPERTY_BORDER_WIDTH);

return (oldHasBorder == newHasBorder);
}

/*
* Check the view heirarchy
*/
private boolean checkViewHeirarchy(TiViewProxy oldProxy, TiViewProxy newProxy){
if (oldProxy == newProxy){
return true;
}
if(oldProxy.getClass() != newProxy.getClass()) {
//Check for type
return false;
} else if (!checkBorderProps(oldProxy, newProxy)) {
//Ensure they have compatible border props
return false;
} else {
//Check children recursively
TiViewProxy[] oldChildren = oldProxy.getChildren();
TiViewProxy[] newChildren = newProxy.getChildren();
if (oldChildren.length != newChildren.length) {
return false;
} else {
int len = oldChildren.length;
for (int i=0;i<len;i++) {
if (!checkViewHeirarchy(oldChildren[i],newChildren[i])) {
return false;
}
}
}
views = new ArrayList<TiUIView>(len);
}

for (int i = 0; i < len; i++) {
TiUIView view = views.size() > i ? views.get(i) : null;
TiViewProxy proxy = proxies.get(i);
if (view != null && view.getProxy() instanceof TableViewRowProxy) {
proxy = addViewToOldRow(i, view, proxy);
len++;
//ok, all passed. Return true
return true;
}

/*
* Check if views can be reused.
*/
private boolean canUseExistingViews(ArrayList<TiViewProxy> proxies){

int len = proxies.size();
if(views != null && views.size() == len) {
for (int i=0;i<len;i++) {
TiUIView view = views.get(i);
if (view.getProxy() == null) {
return false;
} else if (!checkViewHeirarchy(view.getProxy(), proxies.get(i))) {
return false;
}
}
if (view == null) {
// In some cases the TiUIView for this proxy has been reassigned to another proxy
// We don't want to actually release it though, just reassign by creating a new view
view = proxy.forceCreateView();
clearChildViews(proxy);
if (i >= views.size()) {
views.add(view);
} else {
views.set(i, view);
return true;
}

return false;
}

private ArrayList<KrollPropertyChange> getChangeSet( KrollDict oldProps, KrollDict newProps) {
ArrayList<KrollPropertyChange> propertyChanges = new ArrayList<KrollPropertyChange>();
/*
//First get the values that changed from the oldProps to the newProps
for (String name : oldProps.keySet()) {
Object oldValue = oldProps.get(name);
Object newValue = newProps.get(name);
if (!(oldValue == null && newValue == null)) {
if ((oldValue == null && newValue != null) || (newValue == null && oldValue != null) || (!oldValue.equals(newValue))) {
KrollPropertyChange pch = new KrollPropertyChange(name, oldValue, newValue);
propertyChanges.add(pch);
}
}

View v = view.getOuterView();
view.setProxy(proxy);
view.processProperties(proxy.getProperties());
applyChildProxies(proxy, view);
if (v.getParent() == null) {
content.addView(v, view.getLayoutParams());
}
//Second get the properties that are only in the newProps
for (String name : newProps.keySet()) {
if (!oldProps.containsKey(name)) {
KrollPropertyChange pch = new KrollPropertyChange(name, null, newProps.get(name));
propertyChanges.add(pch);
}
}
*/
/*
What we should do is above. But since we do not handle null values
properly in our SDK, we'll do it the short way which is an optimized
version of doing processProperties.
*/

for (String name : newProps.keySet()) {
Object oldValue = oldProps.get(name);
Object newValue = newProps.get(name);

if (!(oldValue == null && newValue == null)) {
if ((oldValue == null && newValue != null) || (newValue == null && oldValue != null) || (!oldValue.equals(newValue))) {
KrollPropertyChange pch = new KrollPropertyChange(name, oldValue, newValue);
propertyChanges.add(pch);
}
}
}

return propertyChanges;
}

protected void clearChildViews(TiViewProxy parent)
protected void refreshControls()
{
for (TiViewProxy childProxy : parent.getChildren()) {
childProxy.setView(null);
clearChildViews(childProxy);
TableViewRowProxy parent = getRowProxy();
ArrayList<TiViewProxy> proxies = parent.getControls();
int len = proxies.size();
if (!canUseExistingViews(proxies)) {
content.removeAllViews();
if(views == null) {
views = new ArrayList<TiUIView>(len);
} else {
views.clear();
}

for (int i=0;i<len;i++){
TiViewProxy proxy = proxies.get(i);
clearChildViews(proxy);
TiUIView view = proxy.forceCreateView();
views.add(view);
View v = view.getOuterView();
if (v.getParent() == null) {
content.addView(v, view.getLayoutParams());
}
}
} else {
//Ok the view heirarchies are the same.
//Transfer over the views and modelListeners from the old proxies to the new proxies
for (int i=0;i<len;i++) {
TiUIView view = views.get(i);
TiViewProxy oldProxy = view.getProxy();
TiViewProxy newProxy = proxies.get(i);

if (oldProxy != newProxy) {
newProxy.transferView(view, oldProxy);
view.setParent(parent);
view.propertiesChanged(getChangeSet(oldProxy.getProperties(), newProxy.getProperties()), newProxy);
//Need to apply child properties.
applyChildProxies(newProxy, view);
}
}
}
}

Expand All @@ -162,9 +265,13 @@ protected void applyChildProxies(TiViewProxy viewProxy, TiUIView view)
TiViewProxy childProxies[] = viewProxy.getChildren();
for (TiUIView childView : view.getChildren()) {
TiViewProxy childProxy = childProxies[i];
childView.setProxy(childProxy);
childView.processProperties(childProxy.getProperties());
applyChildProxies(childProxy, childView);
TiViewProxy oldProxy = childView.getProxy();
if (childProxy != oldProxy) {
childProxy.transferView(childView, oldProxy);
childView.setParent(viewProxy);
childView.propertiesChanged(getChangeSet(oldProxy.getProperties(), childProxy.getProperties()), childProxy);
applyChildProxies(childProxy, childView);
}
i++;
}
}
Expand Down Expand Up @@ -213,7 +320,7 @@ public void setRowData(TableViewRowProxy rp) {
// Handle right image
boolean clearRightImage = true;
// It's one or the other, check or child. If you set them both, child's gonna win.
HashMap props = rp.getProperties();
KrollDict props = rp.getProperties();
if (props.containsKey(TiC.PROPERTY_HAS_CHECK)) {
if (TiConvert.toBoolean(props, TiC.PROPERTY_HAS_CHECK)) {
if (hasCheckDrawable == null) {
Expand Down Expand Up @@ -366,7 +473,9 @@ protected void onLayout(boolean changed, int left, int top, int right, int botto
top = 0;

int height = bottom - top;


getRowProxy().setTableViewItem(this);

if (leftImage != null && leftImage.getVisibility() != GONE) {
int w = leftImage.getMeasuredWidth();
int h = leftImage.getMeasuredHeight();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,23 @@ public TiUIView forceCreateView()
view = null;
return getOrCreateView();
}

/**
* Transfer an existing view to this view proxy.
* Special use in tableView. Do not use anywhere else.
* Called from TiTableViewRowProxyItem.java
* @param transferview - The view to transfer
* @param oldProxy - The currentProxy of the view
*/
public void transferView(TiUIView transferview, TiViewProxy oldProxy) {
if(oldProxy != null) {
oldProxy.setView(null);
oldProxy.setModelListener(null);
}
view = transferview;
modelListener = transferview;
view.setProxy(this);
}

/**
* Creates or retrieves the view associated with this proxy.
Expand Down

0 comments on commit 245b50d

Please sign in to comment.