Many style and navigation changes. Pulled in ActionBarCompat from Android sample sources to provide an action bar paradigm on pre-gingerbread devices. Changed the OpenRocket Viewer activity to use a viewpager with sliding tabs since it looks much nicer. Updated to the newest android-support-v4 jar.

This commit is contained in:
Kevin Ruland 2012-02-11 20:17:39 +00:00
parent e56dabfd78
commit 0f7a05b95b
51 changed files with 1757 additions and 324 deletions

View File

@ -6,7 +6,7 @@
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="9" />
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
@ -16,10 +16,11 @@
android:debuggable="true"
android:icon="@drawable/or_launcher"
android:killAfterRestore="true"
android:label="@string/app_name" >
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".android.Main"
android:theme="@android:style/Theme.Black.NoTitleBar" >
android:theme="@style/AppTheme.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -28,14 +29,14 @@
</activity>
<activity
android:name=".android.rocket.OpenRocketLoaderActivity"
android:theme="@android:style/Theme.Black.NoTitleBar" >
android:theme="@style/AppTheme.NoTitleBar" >
<!--
I don't understand why I need to have two different intent filters.
Combining the <data> elements into a single field did not result in a working
application. The first intent-filter (with mimeType wildcard) convinces the
file browser to associate the correct launcher icon. the second intent-filter
is actually invoked when a file is selected.
is actually invoked when a file is selected.
-->
<!-- this intent filter convinces the file browser to display icons -->
<intent-filter>
@ -61,9 +62,7 @@
android:scheme="file" />
</intent-filter>
</activity>
<activity
android:name=".android.rocket.OpenRocketViewer"
android:label="@string/app_name" />
<activity android:name=".android.rocket.OpenRocketViewer" />
<activity android:name=".android.PreferencesActivity" >
<intent-filter>
<action android:name="net.sf.openrocket.android.PreferencesActivity" />
@ -72,9 +71,13 @@
</intent-filter>
</activity>
<activity android:name=".android.motor.MotorBrowserActivity" />
<activity android:name=".android.motor.BurnPlotActivity" />
<activity
android:name=".android.motor.BurnPlotActivity"
android:theme="@style/AppTheme.NoTitleBar" />
<activity android:name=".android.thrustcurve.TCQueryActivity" />
<activity android:name=".android.simulation.SimulationViewActivity" />
<activity
android:name=".android.simulation.SimulationViewActivity"
android:theme="@style/AppTheme.NoTitleBar" />
<activity android:name=".android.filebrowser.SimpleFileBrowser" />
</application>

Binary file not shown.

3
android/lint.xml Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<lint>
</lint>

View File

@ -8,4 +8,4 @@
# project structure.
# Project target.
target=android-10
target=android-15

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 955 B

View File

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -0,0 +1,23 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/actionbar_compat_item_pressed"
android:state_pressed="true" />
<item android:drawable="@drawable/actionbar_compat_item_focused"
android:state_focused="true" />
<item android:drawable="@android:color/transparent" />
</selector>

View File

@ -0,0 +1,19 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#ef7000" />
</shape>

View File

@ -0,0 +1,19 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#eda700" />
</shape>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
android:src="@drawable/or_launcher"/>

View File

@ -0,0 +1,27 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center">
<ProgressBar android:layout_width="32dp"
android:layout_height="32dp"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_gravity="center"
style="?android:attr/indeterminateProgressStyle" />
</FrameLayout>

View File

@ -4,42 +4,23 @@
android:layout_height="match_parent"
android:orientation="horizontal" >
<TabHost
android:id="@android:id/tabhost"
android:layout_width="match_parent"
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_weight="4"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<LinearLayout
<android.support.v4.view.PagerTitleStrip
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</TabHost>
<LinearLayout android:id="@+id/sidepane"
<LinearLayout
android:id="@+id/sidepane"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical"/>
android:layout_weight="1"
android:orientation="vertical" />
</LinearLayout>

View File

@ -4,42 +4,23 @@
android:layout_height="match_parent"
android:orientation="vertical" >
<TabHost
android:id="@android:id/tabhost"
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_weight="4"
android:layout_height="match_parent" >
android:layout_height="match_parent"
android:layout_weight="3" >
<LinearLayout
<android.support.v4.view.PagerTitleStrip
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
android:layout_gravity="top" />
</android.support.v4.view.ViewPager>
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"
android:orientation="horizontal" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0" />
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</TabHost>
<LinearLayout android:id="@+id/sidepane"
<LinearLayout
android:id="@+id/sidepane"
android:layout_width="wrap_content"
android:layout_weight="1"
android:layout_height="wrap_content"
android:orientation="vertical"/>
android:layout_weight="1"
android:orientation="vertical" />
</LinearLayout>

View File

@ -0,0 +1,22 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@id/actionbar_compat"
android:background="#ff000000"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal" />

View File

@ -3,8 +3,8 @@
android:id="@+id/xyplot"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginLeft="0px"
android:layout_marginRight="0px"
android:layout_marginTop="5px"
title="plot"
android:layout_marginLeft="2dp"
android:layout_marginRight="2dp"
android:layout_marginTop="5dp"
title=" "
/>

View File

@ -1,33 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<TabHost
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:orientation="vertical"
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent" >
<TabWidget
android:id="@android:id/tabs"
android:orientation="horizontal"
<android.support.v4.view.PagerTitleStrip
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="0"/>
android:layout_height="match_parent"
android:layout_gravity="top"/>
</android.support.v4.view.ViewPager>
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0"/>
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
</LinearLayout>
</TabHost>
</LinearLayout>

View File

@ -10,44 +10,52 @@
android:orientation="vertical" >
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Designer" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerDesigner"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Length" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerLength"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Empty Mass" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerMass"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stage Count" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerStageCount"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@ -56,47 +64,56 @@
<Spinner
android:id="@+id/openrocketviewerConfigurationSpinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
android:layout_height="wrap_content"
android:prompt="@string/overviewConfigurationSpinnerPrompt" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Lift off weight" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerLiftOffWeight"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CG" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerCG"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="CP" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerCP"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="" />
<TextView
style="@style/labelTextStyle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stability margin" />
<TextView
style="@style/valueTextStyle"
android:id="@+id/openrocketviewerStabilityMargin"
android:layout_width="match_parent"
android:layout_height="wrap_content"

View File

@ -4,11 +4,6 @@
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/path"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"

View File

@ -6,7 +6,7 @@
<!-- shim to get dialog correct size ?? -->
<View
android:layout_width="2000dp"
android:layout_width="200dp"
android:layout_height="0px"
android:layout_margin="0px"
android:orientation="horizontal" />

