implement navigation drawer

This commit is contained in:
Dominik Schürmann 2014-01-09 22:58:52 +01:00
parent 10715f7ace
commit bb161d5fa9
44 changed files with 723 additions and 1505 deletions

View File

@ -75,20 +75,15 @@
android:label="@string/app_name" android:label="@string/app_name"
android:theme="@style/Theme.Sherlock.Light" > android:theme="@style/Theme.Sherlock.Light" >
<activity <activity
android:name=".ui.MainActivity" android:name=".ui.KeyListPublicActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard" android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/app_name" > android:label="@string/app_name"
android:launchMode="singleTop" >
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity>
<activity
android:name=".ui.KeyListPublicActivity"
android:configChanges="orientation|screenSize|keyboardHidden|keyboard"
android:label="@string/title_manage_public_keys"
android:launchMode="singleTop" >
<!-- <intent-filter> --> <!-- <intent-filter> -->
<!-- <action android:name="android.intent.action.SEARCH" /> --> <!-- <action android:name="android.intent.action.SEARCH" /> -->

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -1,28 +0,0 @@
<!--
Copyright 2011 Google Inc.
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/dashboard_decrypt_pressed"
android:state_focused="true"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_decrypt_pressed"
android:state_focused="false"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_decrypt_pressed"
android:state_focused="true" />
<item android:drawable="@drawable/dashboard_decrypt_default"
android:state_focused="false"
android:state_pressed="false" />
</selector>

View File

@ -1,28 +0,0 @@
<!--
Copyright 2011 Google Inc.
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/dashboard_encrypt_pressed"
android:state_focused="true"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_encrypt_pressed"
android:state_focused="false"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_encrypt_pressed"
android:state_focused="true" />
<item android:drawable="@drawable/dashboard_encrypt_default"
android:state_focused="false"
android:state_pressed="false" />
</selector>

View File

@ -1,28 +0,0 @@
<!--
Copyright 2011 Google Inc.
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/dashboard_help_pressed"
android:state_focused="true"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_help_pressed"
android:state_focused="false"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_help_pressed"
android:state_focused="true" />
<item android:drawable="@drawable/dashboard_help_default"
android:state_focused="false"
android:state_pressed="false" />
</selector>

View File

@ -1,28 +0,0 @@
<!--
Copyright 2011 Google Inc.
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/dashboard_import_pressed"
android:state_focused="true"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_import_pressed"
android:state_focused="false"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_import_pressed"
android:state_focused="true" />
<item android:drawable="@drawable/dashboard_import_default"
android:state_focused="false"
android:state_pressed="false" />
</selector>

View File

@ -1,28 +0,0 @@
<!--
Copyright 2011 Google Inc.
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/dashboard_manage_keys_pressed"
android:state_focused="true"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_manage_keys_pressed"
android:state_focused="false"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_manage_keys_pressed"
android:state_focused="true" />
<item android:drawable="@drawable/dashboard_manage_keys_default"
android:state_focused="false"
android:state_pressed="false" />
</selector>

View File

@ -1,28 +0,0 @@
<!--
Copyright 2011 Google Inc.
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/dashboard_my_keys_pressed"
android:state_focused="true"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_my_keys_pressed"
android:state_focused="false"
android:state_pressed="true" />
<item android:drawable="@drawable/dashboard_my_keys_pressed"
android:state_focused="true" />
<item android:drawable="@drawable/dashboard_my_keys_default"
android:state_focused="false"
android:state_pressed="false" />
</selector>

View File

@ -1,12 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="match_parent" >
<fragment <FrameLayout
android:id="@+id/crypto_consumers_list_fragment"
android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent" >
</LinearLayout> <fragment
android:id="@+id/crypto_consumers_list_fragment"
android:name="org.sufficientlysecure.keychain.service.remote.RegisteredAppsListFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<include layout="@layout/drawer_list" />
</android.support.v4.widget.DrawerLayout>

View File

@ -1,185 +1,177 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
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"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" >
android:fillViewport="true"
android:orientation="vertical" >
<ScrollView <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:fillViewport="true" > android:fillViewport="true"
android:orientation="vertical" >
<LinearLayout <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" android:fillViewport="true" >
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<LinearLayout <LinearLayout
android:id="@+id/signature"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:clickable="true" android:orientation="vertical"
android:orientation="horizontal"
android:padding="4dp"
android:paddingLeft="10dp" android:paddingLeft="10dp"
android:paddingRight="10dp" > android:paddingRight="10dp" >
<RelativeLayout <LinearLayout
android:layout_width="wrap_content" android:id="@+id/signature"
android:layout_height="wrap_content" > android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="horizontal"
android:padding="4dp"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<ImageView <RelativeLayout
android:id="@+id/ic_signature" android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<ImageView
android:id="@+id/ic_signature"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/signed_large" />
<ImageView
android:id="@+id/ic_signature_status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/overlay_error" />
</RelativeLayout>
<LinearLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/signed_large" /> android:orientation="vertical"
android:paddingLeft="5dip" >
<ImageView <TextView
android:id="@+id/ic_signature_status" android:id="@+id/mainUserId"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:src="@drawable/overlay_error" /> android:layout_gravity="left"
</RelativeLayout> android:text="Main User Id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/mainUserIdRest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="left"
android:text="Main User Id Rest"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
<LinearLayout <LinearLayout
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal" >
android:paddingLeft="5dip" >
<TextView <ImageView
android:id="@+id/mainUserId" android:id="@+id/sourcePrevious"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left" android:src="@drawable/ic_previous" />
android:text="Main User Id"
<TextView
android:id="@+id/sourceLabel"
style="@style/SectionHeader"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|center_vertical"
android:text="@string/label_message"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView <ImageView
android:id="@+id/mainUserIdRest" android:id="@+id/sourceNext"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="left" android:src="@drawable/ic_next" />
android:text="Main User Id Rest"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout> </LinearLayout>
</LinearLayout>
<LinearLayout <ViewFlipper
android:layout_width="match_parent" android:id="@+id/source"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<ImageView
android:id="@+id/sourcePrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_previous" />
<TextView
android:id="@+id/sourceLabel"
style="@style/SectionHeader"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|center_vertical"
android:text="@string/label_message"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/sourceNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/source"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/sourceMessage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="0dip"
android:orientation="vertical" android:layout_weight="1" >
android:padding="4dp" >
<EditText <LinearLayout
android:id="@+id/message" android:id="@+id/sourceMessage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="top" android:orientation="vertical"
android:inputType="text|textCapSentences|textMultiLine|textLongMessage" android:padding="4dp" >
android:scrollHorizontally="true" />
</LinearLayout>
<LinearLayout
android:id="@+id/sourceFile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="4dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText <EditText
android:id="@+id/filename" android:id="@+id/message"
android:layout_width="0dip" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" android:gravity="top"
android:inputType="textNoSuggestions" /> android:inputType="text|textCapSentences|textMultiLine|textLongMessage"
android:scrollHorizontally="true" />
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/btn_browse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
bootstrapbutton:bb_icon_left="fa-folder-open"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/sourceFile"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="horizontal" > android:orientation="vertical"
android:padding="4dp" >
<CheckBox <LinearLayout
android:id="@+id/deleteAfterDecryption" android:layout_width="match_parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:orientation="horizontal" >
android:text="@string/label_delete_after_decryption" />
</LinearLayout>
</LinearLayout>
</ViewFlipper>
</LinearLayout>
</ScrollView>
</LinearLayout> <EditText
android:id="@+id/filename"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textNoSuggestions" />
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/btn_browse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
bootstrapbutton:bb_icon_left="fa-folder-open"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/deleteAfterDecryption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/label_delete_after_decryption" />
</LinearLayout>
</LinearLayout>
</ViewFlipper>
</LinearLayout>
</ScrollView>
</LinearLayout>
<include layout="@layout/drawer_list" />
</android.support.v4.widget.DrawerLayout>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
The drawer is given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view.
-->
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:choiceMode="singleChoice"
android:divider="@color/bg_gray"
android:dividerHeight="1dp" />

