1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.widget;
18
19import com.google.android.collect.Lists;
20
21import junit.framework.Assert;
22
23import android.content.Context;
24import android.content.res.Resources;
25import android.test.InstrumentationTestCase;
26import android.test.mock.MockContext;
27import android.test.suitebuilder.annotation.MediumTest;
28import android.view.View;
29import android.view.ViewGroup;
30import android.widget.ArrayAdapter;
31import android.widget.ListView;
32
33import java.util.List;
34
35public class ListViewTest extends InstrumentationTestCase {
36
37    /**
38     * If a view in a ListView requests a layout it should be remeasured.
39     */
40    @MediumTest
41    public void testRequestLayout() throws Exception {
42        MockContext context = new MockContext2();
43        ListView listView = new ListView(context);
44        List<String> items = Lists.newArrayList("hello");
45        Adapter<String> adapter = new Adapter<String>(context, 0, items);
46        listView.setAdapter(adapter);
47
48        int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
49
50        adapter.notifyDataSetChanged();
51        listView.measure(measureSpec, measureSpec);
52        listView.layout(0, 0, 100, 100);
53
54        MockView childView = (MockView) listView.getChildAt(0);
55
56        childView.requestLayout();
57        childView.onMeasureCalled = false;
58        listView.measure(measureSpec, measureSpec);
59        listView.layout(0, 0, 100, 100);
60        Assert.assertTrue(childView.onMeasureCalled);
61    }
62
63    /**
64     * The list view should handle the disappearance of the only selected item, even when that item
65     * was selected before its disappearance.
66     *
67     */
68    @MediumTest
69    public void testNoSelectableItems() throws Exception {
70        MockContext context = new MockContext2();
71        ListView listView = new ListView(context);
72        // We use a header as the unselectable item to remain after the selectable one is removed.
73        listView.addHeaderView(new View(context), null, false);
74        List<String> items = Lists.newArrayList("hello");
75        Adapter<String> adapter = new Adapter<String>(context, 0, items);
76        listView.setAdapter(adapter);
77
78        listView.setSelection(1);
79
80        int measureSpec = View.MeasureSpec.makeMeasureSpec(100, View.MeasureSpec.EXACTLY);
81
82        adapter.notifyDataSetChanged();
83        listView.measure(measureSpec, measureSpec);
84        listView.layout(0, 0, 100, 100);
85
86        items.remove(0);
87
88        adapter.notifyDataSetChanged();
89        listView.measure(measureSpec, measureSpec);
90        listView.layout(0, 0, 100, 100);
91    }
92
93    private class MockContext2 extends MockContext {
94
95        @Override
96        public Resources getResources() {
97            return getInstrumentation().getTargetContext().getResources();
98        }
99
100        @Override
101        public Resources.Theme getTheme() {
102            return getInstrumentation().getTargetContext().getTheme();
103        }
104
105        @Override
106        public Object getSystemService(String name) {
107            if (Context.LAYOUT_INFLATER_SERVICE.equals(name)) {
108                return getInstrumentation().getTargetContext().getSystemService(name);
109            }
110            return super.getSystemService(name);
111        }
112    }
113
114    private class MockView extends View {
115
116        public boolean onMeasureCalled = false;
117
118        public MockView(Context context) {
119            super(context);
120        }
121
122        @Override
123        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
124            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
125            onMeasureCalled = true;
126        }
127    }
128
129    private class Adapter<T> extends ArrayAdapter<T> {
130
131        public Adapter(Context context, int resource, List<T> objects) {
132            super(context, resource, objects);
133        }
134
135        @Override
136        public View getView(int position, View convertView, ViewGroup parent) {
137            return new MockView(getContext());
138        }
139    }
140
141}
142