View File

@ -1,15 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/main_menu_open"
android:title="Open"/>
<item
android:id="@+id/main_menu_motor"
android:title="Motor"/>
<item
android:id="@+id/main_menu_preferences"
android:title="@string/Preferences"
android:icon="@drawable/ic_menu_preferences"/>
android:icon="@drawable/ic_menu_preferences"
android:showAsAction="always"/>
</menu>

View File

@ -7,6 +7,7 @@
<item
android:id="@+id/preference_menu_option"
android:icon="@drawable/ic_menu_preferences"
android:title="@string/Preferences"/>
android:title="@string/Preferences"
/>
</menu>

View File

@ -3,7 +3,8 @@
<item
android:id="@+id/motor_list_menu_option"
android:title="Motor List"/>
android:title="Motor List"
android:showAsAction="always"/>
<item
android:id="@+id/preference_menu_option"
android:title="@string/Preferences"

View File

@ -0,0 +1,34 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<resources>
<style name="AppTheme" parent="android:style/Theme.Holo">
<item name="android:actionBarStyle">@style/ActionBar</item>
<item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
</style>
<style name="ActionBar" parent="android:style/Widget.Holo.ActionBar">
<item name="android:background">@color/actionbar_background_color</item>
<item name="android:titleTextStyle">@style/ActionBarTitle</item>
<item name="android:logo">@drawable/home_item</item>
</style>
<style name="ActionBarTitle">
<item name="android:textColor">@color/actionbar_title_color</item>
</style>
</resources>

View File

@ -0,0 +1,24 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<resources>
<style name="ActionBarTitle" parent="android:style/TextAppearance.Holo.Widget.ActionBar.Title">
<item name="android:textColor">@color/actionbar_title_color</item>
<item name="android:background">@color/actionbar_background_color</item>
</style>
</resources>

View File

@ -0,0 +1,27 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<resources>
<declare-styleable name="AppTheme">
<attr name="actionbarCompatHomeAsUpStyle" format="reference" />
<attr name="actionbarCompatTitleStyle" format="reference" />
<attr name="actionbarCompatItemStyle" format="reference" />
<attr name="actionbarCompatItemHomeStyle" format="reference" />
<attr name="actionbarCompatProgressIndicatorStyle" format="reference" />
</declare-styleable>
</resources>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="actionbar_title_color">#FFFFFF</color>
<color name="actionbar_background_color">#ff000000</color>
</resources>

View File

@ -0,0 +1,21 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<resources>
<dimen name="actionbar_compat_height">48dp</dimen>
<dimen name="actionbar_compat_button_width">48dp</dimen>
<dimen name="actionbar_compat_button_home_width">40dp</dimen>
</resources>

View File

@ -0,0 +1,24 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<resources>
<item type="id" name="actionbar_compat" />
<item type="id" name="actionbar_home_as_up" />
<item type="id" name="actionbar_compat_title" />
<item type="id" name="actionbar_compat_item_refresh_progress" />
<item type="id" name="actionbar_compat_item_refresh" />
<item type="id" name="menu_refresh" />
</resources>

View File

@ -0,0 +1,72 @@
<!--
Copyright 2011 The Android Open Source Project
Licensed 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.
-->
<resources>
<style name="AppTheme" parent="android:style/Theme">
<item name="android:textColor">#FFFFFF</item>
<item name="android:windowTitleSize">@dimen/actionbar_compat_height</item>
<item name="android:windowTitleBackgroundStyle">@style/ActionBarCompat</item>
<item name="android:windowContentOverlay">@drawable/actionbar_shadow</item>
<!-- for programmatic instantiation -->
<item name="actionbarCompatTitleStyle">@style/ActionBarCompatTitle</item>
<item name="actionbarCompatItemStyle">@style/ActionBarCompatItem</item>
<item name="actionbarCompatItemHomeStyle">@style/ActionBarCompatHomeItem</item>
<item name="actionbarCompatProgressIndicatorStyle">@style/ActionBarCompatProgressIndicator</item>
<item name="actionbarCompatHomeAsUpStyle">@style/ActionBarCompatHomeAsUp</item>
</style>
<style name="ActionBarCompat">
<item name="android:background">@color/actionbar_background_color</item>
</style>
<style name="ActionBarCompatHomeAsUp">
<item name="android:background">@drawable/ic_home_carat</item>
</style>
<style name="ActionBarCompatItemBase">
<!-- layout_width/height must be set in code -->
<item name="android:scaleType">center</item>
<item name="android:background">@drawable/actionbar_compat_item</item>
</style>
<style name="ActionBarCompatProgressIndicator" parent="android:style/Widget.ProgressBar.Large">
<item name="android:indeterminate">true</item>
</style>
<style name="ActionBarCompatTitleBase">
<item name="android:id">@id/actionbar_compat_title</item>
<!-- layout_width/height/weight must be set in code -->
<item name="android:gravity">center_vertical</item>
<item name="android:textSize">16sp</item>
<item name="android:paddingLeft">6dp</item>
<item name="android:paddingRight">6dp</item>
<item name="android:singleLine">true</item>
<item name="android:ellipsize">marquee</item>
</style>
<style name="ActionBarCompatTitle" parent="style/ActionBarCompatTitleBase">
<item name="android:textColor">@color/actionbar_title_color</item>
</style>
<style name="ActionBarCompatItem" parent="style/ActionBarCompatItemBase">
</style>
<style name="ActionBarCompatHomeItem" parent="style/ActionBarCompatItemBase">
</style>
</resources>

View File

@ -88,12 +88,13 @@
<string name="TCMotorSearchFormSubmit">Submit</string>
<string name="tcdownload">Download from ThrustCurve</string>
<string name="overviewConfigurationSpinnerPrompt">Select Configuration</string>
<string name="simulationSeries1Label">Series 1</string>
<string name="simulationSeries2Label">Series 2</string>
<string name="motorbrowsergrouptitle">Motor Browser Grouping</string>
<string name="useinternalfilebrowsertitle">Use Internal File Browser</string>
<string name="useinternalfilebrowsersummary">uncheck to use system file browser if available</string>
<string name="useinternalfilebrowsersummary">Check to use built in file browser instead of external file browser</string>
<string-array name="PreferenceUnitLengthEntries">
<item>Millimeters</item>

View File

@ -1,7 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style parent="@android:attr/listViewStyle" name="treeViewListStyle">
<style name="treeViewListStyle" parent="@android:attr/listViewStyle">
<item name="android:background">@android:color/white</item>
<item name="android:divider">@drawable/divider</item>
</style>
</resources>
<style name="labelTextStyle" parent="@android:style/TextAppearance.Medium" />
<style name="valueTextStyle" parent="@android:style/TextAppearance.Large" />
<style name="AppTheme.NoTitleBar" parent="@style/AppTheme">
<item name="android:windowNoTitle">true</item>
</style>
</resources>