View File

@ -1,28 +1,31 @@
<!-- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
Copyright 2013 The Android Open Source Project xmlns:fontawesometext="http://schemas.android.com/apk/res-auto"
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.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:textAppearance="@android:style/TextAppearance.Medium" android:orientation="horizontal" >
android:gravity="center_vertical"
android:padding="16dp" <com.beardedhen.androidbootstrap.FontAwesomeText
android:textColor="#fff"/> android:id="@+id/drawer_item_icon"
<!-- android:layout_width="32dp"
android:layout_height="32dp"
android:layout_margin="10dp"
android:gravity="center_vertical"
android:textSize="24sp"
fontawesometext:fa_icon="fa-github" />
<TextView
android:id="@+id/drawer_item_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:paddingBottom="16dp"
android:paddingLeft="4dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:textAppearance="@android:style/TextAppearance.Medium"
android:textColor="#111" />
</LinearLayout><!--
<TextView xmlns:android="http://schemas.android.com/apk/res/android" <TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/text1" android:id="@android:id/text1"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -33,4 +36,5 @@
android:paddingRight="16dp" android:paddingRight="16dp"
android:textColor="#fff" android:textColor="#fff"
android:background="?android:attr/activatedBackgroundIndicator" android:background="?android:attr/activatedBackgroundIndicator"
android:minHeight="?android:attr/listPreferredItemHeightSmall"/> --> android:minHeight="?android:attr/listPreferredItemHeightSmall"/>
-->

View File

@ -1,315 +1,307 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
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.
-->
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" >
android:fillViewport="true" >
<LinearLayout <ScrollView
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="vertical" android:fillViewport="true" >
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:orientation="vertical"
android:padding="4dp" > android:paddingLeft="10dp"
android:paddingRight="10dp" >
<ImageView
android:id="@+id/modePrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_previous" />
<TextView
android:id="@+id/modeLabel"
style="@style/SectionHeader"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|center_vertical"
android:text="@string/label_asymmetric" />
<ImageView
android:id="@+id/modeNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/mode"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout <LinearLayout
android:id="@+id/modeAsymmetric"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal"
android:padding="4dp" > android:padding="4dp" >
<ImageView
android:id="@+id/modePrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_previous" />
<TextView
android:id="@+id/modeLabel"
style="@style/SectionHeader"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|center_vertical"
android:text="@string/label_asymmetric" />
<ImageView
android:id="@+id/modeNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/mode"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout <LinearLayout
android:id="@+id/modeAsymmetric"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" > android:orientation="vertical"
android:padding="4dp" >
<CheckBox
android:id="@+id/sign"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/label_sign" />
<LinearLayout <LinearLayout
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal" >
android:paddingLeft="16dp" >
<TextView <CheckBox
android:id="@+id/mainUserId" android:id="@+id/sign"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="right" android:layout_gravity="center_vertical"
android:ellipsize="end" android:text="@string/label_sign" />
android:singleLine="true"
android:text="Sign User Id" <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingLeft="16dp" >
<TextView
android:id="@+id/mainUserId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:ellipsize="end"
android:singleLine="true"
android:text="Sign User Id"
android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView
android:id="@+id/mainUserIdRest"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:ellipsize="end"
android:singleLine="true"
android:text="Sign email"
android:textAppearance="?android:attr/textAppearanceSmall" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:paddingBottom="3dip" >
<TextView
android:id="@+id/label_selectPublicKeys"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:text="@string/label_select_public_keys"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<TextView <com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/mainUserIdRest" android:id="@+id/btn_selectEncryptKeys"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="right" android:layout_gravity="center_vertical"
android:ellipsize="end" android:layout_margin="4dp"
android:singleLine="true" android:text="@string/btn_select_encrypt_keys"
android:text="Sign email" bootstrapbutton:bb_icon_left="fa-users"
android:textAppearance="?android:attr/textAppearanceSmall" /> bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout> </LinearLayout>
</LinearLayout> </LinearLayout>
<LinearLayout <TableLayout
android:id="@+id/modeSymmetric"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" android:padding="4dp"
android:paddingBottom="3dip" > android:stretchColumns="1" >
<TextView <TableRow>
android:id="@+id/label_selectPublicKeys"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:text="@string/label_select_public_keys"
android:textAppearance="?android:attr/textAppearanceMedium" />
<com.beardedhen.androidbootstrap.BootstrapButton <TextView
android:id="@+id/btn_selectEncryptKeys" android:id="@+id/label_passPhrase"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:layout_margin="4dp" android:paddingRight="10dip"
android:text="@string/btn_select_encrypt_keys" android:text="@string/label_passphrase"
bootstrapbutton:bb_icon_left="fa-key" android:textAppearance="?android:attr/textAppearanceMedium" />
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout>
</LinearLayout>
<TableLayout <EditText
android:id="@+id/modeSymmetric" android:id="@+id/passPhrase"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="4dp" android:inputType="textPassword" />
android:stretchColumns="1" > </TableRow>
<TableRow> <TableRow>
<TextView <TextView
android:id="@+id/label_passPhrase" android:id="@+id/label_passPhraseAgain"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:layout_gravity="center_vertical"
android:paddingRight="10dip" android:paddingRight="10dip"
android:text="@string/label_passphrase" android:text="@string/label_passphrase_again"
android:textAppearance="?android:attr/textAppearanceMedium" /> android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText <EditText
android:id="@+id/passPhrase" android:id="@+id/passPhraseAgain"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:inputType="textPassword" /> android:inputType="textPassword" />
</TableRow> </TableRow>
</TableLayout>
<TableRow> </ViewFlipper>
<TextView
android:id="@+id/label_passPhraseAgain"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingRight="10dip"
android:text="@string/label_passphrase_again"
android:textAppearance="?android:attr/textAppearanceMedium" />
<EditText
android:id="@+id/passPhraseAgain"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPassword" />
</TableRow>
</TableLayout>
</ViewFlipper>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="4dp" >
<ImageView
android:id="@+id/sourcePrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_previous" />
<TextView
android:id="@+id/sourceLabel"
style="@style/SectionHeader"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|center_vertical"
android:text="@string/label_message"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/sourceNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/source"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout <LinearLayout
android:id="@+id/sourceMessage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="wrap_content"
android:orientation="vertical" android:orientation="horizontal"
android:padding="4dp" > android:padding="4dp" >
<EditText <ImageView
android:id="@+id/message" android:id="@+id/sourcePrevious"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_previous" />
<TextView
android:id="@+id/sourceLabel"
style="@style/SectionHeader"
android:layout_width="0dip"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center_horizontal|center_vertical"
android:text="@string/label_message"
android:textAppearance="?android:attr/textAppearanceMedium" />
<ImageView
android:id="@+id/sourceNext"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ViewFlipper
android:id="@+id/source"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<LinearLayout
android:id="@+id/sourceMessage"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:gravity="top" android:orientation="vertical"
android:inputType="text|textCapSentences|textMultiLine|textLongMessage" /> android:padding="4dp" >
</LinearLayout>
<LinearLayout
android:id="@+id/sourceFile"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="4dp" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<EditText <EditText
android:id="@+id/filename" android:id="@+id/message"
android:layout_width="0dip" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:layout_weight="1" android:gravity="top"
android:inputType="textNoSuggestions" /> android:inputType="text|textCapSentences|textMultiLine|textLongMessage" />
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/btn_browse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
bootstrapbutton:bb_icon_left="fa-folder-open"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout> </LinearLayout>
<LinearLayout <LinearLayout
android:id="@+id/sourceFile"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="match_parent"
android:orientation="horizontal" > android:orientation="vertical"
android:padding="4dp" >
<TextView <LinearLayout
android:id="@+id/label_fileCompression" android:layout_width="match_parent"
android:layout_width="0dip"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" android:orientation="horizontal" >
android:layout_weight="1"
android:paddingRight="10dip"
android:text="@string/label_file_compression"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner <EditText
android:id="@+id/fileCompression" android:id="@+id/filename"
android:layout_width="wrap_content" android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
android:inputType="textNoSuggestions" />
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/btn_browse"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="4dp"
bootstrapbutton:bb_icon_left="fa-folder-open"
bootstrapbutton:bb_roundedCorners="true"
bootstrapbutton:bb_size="default"
bootstrapbutton:bb_type="default" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical" /> android:orientation="horizontal" >
<TextView
android:id="@+id/label_fileCompression"
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_weight="1"
android:paddingRight="10dip"
android:text="@string/label_file_compression"
android:textAppearance="?android:attr/textAppearanceSmall" />
<Spinner
android:id="@+id/fileCompression"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/deleteAfterEncryption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/label_delete_after_encryption" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/asciiArmour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/label_ascii_armor" />
</LinearLayout>
</LinearLayout> </LinearLayout>
</ViewFlipper>
</LinearLayout>
</ScrollView>
<LinearLayout <include layout="@layout/drawer_list" />
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox </android.support.v4.widget.DrawerLayout>
android:id="@+id/deleteAfterEncryption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/label_delete_after_encryption" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<CheckBox
android:id="@+id/asciiArmour"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/label_ascii_armor" />
</LinearLayout>
</LinearLayout>
</ViewFlipper>
</LinearLayout>
</ScrollView>

