Titanium JIRA Archive
Titanium SDK/CLI (TIMOB)

[TIMOB-20116] Android - ScrollableView removeView(): java.lang.IndexOutOfBoundsException: Invalid index X, size is X

GitHub Issuen/a
TypeBug
PriorityMedium
StatusClosed
ResolutionFixed
Resolution Date2016-04-05T03:31:23.000+0000
Affected Version/sRelease 5.0.2, Release 5.1.1
Fix Version/sRelease 5.4.0
ComponentsAndroid
Labelsandroid, removeview, scrollableview
ReporterRodolfo Perottoni
AssigneeAshraf Abu
Created2015-10-06T19:23:15.000+0000
Updated2016-06-24T18:41:04.000+0000

Description

This is happening only in the android platform. Seems like when you call the ScrollableView.removeView() method it automatically jumps to the previous view if you're currently viewing the one you're trying to delete. However, that fires an exception. How to reproduce: * Create an Android-enabled project with a single, main view. * Add to that view a ScrollableView and a Button below it. * Add 3 empty views to the ScrollableView. * Add an event to the button which fires the following code:
_.each($.scrollableView.getViews(), function(view) {
     $.scrollableView.removeView(view);
});
* Click the button with the view number 1 focused: it will work. * Reopen the app (so the views get added again), browse to the 3rd view and click the button. It will throw this exception:
[ERROR] :  TiApplication: (main) [47704,48391] Sending event: exception on thread: main msg:java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1; Titanium 5.0.3,2015/10/02 00:31,d4496fe
[ERROR] :  TiApplication: java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
[ERROR] :  TiApplication: 	at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
[ERROR] :  TiApplication: 	at java.util.ArrayList.get(ArrayList.java:308)
[ERROR] :  TiApplication: 	at ti.modules.titanium.ui.widget.TiUIScrollableView$2.onPageSelected(TiUIScrollableView.java:159)
[ERROR] :  TiApplication: 	at android.support.v4.view.ViewPager.scrollToItem(ViewPager.java:578)
[ERROR] :  TiApplication: 	at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:555)
[ERROR] :  TiApplication: 	at android.support.v4.view.ViewPager.setCurrentItemInternal(ViewPager.java:513)
[ERROR] :  TiApplication: 	at android.support.v4.view.ViewPager.dataSetChanged(ViewPager.java:912)
[ERROR] :  TiApplication: 	at android.support.v4.view.ViewPager$PagerObserver.onChanged(ViewPager.java:2826)
[ERROR] :  TiApplication: 	at android.database.DataSetObservable.notifyChanged(DataSetObservable.java:37)
[ERROR] :  TiApplication: 	at android.support.v4.view.PagerAdapter.notifyDataSetChanged(PagerAdapter.java:276)
[ERROR] :  TiApplication: 	at ti.modules.titanium.ui.widget.TiUIScrollableView.removeView(TiUIScrollableView.java:350)
[ERROR] :  TiApplication: 	at ti.modules.titanium.ui.ScrollableViewProxy.handleMessage(ScrollableViewProxy.java:131)
[ERROR] :  TiApplication: 	at android.os.Handler.dispatchMessage(Handler.java:98)
[ERROR] :  TiApplication: 	at android.os.Looper.loop(Looper.java:135)
[ERROR] :  TiApplication: 	at android.app.ActivityThread.main(ActivityThread.java:5254)
[ERROR] :  TiApplication: 	at java.lang.reflect.Method.invoke(Native Method)
[ERROR] :  TiApplication: 	at java.lang.reflect.Method.invoke(Method.java:372)
[ERROR] :  TiApplication: 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:903)
[ERROR] :  TiApplication: 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:698)
How i've solved it: Before removing the ScrollableView views, i've used this method:
$.scrollableView.scrollToView($.scrollableView.getViews()[0]);

Comments

  1. Andrey Tkachenko 2016-04-01

    Friday PR: https://github.com/appcelerator/titanium_mobile/pull/7904 Test code: index.xml
       <Alloy>
       	<Window class="container">
       		<ScrollableView id="scrollableView">
       			<View><Label>1</Label></View>
       			<View><Label>2</Label></View>
       			<View><Label>3</Label></View>
       		</ScrollableView>
       		<View height="Ti.UI.SIZE" top="0" layout="vertical">
       		<Button onClick="doClear">Clear</Button>
       		<Button onClick="doClearSecond">Clear second</Button>
       		</View>
       	</Window>
       </Alloy>
       
    index.js
       function doClear(e) {
           _.each($.scrollableView.getViews(), function(view) {
            	$.scrollableView.removeView(view);
            });
       }
       
       function doClearSecond() {
       	$.scrollableView.removeView($.scrollableView.getViews()[1]);}
       $.index.open();
       
  2. Ashraf Abu 2016-04-05

    Tested code with test case above. Working as expected.
  3. Ashraf Abu 2016-04-05

    PR https://github.com/appcelerator/titanium_mobile/pull/7904 Merged with test cases in TIMOB-23134 and TIMOB-20116
  4. Lokesh Choudhary 2016-06-24

    Verified the fix. removeView() does not give a java.lang.IndexOutOfBoundsException. Closing. Environment: Appc Studio : 4.7.0.201606150733 Ti SDK : 5.4.0.v20160617074028 Ti CLI : 5.0.9 Alloy : 1.9.0 MAC El Capitan : 10.11.4 Appc NPM : 4.2.7-2 Appc CLI : 5.4.0-18 Node: 4.4.4 Nexus 6 - Android 6.0.1

JSON Source