View File

@ -51,12 +51,6 @@ public class Main extends FragmentActivity {
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch( item.getItemId() ) {
case R.id.main_menu_motor:
ActivityHelpers.browseMotors(this);
return true;
case R.id.main_menu_open:
pickOrkFiles();
return true;
case R.id.main_menu_preferences:
ActivityHelpers.startPreferences(this);
return true;

View File

@ -0,0 +1,83 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
/**
* A base activity that defers common functionality across app activities to an {@link
* ActionBarHelper}.
*
* NOTE: dynamically marking menu items as invisible/visible is not currently supported.
*
* NOTE: this may used with the Android Compatibility Package by extending
* android.support.v4.app.FragmentActivity instead of {@link Activity}.
*/
public abstract class ActionBarActivity extends Activity {
final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this);
/**
* Returns the {@link ActionBarHelper} for this activity.
*/
protected ActionBarHelper getActionBarHelper() {
return mActionBarHelper;
}
/**{@inheritDoc}*/
@Override
public MenuInflater getMenuInflater() {
return mActionBarHelper.getMenuInflater(super.getMenuInflater());
}
/**{@inheritDoc}*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActionBarHelper.onCreate(savedInstanceState);
}
/**{@inheritDoc}*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mActionBarHelper.onPostCreate(savedInstanceState);
}
/**
* Base action bar-aware implementation for
* {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
*
* Note: marking menu items as invisible/visible is not currently supported.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean retValue = false;
retValue |= mActionBarHelper.onCreateOptionsMenu(menu);
retValue |= super.onCreateOptionsMenu(menu);
return retValue;
}
/**{@inheritDoc}*/
@Override
protected void onTitleChanged(CharSequence title, int color) {
mActionBarHelper.onTitleChanged(title, color);
super.onTitleChanged(title, color);
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.Menu;
import android.view.MenuInflater;
/**
* A base activity that defers common functionality across app activities to an {@link
* ActionBarHelper}.
*
* NOTE: dynamically marking menu items as invisible/visible is not currently supported.
*
* NOTE: this may used with the Android Compatibility Package by extending
* android.support.v4.app.FragmentActivity instead of {@link Activity}.
*/
public abstract class ActionBarFragmentActivity extends FragmentActivity {
final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this);
/**
* Returns the {@link ActionBarHelper} for this activity.
*/
protected ActionBarHelper getActionBarHelper() {
return mActionBarHelper;
}
/**{@inheritDoc}*/
@Override
public MenuInflater getMenuInflater() {
return mActionBarHelper.getMenuInflater(super.getMenuInflater());
}
/**{@inheritDoc}*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActionBarHelper.onCreate(savedInstanceState);
}
/**{@inheritDoc}*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mActionBarHelper.onPostCreate(savedInstanceState);
}
/**
* Base action bar-aware implementation for
* {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
*
* Note: marking menu items as invisible/visible is not currently supported.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean retValue = false;
retValue |= mActionBarHelper.onCreateOptionsMenu(menu);
retValue |= super.onCreateOptionsMenu(menu);
return retValue;
}
/**{@inheritDoc}*/
@Override
protected void onTitleChanged(CharSequence title, int color) {
mActionBarHelper.onTitleChanged(title, color);
super.onTitleChanged(title, color);
}
}

View File

@ -0,0 +1,102 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import net.sf.openrocket.R;
import android.app.Activity;
import android.os.Build;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
/**
* An abstract class that handles some common action bar-related functionality in the app. This
* class provides functionality useful for both phones and tablets, and does not require any Android
* 3.0-specific features, although it uses them if available.
*
* Two implementations of this class are {@link ActionBarHelperBase} for a pre-Honeycomb version of
* the action bar, and {@link ActionBarHelperHoneycomb}, which uses the built-in ActionBar features
* in Android 3.0 and later.
*/
public abstract class ActionBarHelper {
protected Activity mActivity;
/**
* Factory method for creating {@link ActionBarHelper} objects for a
* given activity. Depending on which device the app is running, either a basic helper or
* Honeycomb-specific helper will be returned.
*/
public static ActionBarHelper createInstance(Activity activity) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
return new ActionBarHelperICS(activity);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
return new ActionBarHelperHoneycomb(activity);
} else {
return new ActionBarHelperBase(activity);
}
}
protected ActionBarHelper(Activity activity) {
mActivity = activity;
}
/**
* Action bar helper code to be run in {@link Activity#onCreate(android.os.Bundle)}.
*/
public void onCreate(Bundle savedInstanceState) {
}
/**
* Action bar helper code to be run in {@link Activity#onPostCreate(android.os.Bundle)}.
*/
public void onPostCreate(Bundle savedInstanceState) {
}
/**
* Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
*
* NOTE: Setting the visibility of menu items in <em>menu</em> is not currently supported.
*/
public boolean onCreateOptionsMenu(Menu menu) {
return true;
}
/**
* Action bar helper code to be run in {@link Activity#onTitleChanged(CharSequence, int)}.
*/
protected void onTitleChanged(CharSequence title, int color) {
}
/**
* Sets the indeterminate loading state of the item with ID {@link R.id.menu_refresh}.
* (where the item ID was menu_refresh).
*/
public abstract void setRefreshActionItemState(boolean refreshing);
/**
* Returns a {@link MenuInflater} for use when inflating menus. The implementation of this
* method in {@link ActionBarHelperBase} returns a wrapped menu inflater that can read
* action bar metadata from a menu resource pre-Honeycomb.
*/
public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
return superMenuInflater;
}
public abstract void setDisplayHomeAsUpEnabled( boolean enabled );
public abstract void hide();
}

View File