View File

@ -1,13 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:id="@+id/drawer_layout"
android:layout_height="fill_parent" android:layout_width="match_parent"
android:orientation="vertical" > android:layout_height="match_parent" >
<android.support.v4.view.ViewPager <LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/pager"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" /> android:layout_height="match_parent"
android:orientation="vertical" >
</LinearLayout> <android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
<include layout="@layout/drawer_list" />
</android.support.v4.widget.DrawerLayout>

View File

@ -1,55 +1,63 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto" xmlns:bootstrapbutton="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content" android:id="@+id/drawer_layout"
android:layout_height="wrap_content" android:layout_width="match_parent"
android:layout_centerHorizontal="true" > android:layout_height="match_parent" >
<FrameLayout <RelativeLayout
android:id="@+id/import_navigation_fragment" android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentTop="true" android:layout_centerHorizontal="true" >
android:orientation="vertical"
android:paddingLeft="4dp"
android:paddingRight="4dp" />
<LinearLayout <FrameLayout
android:id="@+id/import_footer" android:id="@+id/import_navigation_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="vertical"
android:paddingLeft="10dp"
android:paddingRight="10dp" >
<com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_import"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="wrap_content"
android:padding="4dp" android:layout_alignParentTop="true"
android:text="@string/import_import" android:orientation="vertical"
bootstrapbutton:bb_icon_left="fa-download" android:paddingLeft="4dp"
bootstrapbutton:bb_type="info" /> android:paddingRight="4dp" />
<com.beardedhen.androidbootstrap.BootstrapButton <LinearLayout
android:id="@+id/import_sign_and_upload" android:id="@+id/import_footer"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="60dp" android:layout_height="wrap_content"
android:padding="4dp" android:layout_alignParentBottom="true"
android:text="@string/import_sign_and_upload" android:orientation="vertical"
bootstrapbutton:bb_type="info" /> android:paddingLeft="10dp"
</LinearLayout> android:paddingRight="10dp" >
<FrameLayout <com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_keys_list_container" android:id="@+id/import_import"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="60dp"
android:layout_above="@+id/import_footer" android:padding="4dp"
android:layout_alignParentLeft="true" android:text="@string/import_import"
android:layout_below="@+id/import_navigation_fragment" bootstrapbutton:bb_icon_left="fa-download"
android:orientation="vertical" bootstrapbutton:bb_type="info" />
android:paddingLeft="4dp"
android:paddingRight="4dp" />
</RelativeLayout> <com.beardedhen.androidbootstrap.BootstrapButton
android:id="@+id/import_sign_and_upload"
android:layout_width="match_parent"
android:layout_height="60dp"
android:padding="4dp"
android:text="@string/import_sign_and_upload"
bootstrapbutton:bb_type="info" />
</LinearLayout>
<FrameLayout
android:id="@+id/import_keys_list_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/import_footer"
android:layout_alignParentLeft="true"
android:layout_below="@+id/import_navigation_fragment"
android:orientation="vertical"
android:paddingLeft="4dp"
android:paddingRight="4dp" />
</RelativeLayout>
<include layout="@layout/drawer_list" />
</android.support.v4.widget.DrawerLayout>

View File

@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout" android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
@ -16,23 +15,6 @@
android:layout_height="match_parent" /> android:layout_height="match_parent" />
</FrameLayout> </FrameLayout>
<!-- <include layout="@layout/drawer_list" />
android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
The drawer is given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view.
-->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#111"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp" />
</android.support.v4.widget.DrawerLayout> </android.support.v4.widget.DrawerLayout>

View File

@ -1,14 +1,20 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" <android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent" >
android:orientation="vertical" >
<fragment <FrameLayout
android:id="@+id/key_list_secret_fragment"
android:name="org.sufficientlysecure.keychain.ui.KeyListSecretFragment"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="0dip" android:layout_height="match_parent" >
android:layout_weight="1" />
</LinearLayout> <fragment
android:id="@+id/key_list_secret_fragment"
android:name="org.sufficientlysecure.keychain.ui.KeyListSecretFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
<include layout="@layout/drawer_list" />
</android.support.v4.widget.DrawerLayout>

View File

@ -1,70 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2010 Thialfihar <thi@thialfihar.org>
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:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<org.sufficientlysecure.keychain.ui.widget.DashboardLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<Button
android:id="@+id/dashboard_manage_keys"
style="@style/DashboardButton"
android:drawableTop="@drawable/dashboard_manage_keys"
android:onClick="manageKeysOnClick"
android:text="@string/dashboard_manage_keys" />
<Button
android:id="@+id/dashboard_my_keys"
style="@style/DashboardButton"
android:drawableTop="@drawable/dashboard_my_keys"
android:onClick="myKeysOnClick"
android:text="@string/dashboard_my_keys" />
<Button
android:id="@+id/dashboard_encrypt"
style="@style/DashboardButton"
android:drawableTop="@drawable/dashboard_encrypt"
android:onClick="encryptOnClick"
android:text="@string/dashboard_encrypt" />
<Button
android:id="@+id/dashboard_decrypt"
style="@style/DashboardButton"
android:drawableTop="@drawable/dashboard_decrypt"
android:onClick="decryptOnClick"
android:text="@string/dashboard_decrypt" />
<Button
android:id="@+id/dashboard_scan_qrcode"
style="@style/DashboardButton"
android:drawableTop="@drawable/dashboard_import"
android:onClick="scanQrcodeOnClick"
android:text="@string/dashboard_import_keys" />
<Button
android:id="@+id/dashboard_help"
style="@style/DashboardButton"
android:drawableTop="@drawable/dashboard_help"
android:onClick="helpOnClick"
android:text="@string/dashboard_help" />
</org.sufficientlysecure.keychain.ui.widget.DashboardLayout>
</LinearLayout>