@ -0,0 +1,331 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;
import net.sf.openrocket.R;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import android.app.Activity;
import android.content.Context;
import android.content.res.XmlResourceParser;
import android.os.Bundle;
import android.view.Gravity;
import android.view.InflateException;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
/**
* A class that implements the action bar pattern for pre-Honeycomb devices.
*/
public class ActionBarHelperBase extends ActionBarHelper {
private static final String MENU_RES_NAMESPACE = "http://schemas.android.com/apk/res/android";
private static final String MENU_ATTR_ID = "id";
private static final String MENU_ATTR_SHOW_AS_ACTION = "showAsAction";
private boolean showHomeAsUpEnabled = false;
protected Set<Integer> mActionItemIds = new HashSet<Integer>();
protected ActionBarHelperBase(Activity activity) {
super(activity);
}
/**{@inheritDoc}*/
@Override
public void onCreate(Bundle savedInstanceState) {
mActivity.requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
}
/**{@inheritDoc}*/
@Override
public void onPostCreate(Bundle savedInstanceState) {
mActivity.getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
R.layout.actionbar_compat);
setupActionBar();
SimpleMenu menu = new SimpleMenu(mActivity);
mActivity.onCreatePanelMenu(Window.FEATURE_OPTIONS_PANEL, menu);
mActivity.onPrepareOptionsMenu(menu);
for (int i = 0; i < menu.size(); i++) {
MenuItem item = menu.getItem(i);
if (mActionItemIds.contains(item.getItemId())) {
addActionItemCompatFromMenuItem(item);
}
}
}
/**
* Sets up the compatibility action bar with the given title.
*/
private void setupActionBar() {
final ViewGroup actionBarCompat = getActionBarCompat();
if (actionBarCompat == null) {
return;
}
LinearLayout.LayoutParams springLayoutParams = new LinearLayout.LayoutParams(
0, ViewGroup.LayoutParams.FILL_PARENT);
springLayoutParams.weight = 1;
// Add Home as Up Carat
ImageButton homeAsUp = new ImageButton(mActivity,null, R.attr.actionbarCompatHomeAsUpStyle);
homeAsUp.setId(R.id.actionbar_home_as_up);
LinearLayout.LayoutParams centerVerticalParams = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
centerVerticalParams.gravity = Gravity.CENTER_VERTICAL;
homeAsUp.setLayoutParams(centerVerticalParams);
homeAsUp.setVisibility( showHomeAsUpEnabled ? View.VISIBLE : View.INVISIBLE );
actionBarCompat.addView(homeAsUp);
// Add Home button
SimpleMenu tempMenu = new SimpleMenu(mActivity);
SimpleMenuItem homeItem = new SimpleMenuItem(
tempMenu, android.R.id.home, 0, mActivity.getString(R.string.app_name));
homeItem.setIcon(R.drawable.home_item);
addActionItemCompatFromMenuItem(homeItem);
// Add title text
TextView titleText = new TextView(mActivity, null, R.attr.actionbarCompatTitleStyle);
titleText.setLayoutParams(springLayoutParams);
titleText.setText(mActivity.getTitle());
actionBarCompat.addView(titleText);
}
/**{@inheritDoc}*/
@Override
public void setRefreshActionItemState(boolean refreshing) {
View refreshButton = mActivity.findViewById(R.id.actionbar_compat_item_refresh);
View refreshIndicator = mActivity.findViewById(
R.id.actionbar_compat_item_refresh_progress);
if (refreshButton != null) {
refreshButton.setVisibility(refreshing ? View.GONE : View.VISIBLE);
}
if (refreshIndicator != null) {
refreshIndicator.setVisibility(refreshing ? View.VISIBLE : View.GONE);
}
}
/**
* Action bar helper code to be run in {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
*
* NOTE: This code will mark on-screen menu items as invisible.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Hides on-screen action items from the options menu.
for (Integer id : mActionItemIds) {
menu.findItem(id).setVisible(false);
}
return true;
}
/**{@inheritDoc}*/
@Override
protected void onTitleChanged(CharSequence title, int color) {
TextView titleView = (TextView) mActivity.findViewById(R.id.actionbar_compat_title);
if (titleView != null) {
titleView.setText(title);
}
}
/**
* Returns a {@link android.view.MenuInflater} that can read action bar metadata on
* pre-Honeycomb devices.
*/
public MenuInflater getMenuInflater(MenuInflater superMenuInflater) {
return new WrappedMenuInflater(mActivity, superMenuInflater);
}
@Override
public void setDisplayHomeAsUpEnabled(boolean enabled) {
showHomeAsUpEnabled = enabled;
View v = mActivity.findViewById(R.id.actionbar_home_as_up);
if ( v != null ) {
v.setVisibility( showHomeAsUpEnabled ? View.VISIBLE : View.INVISIBLE );
}
}
@Override
public void hide() {
ViewGroup actionbar = getActionBarCompat();
actionbar.setVisibility(View.GONE);
}
/**
* Returns the {@link android.view.ViewGroup} for the action bar on phones (compatibility action
* bar). Can return null, and will return null on Honeycomb.
*/
private ViewGroup getActionBarCompat() {
return (ViewGroup) mActivity.findViewById(R.id.actionbar_compat);
}
/**
* Adds an action button to the compatibility action bar, using menu information from a {@link
* android.view.MenuItem}. If the menu item ID is <code>menu_refresh</code>, the menu item's
* state can be changed to show a loading spinner using
* {@link com.example.android.actionbarcompat.ActionBarHelperBase#setRefreshActionItemState(boolean)}.
*/
private View addActionItemCompatFromMenuItem(final MenuItem item) {
final int itemId = item.getItemId();
final ViewGroup actionBar = getActionBarCompat();
if (actionBar == null) {
return null;
}
// Create the button
ImageButton actionButton = new ImageButton(mActivity, null,
itemId == android.R.id.home
? R.attr.actionbarCompatItemHomeStyle
: R.attr.actionbarCompatItemStyle);
actionButton.setLayoutParams(new ViewGroup.LayoutParams(
(int) mActivity.getResources().getDimension(
itemId == android.R.id.home
? R.dimen.actionbar_compat_button_home_width
: R.dimen.actionbar_compat_button_width),
ViewGroup.LayoutParams.FILL_PARENT));
if (itemId == R.id.menu_refresh) {
actionButton.setId(R.id.actionbar_compat_item_refresh);
}
actionButton.setImageDrawable(item.getIcon());
actionButton.setScaleType(ImageView.ScaleType.CENTER);
actionButton.setContentDescription(item.getTitle());
actionButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
mActivity.onMenuItemSelected(Window.FEATURE_OPTIONS_PANEL, item);
}
});
actionBar.addView(actionButton);
if (item.getItemId() == R.id.menu_refresh) {
// Refresh buttons should be stateful, and allow for indeterminate progress indicators,
// so add those.
ProgressBar indicator = new ProgressBar(mActivity, null,
R.attr.actionbarCompatProgressIndicatorStyle);
final int buttonWidth = mActivity.getResources().getDimensionPixelSize(
R.dimen.actionbar_compat_button_width);
final int buttonHeight = mActivity.getResources().getDimensionPixelSize(
R.dimen.actionbar_compat_height);
final int progressIndicatorWidth = buttonWidth / 2;
LinearLayout.LayoutParams indicatorLayoutParams = new LinearLayout.LayoutParams(
progressIndicatorWidth, progressIndicatorWidth);
indicatorLayoutParams.setMargins(
(buttonWidth - progressIndicatorWidth) / 2,
(buttonHeight - progressIndicatorWidth) / 2,
(buttonWidth - progressIndicatorWidth) / 2,
0);
indicator.setLayoutParams(indicatorLayoutParams);
indicator.setVisibility(View.GONE);
indicator.setId(R.id.actionbar_compat_item_refresh_progress);
actionBar.addView(indicator);
}
return actionButton;
}
/**
* A {@link android.view.MenuInflater} that reads action bar metadata.
*/
private class WrappedMenuInflater extends MenuInflater {
MenuInflater mInflater;
public WrappedMenuInflater(Context context, MenuInflater inflater) {
super(context);
mInflater = inflater;
}
@Override
public void inflate(int menuRes, Menu menu) {
loadActionBarMetadata(menuRes);
mInflater.inflate(menuRes, menu);
}
/**
* Loads action bar metadata from a menu resource, storing a list of menu item IDs that
* should be shown on-screen (i.e. those with showAsAction set to always or ifRoom).
* @param menuResId
*/
private void loadActionBarMetadata(int menuResId) {
XmlResourceParser parser = null;
try {
parser = mActivity.getResources().getXml(menuResId);
int eventType = parser.getEventType();
int itemId;
int showAsAction;
boolean eof = false;
while (!eof) {
switch (eventType) {
case XmlPullParser.START_TAG:
if (!parser.getName().equals("item")) {
break;
}
itemId = parser.getAttributeResourceValue(MENU_RES_NAMESPACE,
MENU_ATTR_ID, 0);
if (itemId == 0) {
break;
}
showAsAction = parser.getAttributeIntValue(MENU_RES_NAMESPACE,
MENU_ATTR_SHOW_AS_ACTION, -1);
if (showAsAction == MenuItem.SHOW_AS_ACTION_ALWAYS ||
showAsAction == MenuItem.SHOW_AS_ACTION_IF_ROOM) {
mActionItemIds.add(itemId);
}
break;
case XmlPullParser.END_DOCUMENT:
eof = true;
break;
}
eventType = parser.next();
}
} catch (XmlPullParserException e) {
throw new InflateException("Error inflating menu XML", e);
} catch (IOException e) {
throw new InflateException("Error inflating menu XML", e);
} finally {
if (parser != null) {
parser.close();
}
}
}
}
}