View File

@ -370,17 +370,14 @@
<string name="key_view_action_encrypt">Encrypt to this contact</string> <string name="key_view_action_encrypt">Encrypt to this contact</string>
<!-- Navigation Drawer --> <!-- Navigation Drawer -->
<string-array name="drawer_array"> <string name="nav_contacts">Contacts</string>
<item>Contacts</item> <string name="nav_encrypt">Encrypt</string>
<item>Encrypt</item> <string name="nav_decrypt">Decrypt</string>
<item>Decrypt</item> <string name="nav_import">Import Keys</string>
<item>Import Keys</item> <string name="nav_secret_keys">My Keys</string>
<item>My Keys</item> <string name="nav_settings">Settings</string>
<item>Settings</item> <string name="nav_apps">Registered Apps</string>
<item>Registered Apps</item> <string name="nav_help">Help</string>
<item>Help</item>
</string-array>
<string name="drawer_open">Open navigation drawer</string> <string name="drawer_open">Open navigation drawer</string>
<string name="drawer_close">Close navigation drawer</string> <string name="drawer_close">Close navigation drawer</string>

View File

@ -18,44 +18,19 @@
package org.sufficientlysecure.keychain.service.remote; package org.sufficientlysecure.keychain.service.remote;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.ui.MainActivity; import org.sufficientlysecure.keychain.ui.DrawerActivity;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
public class RegisteredAppsListActivity extends SherlockFragmentActivity { public class RegisteredAppsListActivity extends DrawerActivity {
private ActionBar mActionBar;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
mActionBar = getSupportActionBar();
setContentView(R.layout.api_apps_list_activity); setContentView(R.layout.api_apps_list_activity);
mActionBar.setDisplayShowTitleEnabled(true); setupDrawerNavigation(savedInstanceState);
mActionBar.setDisplayHomeAsUpEnabled(true);
} }
/**
* Menu Options
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
} }

View File

@ -66,13 +66,12 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.ViewFlipper; import android.widget.ViewFlipper;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
@SuppressLint("NewApi") @SuppressLint("NewApi")
public class DecryptActivity extends SherlockFragmentActivity { public class DecryptActivity extends DrawerActivity {
/* Intents */ /* Intents */
// without permission // without permission
@ -144,13 +143,6 @@ public class DecryptActivity extends SherlockFragmentActivity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case Id.menu.option.decrypt: { case Id.menu.option.decrypt: {
decryptClicked(); decryptClicked();
@ -245,6 +237,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
initView(); initView();
setupDrawerNavigation(savedInstanceState);
// Handle intent actions // Handle intent actions
handleActions(getIntent()); handleActions(getIntent());
@ -262,7 +256,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
if (matcher.matches()) { if (matcher.matches()) {
data = matcher.group(1); data = matcher.group(1);
mMessage.setText(data); mMessage.setText(data);
Toast.makeText(this, R.string.using_clipboard_content, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.using_clipboard_content, Toast.LENGTH_SHORT)
.show();
} }
} }
} }
@ -472,8 +467,9 @@ public class DecryptActivity extends SherlockFragmentActivity {
if (!file.exists() || !file.isFile()) { if (!file.exists() || !file.isFile()) {
Toast.makeText( Toast.makeText(
this, this,
getString(R.string.error_message, getString(R.string.error_file_not_found)), getString(R.string.error_message,
Toast.LENGTH_SHORT).show(); getString(R.string.error_file_not_found)), Toast.LENGTH_SHORT)
.show();
return; return;
} }
} }
@ -592,7 +588,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
} }
mSecretKeyId = Id.key.symmetric; mSecretKeyId = Id.key.symmetric;
if (!PgpOperation.hasSymmetricEncryption(this, inStream)) { if (!PgpOperation.hasSymmetricEncryption(this, inStream)) {
throw new PgpGeneralException(getString(R.string.error_no_known_encryption_found)); throw new PgpGeneralException(
getString(R.string.error_no_known_encryption_found));
} }
mAssumeSymmetricEncryption = true; mAssumeSymmetricEncryption = true;
} }
@ -790,8 +787,8 @@ public class DecryptActivity extends SherlockFragmentActivity {
.getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) { .getBoolean(KeychainIntentService.RESULT_SIGNATURE_UNKNOWN)) {
mSignatureStatusImage.setImageResource(R.drawable.overlay_error); mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
Toast.makeText(DecryptActivity.this, Toast.makeText(DecryptActivity.this,
R.string.unknown_signature_key_touch_to_look_up, Toast.LENGTH_LONG) R.string.unknown_signature_key_touch_to_look_up,
.show(); Toast.LENGTH_LONG).show();
} else { } else {
mSignatureStatusImage.setImageResource(R.drawable.overlay_error); mSignatureStatusImage.setImageResource(R.drawable.overlay_error);
} }

View File

@ -1,26 +1,27 @@
/* /*
* Copyright (C) 2014 Dominik Schürmann <dominik@dominikschuermann.de>
* *
* from https://github.com/tobykurien/SherlockNavigationDrawer * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* *
* Copyright 2013 The Android Open Source Project * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * You should have received a copy of the GNU General Public License
* you may not use this file except in compliance with the License. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* 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 org.sufficientlysecure.keychain.ui; package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity;
import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
@ -30,45 +31,24 @@ import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout; import android.support.v4.widget.DrawerLayout;
import android.view.ActionProvider; import android.view.ActionProvider;
import android.view.ContextMenu.ContextMenuInfo; import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.SubMenu; import android.view.SubMenu;
import android.view.View; import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.ArrayAdapter; import android.widget.ArrayAdapter;
import android.widget.ListView; import android.widget.ListView;
import android.widget.TextView;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import com.beardedhen.androidbootstrap.FontAwesomeText;
/** /**
* This example illustrates a common usage of the DrawerLayout widget in the Android support * some fundamental ideas from https://github.com/tobykurien/SherlockNavigationDrawer
* library. *
* <p/> *
* <p>
* When a navigation (left) drawer is present, the host activity should detect presses of the action
* bar's Up affordance as a signal to open and close the navigation drawer. The
* ActionBarDrawerToggle facilitates this behavior. Items within the drawer should fall into one of
* two categories:
* </p>
* <p/>
* <ul>
* <li><strong>View switches</strong>. A view switch follows the same basic policies as list or tab
* navigation in that a view switch does not create navigation history. This pattern should only be
* used at the root activity of a task, leaving some form of Up navigation active for activities
* further down the navigation hierarchy.</li>
* <li><strong>Selective Up</strong>. The drawer allows the user to choose an alternate parent for
* Up navigation. This allows a user to jump across an app's navigation hierarchy at will. The
* application should treat this as it treats Up navigation from a different task, replacing the
* current task stack using TaskStackBuilder or similar. This is the only form of navigation drawer
* that should be used outside of the root activity of a task.</li>
* </ul>
* <p/>
* <p>
* Right side drawers should be used for actions, not navigation. This follows the pattern
* established by the Action Bar that navigation should be to the left and actions to the right. An
* action should be an operation performed on the current contents of the window, for example
* enabling or disabling a data overlay on top of the current content.
* </p>
*/ */
public class DrawerActivity extends SherlockFragmentActivity { public class DrawerActivity extends SherlockFragmentActivity {
private DrawerLayout mDrawerLayout; private DrawerLayout mDrawerLayout;
@ -77,11 +57,14 @@ public class DrawerActivity extends SherlockFragmentActivity {
private CharSequence mDrawerTitle; private CharSequence mDrawerTitle;
private CharSequence mTitle; private CharSequence mTitle;
private String[] mDrawerTitles;
private static Class[] mItemsClass = new Class[] { KeyListPublicActivity.class,
EncryptActivity.class, DecryptActivity.class, ImportKeysActivity.class,
KeyListSecretActivity.class, PreferencesActivity.class,
RegisteredAppsListActivity.class, HelpActivity.class };
protected void setupDrawerNavigation(Bundle savedInstanceState) { protected void setupDrawerNavigation(Bundle savedInstanceState) {
// mTitle = mDrawerTitle = getTitle(); mDrawerTitle = getString(R.string.app_name);
mDrawerTitles = getResources().getStringArray(R.array.drawer_array);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.left_drawer); mDrawerList = (ListView) findViewById(R.id.left_drawer);
@ -89,10 +72,31 @@ public class DrawerActivity extends SherlockFragmentActivity {
// opens // opens
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
// set up the drawer's list view with items and click listener // set up the drawer's list view with items and click listener
mDrawerList.setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, // mDrawerList
mDrawerTitles)); // .setAdapter(new ArrayAdapter<String>(this, R.layout.drawer_list_item, mItemsText));
NavItem mItemIconTexts[] = new NavItem[] {
new NavItem("fa-user", getString(R.string.nav_contacts)),
new NavItem("fa-lock", getString(R.string.nav_encrypt)),
new NavItem("fa-unlock", getString(R.string.nav_decrypt)),
new NavItem("fa-download", getString(R.string.nav_import)),
new NavItem("fa-key", getString(R.string.nav_secret_keys)),
new NavItem("fa-wrench", getString(R.string.nav_settings)),
new NavItem("fa-android", getString(R.string.nav_apps)),
new NavItem("fa-question", getString(R.string.nav_help)), };
mDrawerList.setAdapter(new NavigationDrawerAdapter(this, R.layout.drawer_list_item,
mItemIconTexts));
mDrawerList.setOnItemClickListener(new DrawerItemClickListener()); mDrawerList.setOnItemClickListener(new DrawerItemClickListener());
// <com.beardedhen.androidbootstrap.FontAwesomeText
// android:layout_width="wrap_content"
// android:layout_height="wrap_content"
// android:layout_margin="10dp"
// android:textSize="32sp"
// fontawesometext:fa_icon="fa-github" />
// enable ActionBar app icon to behave as action to toggle nav drawer // enable ActionBar app icon to behave as action to toggle nav drawer
getSupportActionBar().setDisplayHomeAsUpEnabled(true); getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true); getSupportActionBar().setHomeButtonEnabled(true);
@ -107,21 +111,22 @@ public class DrawerActivity extends SherlockFragmentActivity {
) { ) {
public void onDrawerClosed(View view) { public void onDrawerClosed(View view) {
getSupportActionBar().setTitle(mTitle); getSupportActionBar().setTitle(mTitle);
supportInvalidateOptionsMenu(); // creates call to // creates call to onPrepareOptionsMenu()
// onPrepareOptionsMenu() supportInvalidateOptionsMenu();
} }
public void onDrawerOpened(View drawerView) { public void onDrawerOpened(View drawerView) {
mTitle = getSupportActionBar().getTitle();
getSupportActionBar().setTitle(mDrawerTitle); getSupportActionBar().setTitle(mDrawerTitle);
supportInvalidateOptionsMenu(); // creates call to // creates call to onPrepareOptionsMenu()
// onPrepareOptionsMenu() supportInvalidateOptionsMenu();
} }
}; };
mDrawerLayout.setDrawerListener(mDrawerToggle); mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) { // if (savedInstanceState == null) {
selectItem(0); // selectItem(0);
} // }
} }
/* Called whenever we call invalidateOptionsMenu() */ /* Called whenever we call invalidateOptionsMenu() */
@ -142,8 +147,10 @@ public class DrawerActivity extends SherlockFragmentActivity {
return true; return true;
} }
return super.onOptionsItemSelected(item);
// Handle action buttons // Handle action buttons
switch (item.getItemId()) { // switch (item.getItemId()) {
// case R.id.action_websearch: // case R.id.action_websearch:
// // create intent to perform web search for this planet // // create intent to perform web search for this planet
// Intent intent = new Intent(Intent.ACTION_WEB_SEARCH); // Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
@ -155,9 +162,9 @@ public class DrawerActivity extends SherlockFragmentActivity {
// Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show(); // Toast.makeText(this, R.string.app_not_available, Toast.LENGTH_LONG).show();
// } // }
// return true; // return true;
default: // default:
return super.onOptionsItemSelected(item); // return super.onOptionsItemSelected(item);
} // }
} }
private android.view.MenuItem getMenuItem(final MenuItem item) { private android.view.MenuItem getMenuItem(final MenuItem item) {
@ -377,32 +384,24 @@ public class DrawerActivity extends SherlockFragmentActivity {
} }
private void selectItem(int position) { private void selectItem(int position) {
// update the main content by replacing fragments
// Fragment fragment = new PlanetFragment();
// Bundle args = new Bundle();
// args.putInt(PlanetFragment.ARG_PLANET_NUMBER, position);
// fragment.setArguments(args);
// FragmentManager fragmentManager = getSupportFragmentManager();
// fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
// update selected item and title, then close the drawer // update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true); mDrawerList.setItemChecked(position, true);
// setTitle(mDrawerTitles[position]); // setTitle(mDrawerTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList); mDrawerLayout.closeDrawer(mDrawerList);
}
// @Override finish();
// public void setTitle(CharSequence title) { overridePendingTransition(0, 0);
// mTitle = title;
// getSupportActionBar().setTitle(mTitle); Intent intent = new Intent(this, mItemsClass[position]);
// } startActivity(intent);
// disable animation of activity start
overridePendingTransition(0, 0);
}
/** /**
* When using the ActionBarDrawerToggle, you must call it during onPostCreate() and * When using the ActionBarDrawerToggle, you must call it during onPostCreate() and
* onConfigurationChanged()... * onConfigurationChanged()...
*/ */
@Override @Override
protected void onPostCreate(Bundle savedInstanceState) { protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState); super.onPostCreate(savedInstanceState);
@ -417,28 +416,59 @@ public class DrawerActivity extends SherlockFragmentActivity {
mDrawerToggle.onConfigurationChanged(newConfig); mDrawerToggle.onConfigurationChanged(newConfig);
} }
/** private class NavItem {
* Fragment that appears in the "content_frame", shows a planet public String icon;
*/ public String title;
// public static class PlanetFragment extends SherlockFragment {
// public static final String ARG_PLANET_NUMBER = "planet_number"; public NavItem(String icon, String title) {
// super();
// public PlanetFragment() { this.icon = icon;
// // Empty constructor required for fragment subclasses this.title = title;
// } }
// }
// @Override
// public View onCreateView(LayoutInflater inflater, ViewGroup container, private class NavigationDrawerAdapter extends ArrayAdapter<NavItem> {
// Bundle savedInstanceState) { Context context;
// View rootView = inflater.inflate(R.layout.fragment_planet, container, false); int layoutResourceId;
// int i = getArguments().getInt(ARG_PLANET_NUMBER); NavItem data[] = null;
// String planet = getResources().getStringArray(R.array.drawer_array)[i];
// public NavigationDrawerAdapter(Context context, int layoutResourceId, NavItem[] data) {
// int imageId = getResources().getIdentifier(planet.toLowerCase(Locale.getDefault()), super(context, layoutResourceId, data);
// "drawable", getActivity().getPackageName()); this.layoutResourceId = layoutResourceId;
// ((ImageView) rootView.findViewById(R.id.image)).setImageResource(imageId); this.context = context;
// getActivity().setTitle(planet); this.data = data;
// return rootView; }
// }
// } @Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = convertView;
NavItemHolder holder = null;
if (row == null) {
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new NavItemHolder();
holder.img = (FontAwesomeText) row.findViewById(R.id.drawer_item_icon);
holder.txtTitle = (TextView) row.findViewById(R.id.drawer_item_text);
row.setTag(holder);
} else {
holder = (NavItemHolder) row.getTag();
}
NavItem item = data[position];
holder.txtTitle.setText(item.title);
holder.img.setIcon(item.icon);
return row;
}
}
static class NavItemHolder {
FontAwesomeText img;
TextView txtTitle;
}
} }