View File

@ -0,0 +1,90 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import net.sf.openrocket.R;
import android.app.Activity;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
/**
* An extension of {@link ActionBarHelper} that provides Android 3.0-specific functionality for
* Honeycomb tablets. It thus requires API level 11.
*/
public class ActionBarHelperHoneycomb extends ActionBarHelper {
private Menu mOptionsMenu;
private View mRefreshIndeterminateProgressView = null;
protected ActionBarHelperHoneycomb(Activity activity) {
super(activity);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
mOptionsMenu = menu;
return super.onCreateOptionsMenu(menu);
}
@Override
public void setRefreshActionItemState(boolean refreshing) {
// On Honeycomb, we can set the state of the refresh button by giving it a custom
// action view.
if (mOptionsMenu == null) {
return;
}
final MenuItem refreshItem = mOptionsMenu.findItem(R.id.menu_refresh);
if (refreshItem != null) {
if (refreshing) {
if (mRefreshIndeterminateProgressView == null) {
LayoutInflater inflater = (LayoutInflater)
getActionBarThemedContext().getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
mRefreshIndeterminateProgressView = inflater.inflate(
R.layout.actionbar_indeterminate_progress, null);
}
refreshItem.setActionView(mRefreshIndeterminateProgressView);
} else {
refreshItem.setActionView(null);
}
}
}
/**
* Returns a {@link Context} suitable for inflating layouts for the action bar. The
* implementation for this method in {@link ActionBarHelperICS} asks the action bar for a
* themed context.
*/
protected Context getActionBarThemedContext() {
return mActivity;
}
@Override
public void setDisplayHomeAsUpEnabled(boolean enabled) {
mActivity.getActionBar().setDisplayHomeAsUpEnabled(enabled);
}
@Override
public void hide() {
mActivity.getActionBar().hide();
}
}

View File