View File

@ -63,12 +63,11 @@ import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import android.widget.ViewFlipper; import android.widget.ViewFlipper;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu; import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem; import com.actionbarsherlock.view.MenuItem;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
public class EncryptActivity extends SherlockFragmentActivity { public class EncryptActivity extends DrawerActivity {
/* Intents */ /* Intents */
public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT"; public static final String ACTION_ENCRYPT = Constants.INTENT_PREFIX + "ENCRYPT";
@ -153,13 +152,6 @@ public class EncryptActivity extends SherlockFragmentActivity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case Id.menu.option.encrypt_to_clipboard: case Id.menu.option.encrypt_to_clipboard:
encryptToClipboardClicked(); encryptToClipboardClicked();
@ -187,6 +179,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
initView(); initView();
setupDrawerNavigation(savedInstanceState);
// Handle intent actions // Handle intent actions
handleActions(getIntent()); handleActions(getIntent());
@ -491,8 +485,9 @@ public class EncryptActivity extends SherlockFragmentActivity {
if (!file.exists() || !file.isFile()) { if (!file.exists() || !file.isFile()) {
Toast.makeText( Toast.makeText(
this, this,
getString(R.string.error_message, getString(R.string.error_file_not_found)), getString(R.string.error_message,
Toast.LENGTH_SHORT).show(); getString(R.string.error_file_not_found)), Toast.LENGTH_SHORT)
.show();
return; return;
} }
} }
@ -510,7 +505,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
gotPassPhrase = (passPhrase.length() != 0); gotPassPhrase = (passPhrase.length() != 0);
if (!gotPassPhrase) { if (!gotPassPhrase) {
Toast.makeText(this, R.string.passphrase_must_not_be_empty, Toast.LENGTH_SHORT).show(); Toast.makeText(this, R.string.passphrase_must_not_be_empty, Toast.LENGTH_SHORT)
.show();
return; return;
} }
} else { } else {
@ -522,8 +518,8 @@ public class EncryptActivity extends SherlockFragmentActivity {
} }
if (!encryptIt && mSecretKeyId == 0) { if (!encryptIt && mSecretKeyId == 0) {
Toast.makeText(this, R.string.select_encryption_or_signature_key, Toast.LENGTH_SHORT) Toast.makeText(this, R.string.select_encryption_or_signature_key,
.show(); Toast.LENGTH_SHORT).show();
return; return;
} }
@ -852,10 +848,12 @@ public class EncryptActivity extends SherlockFragmentActivity {
Choice[] choices = new Choice[] { Choice[] choices = new Choice[] {
new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " (" new Choice(Id.choice.compression.none, getString(R.string.choice_none) + " ("
+ getString(R.string.compression_fast) + ")"), + getString(R.string.compression_fast) + ")"),
new Choice(Id.choice.compression.zip, "ZIP (" + getString(R.string.compression_fast) + ")"), new Choice(Id.choice.compression.zip, "ZIP ("
new Choice(Id.choice.compression.zlib, "ZLIB (" + getString(R.string.compression_fast) + ")"), + getString(R.string.compression_fast) + ")"),
new Choice(Id.choice.compression.bzip2, "BZIP2 (" + getString(R.string.compression_very_slow) new Choice(Id.choice.compression.zlib, "ZLIB ("
+ ")"), }; + getString(R.string.compression_fast) + ")"),
new Choice(Id.choice.compression.bzip2, "BZIP2 ("
+ getString(R.string.compression_very_slow) + ")"), };
ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(this, ArrayAdapter<Choice> adapter = new ArrayAdapter<Choice>(this,
android.R.layout.simple_spinner_item, choices); android.R.layout.simple_spinner_item, choices);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);

View File

@ -1,175 +0,0 @@
package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.util.Log;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import android.app.Activity;
import android.content.Intent;
import android.content.res.Configuration;
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.FragmentTransaction;
public class EncryptDecryptActivity extends SherlockFragmentActivity {
private FragmentActivity mActivity;
private ActionBar mActionBar;
private ActionBar.Tab mTab1;
private ActionBar.Tab mTab2;
private ActionBar.Tab mTab3;
// @Override
// public boolean onCreateOptionsMenu(Menu menu) {
// MenuInflater inflater = getSupportMenuInflater();
// inflater.inflate(R.menu.lists_activity, menu);
// return true;
// }
/**
* Menu item to go back home in ActionBar, other menu items are defined in Fragments
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(mActivity, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
// case R.id.menu_import:
// ImportExportHelper.openFileStream(mActivity);
// return true;
//
// case R.id.menu_export:
// ImportExportHelper.exportLists(mActivity);
// return true;
default:
return super.onOptionsItemSelected(item);
}
}
/**
* Set up Tabs on create
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mActivity = this;
setContentView(R.layout.lists_activity);
mActionBar = getSupportActionBar();
mActionBar.setDisplayShowTitleEnabled(true);
mActionBar.setDisplayHomeAsUpEnabled(true);
mActionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
mTab1 = getSupportActionBar().newTab();
mTab2 = getSupportActionBar().newTab();
mTab3 = getSupportActionBar().newTab();
mTab1.setTabListener(new TabListener<KeyListPublicFragment>(this, "publicList",
KeyListPublicFragment.class));
mTab2.setTabListener(new TabListener<KeyListPublicFragment>(this, "import",
KeyListPublicFragment.class));
setTabTextBasedOnOrientation(getResources().getConfiguration());
mActionBar.addTab(mTab1);
mActionBar.addTab(mTab2);
// mActionBar.addTab(mTab3);
}
private void setTabTextBasedOnOrientation(Configuration config) {
// longer names for landscape mode or tablets
// if (config.orientation == Configuration.ORIENTATION_LANDSCAPE
// || config.screenLayout == Configuration.SCREENLAYOUT_SIZE_XLARGE) {
mTab1.setText(getString(R.string.dashboard_manage_keys));
mTab2.setText(getString(R.string.dashboard_manage_keys));
// } else {
// mTab1.setText(getString(R.string.lists_tab_blacklist_short));
// mTab2.setText(getString(R.string.lists_tab_whitelist_short));
// mTab3.setText(getString(R.string.lists_tab_redirection_list_short));
// }
}
/**
* Change text on orientation change
*/
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
setTabTextBasedOnOrientation(newConfig);
}
public static class TabListener<T extends Fragment> implements ActionBar.TabListener {
private Fragment mFragment;
private final Activity mActivity;
private final String mTag;
private final Class<T> mClass;
/**
* Constructor used each time a new tab is created.
*
* @param activity
* The host Activity, used to instantiate the fragment
* @param tag
* The identifier tag for the fragment
* @param clz
* The fragment's Class, used to instantiate the fragment
*/
public TabListener(Activity activity, String tag, Class<T> clz) {
mActivity = activity;
mTag = tag;
mClass = clz;
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
/**
* Open Fragment based on selected Tab
*/
@Override
public void onTabSelected(Tab tab, FragmentTransaction ignoredFt) {
// bug in compatibility lib:
// http://stackoverflow.com/questions/8645549/null-fragmenttransaction-being-passed-to-tablistener-ontabselected
FragmentManager fragMgr = ((FragmentActivity) mActivity).getSupportFragmentManager();
FragmentTransaction ft = fragMgr.beginTransaction();
mFragment = Fragment.instantiate(mActivity, mClass.getName());
ft.replace(R.id.lists_tabs_container, mFragment, mTag);
ft.commit();
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ignoredFt) {
FragmentManager fragMgr = ((FragmentActivity) mActivity).getSupportFragmentManager();
FragmentTransaction ft = fragMgr.beginTransaction();
if (mFragment != null) {
// Remove the fragment
ft.remove(mFragment);
}
ft.commit();
}
}
}

View File

@ -17,27 +17,24 @@
package org.sufficientlysecure.keychain.ui; package org.sufficientlysecure.keychain.ui;
import java.util.ArrayList;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.app.FragmentTransaction; import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.ViewPager;
import android.widget.TextView; import android.widget.TextView;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.Tab; import com.actionbarsherlock.app.ActionBar.Tab;
import com.actionbarsherlock.view.MenuItem;
import java.util.ArrayList;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
public class HelpActivity extends SherlockFragmentActivity { public class HelpActivity extends DrawerActivity {
public static final String EXTRA_SELECTED_TAB = "selectedTab"; public static final String EXTRA_SELECTED_TAB = "selectedTab";
ViewPager mViewPager; ViewPager mViewPager;
@ -45,37 +42,18 @@ public class HelpActivity extends SherlockFragmentActivity {
TextView tabCenter; TextView tabCenter;
TextView tabText; TextView tabText;
/**
* Menu Items
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.help_activity); setContentView(R.layout.help_activity);
mViewPager = new ViewPager(this); mViewPager = (ViewPager) findViewById(R.id.pager);
mViewPager.setId(R.id.pager);
setupDrawerNavigation(savedInstanceState);
setContentView(mViewPager);
ActionBar bar = getSupportActionBar(); ActionBar bar = getSupportActionBar();
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowTitleEnabled(true);
bar.setDisplayHomeAsUpEnabled(true);
mTabsAdapter = new TabsAdapter(this, mViewPager); mTabsAdapter = new TabsAdapter(this, mViewPager);

View File

@ -22,7 +22,6 @@ import java.util.List;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.ActionBarHelper;
import org.sufficientlysecure.keychain.service.KeychainIntentService; import org.sufficientlysecure.keychain.service.KeychainIntentService;
import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler; import org.sufficientlysecure.keychain.service.KeychainIntentServiceHandler;
import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry; import org.sufficientlysecure.keychain.ui.adapter.ImportKeysListEntry;
@ -51,11 +50,9 @@ import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar; import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.ActionBar.OnNavigationListener; import com.actionbarsherlock.app.ActionBar.OnNavigationListener;
import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.MenuItem;
import com.beardedhen.androidbootstrap.BootstrapButton; import com.beardedhen.androidbootstrap.BootstrapButton;
public class ImportKeysActivity extends SherlockFragmentActivity implements OnNavigationListener { public class ImportKeysActivity extends DrawerActivity implements OnNavigationListener {
public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY"; public static final String ACTION_IMPORT_KEY = Constants.INTENT_PREFIX + "IMPORT_KEY";
public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX public static final String ACTION_IMPORT_KEY_FROM_QR_CODE = Constants.INTENT_PREFIX
+ "IMPORT_KEY_FROM_QR_CODE"; + "IMPORT_KEY_FROM_QR_CODE";
@ -103,8 +100,12 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
} }
}); });
getSupportActionBar().setDisplayShowTitleEnabled(false);
setupDrawerNavigation(savedInstanceState);
// set actionbar without home button if called from another app // set actionbar without home button if called from another app
ActionBarHelper.setBackButton(this); // ActionBarHelper.setBackButton(this);
// set drop down navigation // set drop down navigation
mNavigationStrings = getResources().getStringArray(R.array.import_action_list); mNavigationStrings = getResources().getStringArray(R.array.import_action_list);
@ -114,7 +115,6 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
list.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item); list.setDropDownViewResource(R.layout.sherlock_spinner_dropdown_item);
getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); getSupportActionBar().setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);
getSupportActionBar().setListNavigationCallbacks(list, this); getSupportActionBar().setListNavigationCallbacks(list, this);
getSupportActionBar().setDisplayShowTitleEnabled(false);
handleActions(savedInstanceState, getIntent()); handleActions(savedInstanceState, getIntent());
} }
@ -240,23 +240,6 @@ public class ImportKeysActivity extends SherlockFragmentActivity implements OnNa
mListFragment.loadNew(importData, importFilename); mListFragment.loadNew(importData, importFilename);
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// private void importAndSignOld(final long keyId, final String expectedFingerprint) { // private void importAndSignOld(final long keyId, final String expectedFingerprint) {
// if (expectedFingerprint != null && expectedFingerprint.length() > 0) { // if (expectedFingerprint != null && expectedFingerprint.length() > 0) {
// //

View File

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de> * Copyright (C) 2013-2014 Dominik Schürmann <dominik@dominikschuermann.de>
* *
* This program is free software: you can redistribute it and/or modify * This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
@ -37,8 +37,6 @@ import android.os.Message;
import android.os.Messenger; import android.os.Messenger;
import android.widget.Toast; import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity;
/** /**
* This implements export key method and delete key method. Used in lists and key view and key edit. * This implements export key method and delete key method. Used in lists and key view and key edit.
* *

View File

@ -50,8 +50,8 @@ public class KeyListPublicActivity extends KeyActivity {
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.menu_key_list_public_import: case R.id.menu_key_list_public_import:
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class); Intent intentImport = new Intent(this, ImportKeysActivity.class);
startActivityForResult(intentImportFromFile, Id.request.import_from_qr_code); startActivityForResult(intentImport, Id.request.import_from_qr_code);
return true; return true;
case R.id.menu_key_list_public_export: case R.id.menu_key_list_public_export:

View File

@ -35,8 +35,8 @@ public class KeyListSecretActivity extends KeyActivity {
setContentView(R.layout.key_list_secret_activity); setContentView(R.layout.key_list_secret_activity);
getSupportActionBar().setDisplayHomeAsUpEnabled(true); // now setup navigation drawer in DrawerActivity...
getSupportActionBar().setHomeButtonEnabled(true); setupDrawerNavigation(savedInstanceState);
} }
@Override @Override
@ -49,13 +49,6 @@ public class KeyListSecretActivity extends KeyActivity {
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case R.id.menu_key_list_secret_create: case R.id.menu_key_list_secret_create:
createKey(); createKey();
@ -70,8 +63,8 @@ public class KeyListSecretActivity extends KeyActivity {
return true; return true;
case R.id.menu_key_list_secret_import: case R.id.menu_key_list_secret_import:
Intent intentImportFromFile = new Intent(this, ImportKeysActivity.class); Intent intentImport = new Intent(this, ImportKeysActivity.class);
startActivityForResult(intentImportFromFile, Id.request.import_from_qr_code); startActivityForResult(intentImport, Id.request.import_from_qr_code);
return true; return true;
default: default:

View File

@ -1,109 +0,0 @@
/*
* Copyright (C) 2012-2013 Dominik Schürmann <dominik@dominikschuermann.de>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.sufficientlysecure.keychain.ui;
import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.service.remote.RegisteredAppsListActivity;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends SherlockActivity {
public void manageKeysOnClick(View view) {
// used instead of startActivity set actionbar based on callingPackage
startActivityForResult(new Intent(this, KeyListPublicActivity.class), 0);
}
public void myKeysOnClick(View view) {
// used instead of startActivity set actionbar based on callingPackage
startActivityForResult(new Intent(this, KeyListSecretActivity.class), 0);
}
public void encryptOnClick(View view) {
Intent intent = new Intent(MainActivity.this, EncryptActivity.class);
intent.setAction(EncryptActivity.ACTION_ENCRYPT);
// used instead of startActivity set actionbar based on callingPackage
startActivityForResult(intent, 0);
}
public void decryptOnClick(View view) {
Intent intent = new Intent(MainActivity.this, DecryptActivity.class);
intent.setAction(DecryptActivity.ACTION_DECRYPT);
// used instead of startActivity set actionbar based on callingPackage
startActivityForResult(intent, 0);
}
public void scanQrcodeOnClick(View view) {
Intent intent = new Intent(this, ImportKeysActivity.class);
startActivityForResult(intent, 0);
}
public void helpOnClick(View view) {
startActivity(new Intent(this, HelpActivity.class));
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final ActionBar actionBar = getSupportActionBar();
actionBar.setDisplayShowTitleEnabled(true);
actionBar.setDisplayHomeAsUpEnabled(false);
actionBar.setHomeButtonEnabled(false);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
menu.add(0, Id.menu.option.preferences, 0, R.string.menu_preferences)
.setIcon(R.drawable.ic_menu_settings)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
menu.add(0, Id.menu.option.crypto_consumers, 0, R.string.menu_api_app_settings)
.setIcon(R.drawable.ic_menu_settings)
.setShowAsAction(MenuItem.SHOW_AS_ACTION_WITH_TEXT);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case Id.menu.option.preferences:
startActivity(new Intent(this, PreferencesActivity.class));
return true;
case Id.menu.option.crypto_consumers:
startActivity(new Intent(this, RegisteredAppsListActivity.class));
return true;
default:
break;
}
return false;
}
}

View File

@ -20,13 +20,9 @@ import org.spongycastle.bcpg.HashAlgorithmTags;
import org.spongycastle.openpgp.PGPEncryptedData; import org.spongycastle.openpgp.PGPEncryptedData;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R;
import org.sufficientlysecure.keychain.helper.Preferences; import org.sufficientlysecure.keychain.helper.Preferences;
import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference; import org.sufficientlysecure.keychain.ui.widget.IntegerListPreference;
import org.sufficientlysecure.keychain.R;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
import com.actionbarsherlock.view.MenuItem;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
@ -34,6 +30,9 @@ import android.preference.CheckBoxPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceScreen; import android.preference.PreferenceScreen;
import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockPreferenceActivity;
public class PreferencesActivity extends SherlockPreferenceActivity { public class PreferencesActivity extends SherlockPreferenceActivity {
private IntegerListPreference mPassPhraseCacheTtl = null; private IntegerListPreference mPassPhraseCacheTtl = null;
private IntegerListPreference mEncryptionAlgorithm = null; private IntegerListPreference mEncryptionAlgorithm = null;
@ -220,21 +219,4 @@ public class PreferencesActivity extends SherlockPreferenceActivity {
} }
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
break;
}
return false;
}
} }

View File

@ -137,21 +137,4 @@ public class SelectSecretKeyActivity extends SherlockFragmentActivity {
return true; return true;
} }
/**
* Menu Options
*/
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// app icon in Action Bar clicked; go home
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
} }

View File

@ -1,186 +0,0 @@
/*
* Copyright 2011 Google Inc.
*
* 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 org.sufficientlysecure.keychain.ui.widget;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
/**
* Custom layout that arranges children in a grid-like manner, optimizing for even horizontal and
* vertical whitespace.
*/
public class DashboardLayout extends ViewGroup {
private static final int UNEVEN_GRID_PENALTY_MULTIPLIER = 10;
private int mMaxChildWidth = 0;
private int mMaxChildHeight = 0;
public DashboardLayout(Context context) {
super(context, null);
}
public DashboardLayout(Context context, AttributeSet attrs) {
super(context, attrs, 0);
}
public DashboardLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
mMaxChildWidth = 0;
mMaxChildHeight = 0;
// Measure once to find the maximum child size.
int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.AT_MOST);
int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
MeasureSpec.getSize(heightMeasureSpec), MeasureSpec.AT_MOST);
final int count = getChildCount();
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
mMaxChildWidth = Math.max(mMaxChildWidth, child.getMeasuredWidth());
mMaxChildHeight = Math.max(mMaxChildHeight, child.getMeasuredHeight());
}
// Measure again for each child to be exactly the same size.
childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildWidth, MeasureSpec.EXACTLY);
childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(mMaxChildHeight, MeasureSpec.EXACTLY);
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
}
setMeasuredDimension(resolveSize(mMaxChildWidth, widthMeasureSpec),
resolveSize(mMaxChildHeight, heightMeasureSpec));
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
int width = r - l;
int height = b - t;
final int count = getChildCount();
// Calculate the number of visible children.
int visibleCount = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
++visibleCount;
}
if (visibleCount == 0) {
return;
}
// Calculate what number of rows and columns will optimize for even horizontal and
// vertical whitespace between items. Start with a 1 x N grid, then try 2 x N, and so on.
int bestSpaceDifference = Integer.MAX_VALUE;
int spaceDifference;
// Horizontal and vertical space between items
int hSpace = 0;
int vSpace = 0;
int cols = 1;
int rows;
while (true) {
rows = (visibleCount - 1) / cols + 1;
hSpace = ((width - mMaxChildWidth * cols) / (cols + 1));
vSpace = ((height - mMaxChildHeight * rows) / (rows + 1));
spaceDifference = Math.abs(vSpace - hSpace);
if (rows * cols != visibleCount) {
spaceDifference *= UNEVEN_GRID_PENALTY_MULTIPLIER;
} else if (rows * mMaxChildHeight > height || cols * mMaxChildWidth > width) {
spaceDifference *= UNEVEN_GRID_PENALTY_MULTIPLIER;
}
if (spaceDifference < bestSpaceDifference) {
// Found a better whitespace squareness/ratio
bestSpaceDifference = spaceDifference;
// If we found a better whitespace squareness and there's only 1 row, this is
// the best we can do.
if (rows == 1) {
break;
}
} else {
// This is a worse whitespace ratio, use the previous value of cols and exit.
--cols;
rows = (visibleCount - 1) / cols + 1;
hSpace = ((width - mMaxChildWidth * cols) / (cols + 1));
vSpace = ((height - mMaxChildHeight * rows) / (rows + 1));
break;
}
++cols;
}
// Lay out children based on calculated best-fit number of rows and cols.
// If we chose a layout that has negative horizontal or vertical space, force it to zero.
hSpace = Math.max(0, hSpace);
vSpace = Math.max(0, vSpace);
// Re-use width/height variables to be child width/height.
width = (width - hSpace * (cols + 1)) / cols;
height = (height - vSpace * (rows + 1)) / rows;
int left, top;
int col, row;
int visibleIndex = 0;
for (int i = 0; i < count; i++) {
final View child = getChildAt(i);
if (child.getVisibility() == GONE) {
continue;
}
row = visibleIndex / cols;
col = visibleIndex % cols;
left = hSpace * (col + 1) + width * col;
top = vSpace * (row + 1) + height * row;
child.layout(left, top, (hSpace == 0 && col == cols - 1) ? r : (left + width),
(vSpace == 0 && row == rows - 1) ? b : (top + height));
++visibleIndex;
}
}
}