@ -0,0 +1,35 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import android.app.Activity;
import android.content.Context;
/**
* An extension of {@link com.example.android.actionbarcompat.ActionBarHelper} that provides Android
* 4.0-specific functionality for IceCreamSandwich devices. It thus requires API level 14.
*/
public class ActionBarHelperICS extends ActionBarHelperHoneycomb {
protected ActionBarHelperICS(Activity activity) {
super(activity);
}
@Override
protected Context getActionBarThemedContext() {
return mActivity.getActionBar().getThemedContext();
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (C) 2006 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import android.app.Activity;
import android.app.ListActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
public abstract class ActionBarListActivity extends ListActivity {
final ActionBarHelper mActionBarHelper = ActionBarHelper.createInstance(this);
/**
* Returns the {@link ActionBarHelper} for this activity.
*/
protected ActionBarHelper getActionBarHelper() {
return mActionBarHelper;
}
/**{@inheritDoc}*/
@Override
public MenuInflater getMenuInflater() {
return mActionBarHelper.getMenuInflater(super.getMenuInflater());
}
/**{@inheritDoc}*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActionBarHelper.onCreate(savedInstanceState);
}
/**{@inheritDoc}*/
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
mActionBarHelper.onPostCreate(savedInstanceState);
}
/**
* Base action bar-aware implementation for
* {@link Activity#onCreateOptionsMenu(android.view.Menu)}.
*
* Note: marking menu items as invisible/visible is not currently supported.
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
boolean retValue = false;
retValue |= mActionBarHelper.onCreateOptionsMenu(menu);
retValue |= super.onCreateOptionsMenu(menu);
return retValue;
}
/**{@inheritDoc}*/
@Override
protected void onTitleChanged(CharSequence title, int color) {
mActionBarHelper.onTitleChanged(title, color);
super.onTitleChanged(title, color);
}
}

View File

@ -0,0 +1,203 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import java.util.ArrayList;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
/**
* A <em>really</em> dumb implementation of the {@link android.view.Menu} interface, that's only
* useful for our actionbar-compat purposes. See
* <code>com.android.internal.view.menu.MenuBuilder</code> in AOSP for a more complete
* implementation.
*/
public class SimpleMenu implements Menu {
private Context mContext;
private Resources mResources;
private ArrayList<SimpleMenuItem> mItems;
public SimpleMenu(Context context) {
mContext = context;
mResources = context.getResources();
mItems = new ArrayList<SimpleMenuItem>();
}
public Context getContext() {
return mContext;
}
public Resources getResources() {
return mResources;
}
public MenuItem add(CharSequence title) {
return addInternal(0, 0, title);
}
public MenuItem add(int titleRes) {
return addInternal(0, 0, mResources.getString(titleRes));
}
public MenuItem add(int groupId, int itemId, int order, CharSequence title) {
return addInternal(itemId, order, title);
}
public MenuItem add(int groupId, int itemId, int order, int titleRes) {
return addInternal(itemId, order, mResources.getString(titleRes));
}
/**
* Adds an item to the menu. The other add methods funnel to this.
*/
private MenuItem addInternal(int itemId, int order, CharSequence title) {
final SimpleMenuItem item = new SimpleMenuItem(this, itemId, order, title);
mItems.add(findInsertIndex(mItems, order), item);
return item;
}
private static int findInsertIndex(ArrayList<? extends MenuItem> items, int order) {
for (int i = items.size() - 1; i >= 0; i--) {
MenuItem item = items.get(i);
if (item.getOrder() <= order) {
return i + 1;
}
}
return 0;
}
public int findItemIndex(int id) {
final int size = size();
for (int i = 0; i < size; i++) {
SimpleMenuItem item = mItems.get(i);
if (item.getItemId() == id) {
return i;
}
}
return -1;
}
public void removeItem(int itemId) {
removeItemAtInt(findItemIndex(itemId));
}
private void removeItemAtInt(int index) {
if ((index < 0) || (index >= mItems.size())) {
return;
}
mItems.remove(index);
}
public void clear() {
mItems.clear();
}
public MenuItem findItem(int id) {
final int size = size();
for (int i = 0; i < size; i++) {
SimpleMenuItem item = mItems.get(i);
if (item.getItemId() == id) {
return item;
}
}
return null;
}
public int size() {
return mItems.size();
}
public MenuItem getItem(int index) {
return mItems.get(index);
}
// Unsupported operations.
public SubMenu addSubMenu(CharSequence charSequence) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public SubMenu addSubMenu(int titleRes) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public SubMenu addSubMenu(int groupId, int itemId, int order, CharSequence title) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public SubMenu addSubMenu(int groupId, int itemId, int order, int titleRes) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public int addIntentOptions(int i, int i1, int i2, ComponentName componentName,
Intent[] intents, Intent intent, int i3, MenuItem[] menuItems) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public void removeGroup(int i) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public void setGroupCheckable(int i, boolean b, boolean b1) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public void setGroupVisible(int i, boolean b) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public void setGroupEnabled(int i, boolean b) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public boolean hasVisibleItems() {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public void close() {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public boolean performShortcut(int i, KeyEvent keyEvent, int i1) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public boolean isShortcutKey(int i, KeyEvent keyEvent) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public boolean performIdentifierAction(int i, int i1) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
public void setQwertyMode(boolean b) {
throw new UnsupportedOperationException("This operation is not supported for SimpleMenu");
}
}

View File

@ -0,0 +1,260 @@
/*
* Copyright 2011 The Android Open Source Project
*
* Licensed 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 net.sf.openrocket.android.actionbarcompat;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.view.ActionProvider;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.view.View;
/**
* A <em>really</em> dumb implementation of the {@link android.view.MenuItem} interface, that's only
* useful for our actionbar-compat purposes. See
* <code>com.android.internal.view.menu.MenuItemImpl</code> in AOSP for a more complete
* implementation.
*/
public class SimpleMenuItem implements MenuItem {
private SimpleMenu mMenu;
private final int mId;
private final int mOrder;
private CharSequence mTitle;
private CharSequence mTitleCondensed;
private Drawable mIconDrawable;
private int mIconResId = 0;
private boolean mEnabled = true;
public SimpleMenuItem(SimpleMenu menu, int id, int order, CharSequence title) {
mMenu = menu;
mId = id;
mOrder = order;
mTitle = title;
}
public int getItemId() {
return mId;
}
public int getOrder() {
return mOrder;
}
public MenuItem setTitle(CharSequence title) {
mTitle = title;
return this;
}
public MenuItem setTitle(int titleRes) {
return setTitle(mMenu.getContext().getString(titleRes));
}
public CharSequence getTitle() {
return mTitle;
}
public MenuItem setTitleCondensed(CharSequence title) {
mTitleCondensed = title;
return this;
}
public CharSequence getTitleCondensed() {
return mTitleCondensed != null ? mTitleCondensed : mTitle;
}
public MenuItem setIcon(Drawable icon) {
mIconResId = 0;
mIconDrawable = icon;
return this;
}
public MenuItem setIcon(int iconResId) {
mIconDrawable = null;
mIconResId = iconResId;
return this;
}
public Drawable getIcon() {
if (mIconDrawable != null) {
return mIconDrawable;
}
if (mIconResId != 0) {
return mMenu.getResources().getDrawable(mIconResId);
}
return null;
}
public MenuItem setEnabled(boolean enabled) {
mEnabled = enabled;
return this;
}
public boolean isEnabled() {
return mEnabled;
}
// No-op operations. We use no-ops to allow inflation from menu XML.
public int getGroupId() {
// Noop
return 0;
}
public View getActionView() {
// Noop
return null;
}
public MenuItem setActionProvider(ActionProvider actionProvider) {
// Noop
return this;
}
public ActionProvider getActionProvider() {
// Noop
return null;
}
public boolean expandActionView() {
// Noop
return false;
}
public boolean collapseActionView() {
// Noop
return false;
}
public boolean isActionViewExpanded() {
// Noop
return false;
}
public MenuItem setOnActionExpandListener(OnActionExpandListener onActionExpandListener) {
// Noop
return this;
}
public MenuItem setIntent(Intent intent) {
// Noop
return this;
}
public Intent getIntent() {
// Noop
return null;
}
public MenuItem setShortcut(char c, char c1) {
// Noop
return this;
}
public MenuItem setNumericShortcut(char c) {
// Noop
return this;
}
public char getNumericShortcut() {
// Noop
return 0;
}
public MenuItem setAlphabeticShortcut(char c) {
// Noop
return this;
}
public char getAlphabeticShortcut() {
// Noop
return 0;
}
public MenuItem setCheckable(boolean b) {
// Noop
return this;
}
public boolean isCheckable() {
// Noop
return false;
}
public MenuItem setChecked(boolean b) {
// Noop
return this;
}
public boolean isChecked() {
// Noop
return false;
}
public MenuItem setVisible(boolean b) {
// Noop
return this;
}
public boolean isVisible() {
// Noop
return true;
}
public boolean hasSubMenu() {
// Noop
return false;
}
public SubMenu getSubMenu() {
// Noop
return null;
}
public MenuItem setOnMenuItemClickListener(OnMenuItemClickListener onMenuItemClickListener) {
// Noop
return this;
}
public ContextMenu.ContextMenuInfo getMenuInfo() {
// Noop
return null;
}
public void setShowAsAction(int i) {
// Noop
}
public MenuItem setShowAsActionFlags(int i) {
// Noop
return null;
}
public MenuItem setActionView(View view) {
// Noop
return this;
}
public MenuItem setActionView(int i) {
// Noop
return this;
}
}

View File

@ -9,8 +9,8 @@ import java.util.Comparator;
import java.util.List;
import net.sf.openrocket.R;
import net.sf.openrocket.android.actionbarcompat.ActionBarListActivity;
import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
@ -19,14 +19,12 @@ import android.os.Environment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;
public class SimpleFileBrowser extends ListActivity {
public class SimpleFileBrowser extends ActionBarListActivity {
private List<String> item = null;
private List<String> path = null;
private String root = "/";
private TextView myPath;
private static final OrkFileFilter filter = new OrkFileFilter();
private static final Collator sorter = Collator.getInstance();
@ -40,7 +38,6 @@ public class SimpleFileBrowser extends ListActivity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simplefilebrowser);
myPath = (TextView) findViewById(R.id.path);
getDir( Environment.getExternalStorageDirectory().getAbsolutePath() );
}
@ -88,7 +85,7 @@ public class SimpleFileBrowser extends ListActivity {
}
private void getDir(String dirPath) {
myPath.setText("Location: " + dirPath);
setTitle(dirPath);
item = new ArrayList<String>();
path = new ArrayList<String>();

View File

@ -19,5 +19,5 @@ public class BurnPlotActivity extends FragmentActivity {
getSupportFragmentManager().beginTransaction().replace(android.R.id.content, burnPlot).commit();
}
}

View File

@ -8,6 +8,7 @@ import net.sf.openrocket.R;
import net.sf.openrocket.android.db.DbAdapter;
import net.sf.openrocket.android.util.AndroidLogWrapper;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.os.Bundle;
import android.support.v4.app.Fragment;
@ -48,25 +49,25 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
frag.setArguments(bundle);
return frag;
}
@Override
public void onCreate(Bundle savedInstanceState) {
AndroidLogWrapper.d(BurnPlotFragment.class,"onCreate");
if ( savedInstanceState!= null) {
motorId = savedInstanceState.getLong("motorId",-1);
} else {
Bundle b = getArguments();
motorId = b.getLong("motorId");
}
DbAdapter mDbHelper = new DbAdapter(getActivity());
mDbHelper.open();
try {
motor = mDbHelper.getMotorDao().fetchMotor(motorId);
} catch ( Exception e ) {
}
mDbHelper.close();
@ -98,22 +99,25 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
}
return l;
}
private void init( ExtendedThrustCurveMotor motor ) {
mySimpleXYPlot.setUserDomainOrigin(0);
mySimpleXYPlot.setUserRangeOrigin(0);
mySimpleXYPlot.setRangeLabel("impuse (n)");
mySimpleXYPlot.setDomainLabel("time (s)");
mySimpleXYPlot.addMarker(new YValueMarker(motor.getThrustCurveMotor().getAverageThrustEstimate(),"average" ));
YValueMarker average = new YValueMarker(motor.getThrustCurveMotor().getAverageThrustEstimate(),"average" );
average.getLinePaint().setColor(Color.BLACK);
average.getTextPaint().setColor(Color.BLACK);
mySimpleXYPlot.addMarker( average );
mySimpleXYPlot.disableAllMarkup();
try {
mySeries = new SimpleXYSeries(
fromArray(motor.getThrustCurveMotor().getTimePoints()),
fromArray(motor.getThrustCurveMotor().getThrustPoints()),
motor.getThrustCurveMotor().getDesignation());
fromArray(motor.getThrustCurveMotor().getThrustPoints()),
motor.getThrustCurveMotor().getManufacturer().getDisplayName() + " " + motor.getThrustCurveMotor().getDesignation()
);
} catch ( Exception ex ) {
Vector<Double> data = new Vector<Double>();
@ -124,8 +128,11 @@ public class BurnPlotFragment extends Fragment implements OnTouchListener {
mySeries = new SimpleXYSeries(data, SimpleXYSeries.ArrayFormat.XY_VALS_INTERLEAVED,"no data");
}
mySimpleXYPlot.addSeries(mySeries, LineAndPointRenderer.class,
new LineAndPointFormatter(Color.rgb(0, 255, 0), Color.rgb(200, 0, 0), null));
LineAndPointFormatter formatter= new LineAndPointFormatter(Color.RED, Color.GREEN, Color.GREEN);
formatter.getLinePaint().setShadowLayer(0, 0, 0, 0);
formatter.getVertexPaint().setShadowLayer(0, 0, 0, 0);
mySimpleXYPlot.addSeries(mySeries, LineAndPointRenderer.class,formatter);
//Set of internal variables for keeping track of the boundaries
mySimpleXYPlot.calculateMinMaxVals();

View File

@ -3,18 +3,18 @@ package net.sf.openrocket.android.motor;
import net.sf.openrocket.R;
import net.sf.openrocket.android.ActivityHelpers;
import net.sf.openrocket.android.PreferencesActivity;
import net.sf.openrocket.android.actionbarcompat.ActionBarFragmentActivity;
import net.sf.openrocket.android.util.AndroidLogWrapper;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
public class MotorBrowserActivity extends FragmentActivity
public class MotorBrowserActivity extends ActionBarFragmentActivity
implements MotorListFragment.OnMotorSelectedListener
{
@ -27,6 +27,7 @@ implements MotorListFragment.OnMotorSelectedListener
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.motorbrowser);
getActionBarHelper().setDisplayHomeAsUpEnabled(true);
getSupportFragmentManager().beginTransaction().add( R.id.motorBrowserList, new MotorListFragment()).commit();
}
@ -41,6 +42,9 @@ implements MotorListFragment.OnMotorSelectedListener
public boolean onMenuItemSelected(int featureId, MenuItem item) {
AndroidLogWrapper.d(MotorBrowserActivity.class,"onMenuItemSelected" + item.getItemId());
switch(item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.download_from_thrustcurve_menu_option:
ActivityHelpers.downloadFromThrustcurve(this,DOWNLOAD_REQUEST_CODE);
return true;

View File

@ -4,72 +4,45 @@ package net.sf.openrocket.android.rocket;
import net.sf.openrocket.R;
import net.sf.openrocket.android.ActivityHelpers;
import net.sf.openrocket.android.Application;
import net.sf.openrocket.android.actionbarcompat.ActionBarFragmentActivity;
import net.sf.openrocket.android.simulation.SimulationChart;
import net.sf.openrocket.android.simulation.SimulationFragment;
import net.sf.openrocket.android.simulation.SimulationViewActivity;
import net.sf.openrocket.android.util.AndroidLogWrapper;
import net.sf.openrocket.android.util.TabsAdapter;
import net.sf.openrocket.document.OpenRocketDocument;
import net.sf.openrocket.document.Simulation;
import net.sf.openrocket.rocketcomponent.Configuration;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.TabHost;
public class OpenRocketViewer extends FragmentActivity
public class OpenRocketViewer extends ActionBarFragmentActivity
implements Simulations.OnSimulationSelectedListener
{
OpenRocketDocument rocketDocument;
Configuration rocketConfiguration;
private Application app;
TabHost mTabHost;
ViewPager mViewPager;
TabsAdapter mTabsAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
app = (Application) this.getApplication();
setContentView(R.layout.openrocketviewer);
mTabHost = (TabHost)findViewById(android.R.id.tabhost);
mTabHost.setup();
mViewPager = (ViewPager)findViewById(R.id.pager);
mTabsAdapter = new TabsAdapter(this, mTabHost, mViewPager);
mTabsAdapter.addTab(mTabHost.newTabSpec("overview").setIndicator("Overview"),
Overview.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("components").setIndicator("Components"),
Component.class, null);
mTabsAdapter.addTab(mTabHost.newTabSpec("simulations").setIndicator("Simulations"),
Simulations.class, null);
if (savedInstanceState != null) {
mTabHost.setCurrentTabByTag(savedInstanceState.getString("tab"));
}
ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
viewPager.setAdapter( new OpenRocketViewerPager( this.getSupportFragmentManager()));
setTitle(app.getRocketDocument().getRocket().getName());
getActionBarHelper().setDisplayHomeAsUpEnabled(true);
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString("tab", mTabHost.getCurrentTabTag());
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
@ -81,6 +54,9 @@ implements Simulations.OnSimulationSelectedListener
public boolean onMenuItemSelected(int featureId, MenuItem item) {
AndroidLogWrapper.d(OpenRocketViewer.class,"onMenuItemSelected" + item.getItemId());
switch(item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.motor_list_menu_option:
ActivityHelpers.browseMotors(this);
return true;
@ -116,4 +92,39 @@ implements Simulations.OnSimulationSelectedListener
}
}
private class OpenRocketViewerPager extends FragmentPagerAdapter {
public OpenRocketViewerPager( FragmentManager fm ) {
super(fm);
}
@Override
public int getCount() {
return 3;
}
@Override
public Fragment getItem( int position ) {
switch (position) {
case 0:
return new Overview();
case 1:
return new Component();
case 2:
return new Simulations();
}
return null;
}
@Override
public CharSequence getPageTitle(int position) {
switch (position) {
case 0:
return "Overview";
case 1:
return "Components";
case 2:
return "Simulations";
}
return null;
}
}
}

View File

@ -1,140 +0,0 @@
package net.sf.openrocket.android.util;
import java.util.ArrayList;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost;
import android.widget.TabWidget;
//This class was copied from:
//http://developer.android.com/resources/samples/Support4Demos/src/com/example/android/supportv4/app/FragmentTabsPager.html
//With the following copyright & license.
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed 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.
*/
/**
* This is a helper class that implements the management of tabs and all
* details of connecting a ViewPager with associated TabHost. It relies on a
* trick. Normally a tab host has a simple API for supplying a View or
* Intent that each tab will show. This is not sufficient for switching
* between pages. So instead we make the content part of the tab host
* 0dp high (it is not shown) and the TabsAdapter supplies its own dummy
* view to show as the tab content. It listens to changes in tabs, and takes
* care of switch to the correct paged in the ViewPager whenever the selected
* tab changes.
*/
public class TabsAdapter extends FragmentPagerAdapter
implements TabHost.OnTabChangeListener, ViewPager.OnPageChangeListener {
private final Context mContext;
private final TabHost mTabHost;
private final ViewPager mViewPager;
private final ArrayList<TabInfo> mTabs = new ArrayList<TabInfo>();
static final class TabInfo {
private final String tag;
private final Class<?> clss;
private final Bundle args;
TabInfo(String _tag, Class<?> _class, Bundle _args) {
tag = _tag;
clss = _class;
args = _args;
}
}
static class DummyTabFactory implements TabHost.TabContentFactory {
private final Context mContext;
public DummyTabFactory(Context context) {
mContext = context;
}
@Override
public View createTabContent(String tag) {
View v = new View(mContext);
v.setMinimumWidth(0);
v.setMinimumHeight(0);
return v;
}
}
public TabsAdapter(FragmentActivity activity, TabHost tabHost, ViewPager pager) {
super(activity.getSupportFragmentManager());
mContext = activity;
mTabHost = tabHost;
mViewPager = pager;
mTabHost.setOnTabChangedListener(this);
mViewPager.setAdapter(this);
mViewPager.setOnPageChangeListener(this);
}
public void addTab(TabHost.TabSpec tabSpec, Class<?> clss, Bundle args) {
tabSpec.setContent(new DummyTabFactory(mContext));
String tag = tabSpec.getTag();
TabInfo info = new TabInfo(tag, clss, args);
mTabs.add(info);
mTabHost.addTab(tabSpec);
notifyDataSetChanged();
}
@Override
public int getCount() {
return mTabs.size();
}
@Override
public Fragment getItem(int position) {
TabInfo info = mTabs.get(position);
return Fragment.instantiate(mContext, info.clss.getName(), info.args);
}
@Override
public void onTabChanged(String tabId) {
int position = mTabHost.getCurrentTab();
mViewPager.setCurrentItem(position);
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageSelected(int position) {
// Unfortunately when TabHost changes the current tab, it kindly
// also takes care of putting focus on it when not in touch mode.
// The jerk.
// This hack tries to prevent this from pulling focus out of our
// ViewPager.
TabWidget widget = mTabHost.getTabWidget();
int oldFocusability = widget.getDescendantFocusability();
widget.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS);
mTabHost.setCurrentTab(position);
widget.setDescendantFocusability(oldFocusability);
}
@Override
public void onPageScrollStateChanged(int state) {
}
}