improve AppDetails

- App icon is now 72dp x 72dp
- Description is expandable
- License, categories, Website, Source Code, Issues and Donate (#232) are moved from header to summary
- Buttons to install, update and run are moved from action bar to header
- Permissions are expandable and always shown
- Add myself to copyright holders of "F-Droid/res/layout/app_details_header.xml", "F-Droid/res/layout/app_details_summary.xml" and
"F-Droid/src/org/fdroid/fdroid/AppDetails.java"
This commit is contained in:
Nico Alt 2015-06-02 22:33:53 +02:00 committed by Daniel Martí
parent ee6daf356b
commit a653b0156a
50 changed files with 699 additions and 320 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 648 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 976 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 280 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 662 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 741 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 571 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 420 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 311 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 324 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 886 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 617 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 501 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 562 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 476 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 667 B

View File

@ -1,97 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:tools="http://schemas.android.com/tools" xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/icon_and_title"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:paddingTop="2dp">
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/icon_and_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:baselineAligned="false"
android:orientation="horizontal"
android:padding="2dp">
<ImageView
android:id="@+id/icon"
android:contentDescription="@string/app_icon"
android:layout_width="56dp"
android:layout_height="56dp"
android:layout_centerVertical="true"
android:padding="4dp"
android:scaleType="fitCenter"
tools:src="@drawable/ic_launcher"
/>
android:id="@+id/icon"
android:layout_width="72dp"
android:layout_height="72dp"
android:layout_gravity="center_vertical"
android:contentDescription="@string/app_icon"
android:scaleType="fitCenter"
tools:src="@drawable/ic_launcher" />
<RelativeLayout
android:layout_width="fill_parent"
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:baselineAligned="false"
android:orientation="vertical"
android:paddingLeft="16dp"
android:paddingStart="16dp">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_toRightOf="@id/icon"
android:layout_toEndOf="@id/icon"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:gravity="start"
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="17sp"
android:textStyle="bold"
tools:text="F-Droid" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:baselineAligned="false"
android:paddingLeft="5dp"
android:paddingRight="5dp"
android:orientation="vertical"
>
android:orientation="horizontal">
<TextView
android:id="@+id/license"
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:singleLine="true"
android:ellipsize="end"
android:layout_marginLeft="6sp"
android:layout_marginStart="6sp"
android:textSize="12sp"
tools:text="GPLv3+"
/>
android:layout_gravity="center_vertical"
android:layout_marginBottom="3dp"
android:layout_weight="1"
android:baselineAligned="false"
android:orientation="vertical">
<TextView
android:id="@+id/title"
android:textSize="17sp"
android:textStyle="bold"
android:singleLine="true"
android:ellipsize="end"
<TextView
android:id="@+id/current_version"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:gravity="start"
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="13sp"
tools:text="1.24" />
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:ellipsize="end"
android:gravity="start"
android:singleLine="true"
android:textAlignment="viewStart"
android:textSize="13sp"
tools:text="Version 1.23 installed" />
</LinearLayout>
<Button
android:id="@+id/btn_main"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:gravity="start"
android:textAlignment="viewStart"
android:layout_toLeftOf="@id/license"
android:layout_toStartOf="@id/license"
tools:text="F-Droid"/>
android:layout_gravity="end"
android:layout_weight="0"
android:baselineAligned="false"
tools:text="Open" />
<TextView
android:id="@+id/categories"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_marginLeft="6sp"
android:layout_marginStart="6sp"
android:layout_below="@id/title"
android:textSize="12sp"
tools:text="System"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/status"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:ellipsize="end"
android:textSize="12sp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:gravity="start"
android:textAlignment="viewStart"
android:layout_toLeftOf="@id/categories"
android:layout_toStartOf="@id/categories"
android:layout_below="@id/title"
tools:text="Installed"/>
</RelativeLayout>
</RelativeLayout>

View File

@ -1,52 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<!--
Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="4dp"
android:paddingBottom="8dp"
android:paddingBottom="8dp"
android:paddingLeft="5dp"
android:paddingRight="5dp">
android:paddingRight="5dp"
android:paddingTop="4dp">
<TextView
android:id="@+id/summary"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Application manager"/>
android:id="@+id/summary"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textStyle="bold"
tools:text="Application manager" />
<TextView
android:id="@+id/appid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
<TextView
android:id="@+id/appid"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
tools:text="org.fdroid.fdroid" />
<TextView
android:id="@+id/signature"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:id="@+id/signature"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp" />
<TextView
android:id="@+id/antifeatures"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6sp"
android:textStyle="bold"
android:textColor="#ff0000"
<!-- android:visibility="gone" because not needed in app details imho (but maybe will get used in another place soon) -->
<TextView
android:id="@+id/categories"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="12sp"
android:visibility="gone"
tools:text="System" />
<TextView
android:id="@+id/antifeatures"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="6sp"
android:textColor="#ff0000"
android:textStyle="bold"
tools:text="Feeds you too much chocolate" />
<TextView
android:id="@+id/description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8sp"
android:textSize="13sp"
android:singleLine="false"
tools:text="Connects to F-Droid compatible repositories. The default repo is hosted at f-droid.org, which contains only bona fide FOSS.
<LinearLayout
android:id="@+id/ll_description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="@+id/description"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8sp"
android:singleLine="false"
android:textSize="13sp"
tools:text="Connects to F-Droid compatible repositories. The default repo is hosted at f-droid.org, which contains only bona fide FOSS.
Android is open in the sense that you are free to install apks from anywhere you wish, but there are many good reasons for using a client/repository setup:
@ -59,22 +91,171 @@ Android is open in the sense that you are free to install apks from anywhere you
Changelog" />
<TextView
android:id="@+id/permissions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8sp"
android:singleLine="true"
android:textStyle="bold"
tools:text="Permissions for version 1.0" />
<ImageView
android:id="@+id/view_more_description"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:contentDescription="@string/content_description_view_more"
android:src="@drawable/ic_expand_more_grey600"
tools:src="@drawable/ic_expand_more_grey600" />
<TextView
android:id="@+id/permissions_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="13sp"
android:singleLine="false"
tools:text=" * Full network access
</LinearLayout>
<LinearLayout
android:id="@+id/ll_information"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="@+id/information"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8sp"
android:drawableRight="@drawable/ic_expand_more_grey600"
android:drawablePadding="4dp"
android:drawableEnd="@drawable/ic_expand_more_grey600"
android:singleLine="true"
android:text="@string/links"
android:textStyle="bold"
tools:text="@string/links"
tools:drawableRight="@drawable/ic_expand_more_grey600"/>
<LinearLayout
android:id="@+id/ll_information_content"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:visibility="gone"
android:orientation="vertical">
<TextView
android:id="@+id/source"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_source_code"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_source_code"
android:gravity="center_vertical"
android:text="@string/menu_source"
tools:text="@string/menu_source" />
<TextView
android:id="@+id/issues"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_issues"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_issues"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_issues"
tools:text="@string/menu_issues" />
<TextView
android:id="@+id/website"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_website"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_website"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_website"
tools:text="@string/menu_website" />
<TextView
android:id="@+id/donate"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_donate"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_donate"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_donate"
tools:text="@string/menu_donate" />
<TextView
android:id="@+id/bitcoin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_bitcoin"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_bitcoin"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_bitcoin"
tools:text="@string/menu_bitcoin" />
<TextView
android:id="@+id/litecoin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_donate"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_donate"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_litecoin"
tools:text="@string/menu_litecoin" />
<TextView
android:id="@+id/dogecoin"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_donate"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_donate"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_dogecoin"
tools:text="@string/menu_dogecoin" />
<TextView
android:id="@+id/flattr"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:drawableLeft="@drawable/ic_flattr"
android:drawablePadding="4dp"
android:drawableStart="@drawable/ic_flattr"
android:gravity="center_vertical"
android:paddingTop="4dp"
android:text="@string/menu_flattr"
tools:text="@string/menu_flattr" />
</LinearLayout>
</LinearLayout>
<LinearLayout
android:id="@+id/ll_permissions"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:clickable="true"
android:orientation="vertical">
<TextView
android:id="@+id/permissions"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8sp"
android:drawablePadding="4dp"
android:drawableEnd="@drawable/ic_expand_more_grey600"
android:drawableRight="@drawable/ic_expand_more_grey600"
android:singleLine="true"
android:textStyle="bold"
tools:text="Permissions for version 1.0"
tools:drawableRight="@drawable/ic_expand_more_grey600"/>
<TextView
android:id="@+id/permissions_list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:singleLine="false"
android:textSize="13sp"
tools:text=" * Full network access
* View network connections
* View Wi-Fi connections
* Connect and disconnect from Wi-Fi
@ -87,4 +268,6 @@ Changelog" />
* Full permission to all device features and storage
* Test access to protected storage" />
</LinearLayout>
</LinearLayout>

View File

@ -67,6 +67,8 @@
<string name="no">No</string>
<string name="repo_add_title">Add new repository</string>
<string name="repo_add_add">Add</string>
<string name="links">Links</string>
<string name="content_description_view_more">View more</string>
<string name="cancel">Cancel</string>
<string name="enable">Enable</string>

View File

@ -24,9 +24,6 @@
android:key="language"
android:defaultValue=""
android:entryValues="@array/languageValues" />
<CheckBoxPreference android:title="@string/showPermissions"
android:defaultValue="false"
android:key="showPermissions"/>
<CheckBoxPreference android:title="@string/compactlayout"
android:defaultValue="false"
android:key="compactlayout"/>

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2010-12 Ciaran Gultnieks, ciaran@ciarang.com
* Copyright (C) 2013 Stefan Völkel, bd@bc-bd.org
* Copyright (C) 2015 Nico Alt, nicoalt@posteo.org
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -55,13 +56,14 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.SubMenu;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@ -306,18 +308,9 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
private static final int UNINSTALL = Menu.FIRST + 1;
private static final int IGNOREALL = Menu.FIRST + 2;
private static final int IGNORETHIS = Menu.FIRST + 3;
private static final int WEBSITE = Menu.FIRST + 4;
private static final int ISSUES = Menu.FIRST + 5;
private static final int SOURCE = Menu.FIRST + 6;
private static final int LAUNCH = Menu.FIRST + 7;
private static final int SHARE = Menu.FIRST + 8;
private static final int DONATE = Menu.FIRST + 9;
private static final int BITCOIN = Menu.FIRST + 10;
private static final int LITECOIN = Menu.FIRST + 11;
private static final int DOGECOIN = Menu.FIRST + 12;
private static final int FLATTR = Menu.FIRST + 13;
private static final int DONATE_URL = Menu.FIRST + 14;
private static final int SEND_VIA_BLUETOOTH = Menu.FIRST + 15;
private static final int LAUNCH = Menu.FIRST + 4;
private static final int SHARE = Menu.FIRST + 5;
private static final int SEND_VIA_BLUETOOTH = Menu.FIRST + 6;
private App app;
private PackageManager mPm;
@ -370,6 +363,10 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
fdroidApp = ((FDroidApp) getApplication());
fdroidApp.applyTheme(this);
/* TODO:
AppProvider.updateIconUrls(1.5);
*/
super.onCreate(savedInstanceState);
// Must be called *after* super.onCreate(), as that is where the action bar
@ -556,6 +553,9 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
}
inProcessOfChangingConfiguration = false;
/* TODO
AppProvider.updateIconUrls(1.0);
*/
super.onDestroy();
}
@ -632,48 +632,32 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
menu.clear();
if (app == null)
return true;
if (app.canAndWantToUpdate()) {
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, INSTALL, 0, R.string.menu_upgrade)
.setIcon(R.drawable.ic_menu_refresh),
MenuItemCompat.SHOW_AS_ACTION_ALWAYS |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
}
// Check count > 0 due to incompatible apps resulting in an empty list.
if (!app.isInstalled() && app.suggestedVercode > 0 &&
adapter.getCount() > 0) {
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, INSTALL, 1, R.string.menu_install)
.setIcon(android.R.drawable.ic_menu_add),
MenuItemCompat.SHOW_AS_ACTION_ALWAYS |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
} else if (app.isInstalled()) {
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, UNINSTALL, 1, R.string.menu_uninstall)
.setIcon(android.R.drawable.ic_menu_delete),
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
if (mPm.getLaunchIntentForPackage(app.id) != null) {
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, LAUNCH, 1, R.string.menu_launch)
.setIcon(android.R.drawable.ic_media_play),
MenuItemCompat.SHOW_AS_ACTION_ALWAYS |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
}
}
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, SHARE, 1, R.string.menu_share)
.setIcon(android.R.drawable.ic_menu_share),
Menu.NONE, SHARE, 1, R.string.menu_share)
.setIcon(android.R.drawable.ic_menu_share),
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
if (app.isInstalled()) {
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, UNINSTALL, 1, R.string.menu_uninstall)
.setIcon(android.R.drawable.ic_menu_delete),
MenuItemCompat.SHOW_AS_ACTION_IF_ROOM |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
}
if (mPm.getLaunchIntentForPackage(app.id) != null && app.canAndWantToUpdate()) {
MenuItemCompat.setShowAsAction(menu.add(
Menu.NONE, LAUNCH, 1, R.string.menu_launch)
.setIcon(android.R.drawable.ic_media_play),
MenuItemCompat.SHOW_AS_ACTION_ALWAYS |
MenuItemCompat.SHOW_AS_ACTION_WITH_TEXT);
}
menu.add(Menu.NONE, IGNOREALL, 2, R.string.menu_ignore_all)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
@ -682,44 +666,16 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
if (app.hasUpdates()) {
menu.add(Menu.NONE, IGNORETHIS, 2, R.string.menu_ignore_this)
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
.setCheckable(true)
.setChecked(app.ignoreThisUpdate >= app.suggestedVercode);
}
if (app.webURL.length() > 0) {
menu.add(Menu.NONE, WEBSITE, 3, R.string.menu_website).setIcon(
android.R.drawable.ic_menu_view);
}
if (app.trackerURL.length() > 0) {
menu.add(Menu.NONE, ISSUES, 4, R.string.menu_issues).setIcon(
android.R.drawable.ic_menu_view);
}
if (app.sourceURL.length() > 0) {
menu.add(Menu.NONE, SOURCE, 5, R.string.menu_source).setIcon(
android.R.drawable.ic_menu_view);
.setIcon(android.R.drawable.ic_menu_close_clear_cancel)
.setCheckable(true)
.setChecked(app.ignoreThisUpdate >= app.suggestedVercode);
}
if (app.bitcoinAddr != null || app.litecoinAddr != null ||
app.dogecoinAddr != null ||
app.flattrID != null || app.donateURL != null) {
SubMenu donate = menu.addSubMenu(Menu.NONE, DONATE, 7,
R.string.menu_donate).setIcon(
android.R.drawable.ic_menu_send);
if (app.bitcoinAddr != null)
donate.add(Menu.NONE, BITCOIN, 8, R.string.menu_bitcoin);
if (app.litecoinAddr != null)
donate.add(Menu.NONE, LITECOIN, 8, R.string.menu_litecoin);
if (app.dogecoinAddr != null)
donate.add(Menu.NONE, DOGECOIN, 8, R.string.menu_dogecoin);
if (app.flattrID != null)
donate.add(Menu.NONE, FLATTR, 9, R.string.menu_flattr);
if (app.donateURL != null)
donate.add(Menu.NONE, DONATE_URL, 10, R.string.menu_website);
// Ignore on devices without Bluetooth
if (app.isInstalled() && fdroidApp.bluetoothAdapter != null) {
menu.add(Menu.NONE, SEND_VIA_BLUETOOTH, 3, R.string.send_via_bluetooth)
.setIcon(android.R.drawable.stat_sys_data_bluetooth);
}
if (app.isInstalled() && fdroidApp.bluetoothAdapter != null) { // ignore on devices without Bluetooth
menu.add(Menu.NONE, SEND_VIA_BLUETOOTH, 6, R.string.send_via_bluetooth);
}
return true;
}
@ -837,38 +793,6 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
item.setChecked(app.ignoreThisUpdate > 0);
return true;
case WEBSITE:
tryOpenUri(app.webURL);
return true;
case ISSUES:
tryOpenUri(app.trackerURL);
return true;
case SOURCE:
tryOpenUri(app.sourceURL);
return true;
case BITCOIN:
tryOpenUri("bitcoin:" + app.bitcoinAddr);
return true;
case LITECOIN:
tryOpenUri("litecoin:" + app.litecoinAddr);
return true;
case DOGECOIN:
tryOpenUri("dogecoin:" + app.dogecoinAddr);
return true;
case FLATTR:
tryOpenUri("https://flattr.com/thing/" + app.flattrID);
return true;
case DONATE_URL:
tryOpenUri(app.donateURL);
return true;
case SEND_VIA_BLUETOOTH:
/*
* If Bluetooth has not been enabled/turned on, then
@ -1171,6 +1095,13 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
protected final Preferences prefs;
private AppDetailsData data;
private static final int MAX_LINES = 5;
private static boolean view_all_description;
private static boolean view_all_information;
private static boolean view_all_permissions;
private static LinearLayout ll_view_more_description;
private static LinearLayout ll_view_more_information;
private static LinearLayout ll_view_more_permissions;
public AppDetailsSummaryFragment() {
prefs = Preferences.get();
@ -1204,22 +1135,119 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
updateViews(getView());
}
private void setupView(View view) {
TextView description = (TextView) view.findViewById(R.id.description);
Spanned desc = Html.fromHtml(getApp().description, null, new Utils.HtmlTagHandler());
private void setupView(final View view) {
// Expandable description
final TextView description = (TextView) view.findViewById(R.id.description);
final Spanned desc = Html.fromHtml(getApp().description, null, new Utils.HtmlTagHandler());
description.setMovementMethod(SafeLinkMovementMethod.getInstance(getActivity()));
description.setText(desc.subSequence(0, desc.length() - 2));
final ImageView view_more_description = (ImageView) view.findViewById(R.id.view_more_description);
description.post(new Runnable() {
@Override
public void run() {
// If description has more than five lines
if (description.getLineCount() > MAX_LINES) {
description.setMaxLines(MAX_LINES);
description.setOnClickListener(expander_description);
view_all_description = true;
TextView appIdView = (TextView) view.findViewById(R.id.appid);
ll_view_more_description = (LinearLayout) view.findViewById(R.id.ll_description);
ll_view_more_description.setOnClickListener(expander_description);
view_more_description.setImageResource(R.drawable.ic_expand_more_grey600);
view_more_description.setOnClickListener(expander_description);
}
else {
view_more_description.setVisibility(View.GONE);
}
}
});
// App ID
final TextView appIdView = (TextView) view.findViewById(R.id.appid);
if (prefs.expertMode())
appIdView.setText(getApp().id);
else
appIdView.setVisibility(View.GONE);
TextView summaryView = (TextView) view.findViewById(R.id.summary);
// Expandable information
ll_view_more_information = (LinearLayout) view.findViewById(R.id.ll_information);
final TextView information = (TextView) view.findViewById(R.id.information);
final LinearLayout ll_view_more_information_content = (LinearLayout) view.findViewById(R.id.ll_information_content);
ll_view_more_information_content.setVisibility(View.GONE);
view_all_information = true;
information.setCompoundDrawablesWithIntrinsicBounds(null, null, getActivity().getResources().getDrawable(R.drawable.ic_expand_more_grey600), null);
ll_view_more_information.setOnClickListener(expander_information);
information.setOnClickListener(expander_information);
// Summary
final TextView summaryView = (TextView) view.findViewById(R.id.summary);
summaryView.setText(getApp().summary);
// Website button
TextView tv = (TextView) view.findViewById(R.id.website);
if (getApp().webURL != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Source button
tv = (TextView) view.findViewById(R.id.source);
if (getApp().sourceURL != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Issues button
tv = (TextView) view.findViewById(R.id.issues);
if (getApp().trackerURL != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Donate button
tv = (TextView) view.findViewById(R.id.donate);
if (getApp().donateURL != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Bitcoin
tv = (TextView) view.findViewById(R.id.bitcoin);
if (getApp().bitcoinAddr != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Litecoin
tv = (TextView) view.findViewById(R.id.litecoin);
if (getApp().litecoinAddr != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Dogecoin
tv = (TextView) view.findViewById(R.id.dogecoin);
if (getApp().dogecoinAddr != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Flattr
tv = (TextView) view.findViewById(R.id.flattr);
if (getApp().flattrID != null)
tv.setOnClickListener(mOnClickListener);
else
tv.setVisibility(View.GONE);
// Categories TextView
final TextView categories = (TextView) view.findViewById(R.id.categories);
if (prefs.expertMode() && getApp().categories != null)
categories.setText(getApp().categories.toString().replaceAll(",", ", "));
else
categories.setVisibility(View.GONE);
Apk curApk = null;
for (int i = 0; i < getApks().getCount(); i++) {
final Apk apk = getApks().getItem(i);
@ -1229,40 +1257,27 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
}
TextView permissionListView = (TextView) view.findViewById(R.id.permissions_list);
TextView permissionHeader = (TextView) view.findViewById(R.id.permissions);
boolean curApkCompatible = curApk != null && curApk.compatible;
if (prefs.showPermissions() && !getApks().isEmpty() &&
(curApkCompatible || prefs.showIncompatibleVersions())) {
// Expandable permissions
ll_view_more_permissions = (LinearLayout) view.findViewById(R.id.ll_permissions);
final TextView permissionHeader = (TextView) view.findViewById(R.id.permissions);
final TextView permissionListView = (TextView) view.findViewById(R.id.permissions_list);
permissionListView.setVisibility(View.GONE);
view_all_permissions = true;
CommaSeparatedList permsList = getApks().getItem(0).permissions;
if (permsList == null) {
permissionListView.setText(getString(R.string.no_permissions));
} else {
Iterator<String> permissions = permsList.iterator();
StringBuilder sb = new StringBuilder();
while (permissions.hasNext()) {
final String permissionName = permissions.next();
try {
Permission permission = new Permission(getActivity(), permissionName);
// TODO: Make this list RTL friendly
sb.append("\t• ").append(permission.getName()).append('\n');
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Ignoring unknown permission: " + permissionName);
}
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
permissionListView.setText(sb.toString());
}
final boolean curApkCompatible = curApk != null && curApk.compatible;
if (!getApks().isEmpty() && (curApkCompatible || prefs.showIncompatibleVersions())) {
permissionHeader.setText(getString(R.string.permissions_for_long, getApks().getItem(0).version));
permissionHeader.setCompoundDrawablesWithIntrinsicBounds(null, null, getActivity().getResources().getDrawable(R.drawable.ic_expand_more_grey600), null);
ll_view_more_permissions.setOnClickListener(expander_permissions);
permissionHeader.setOnClickListener(expander_permissions);
} else {
permissionListView.setVisibility(View.GONE);
permissionHeader.setVisibility(View.GONE);
permissionHeader.setCompoundDrawables(null, null, null, null);
}
TextView antiFeaturesView = (TextView) view.findViewById(R.id.antifeatures);
// Anti features
final TextView antiFeaturesView = (TextView) view.findViewById(R.id.antifeatures);
if (getApp().antiFeatures != null) {
StringBuilder sb = new StringBuilder();
for (final String af : getApp().antiFeatures) {
@ -1284,6 +1299,113 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
updateViews(view);
}
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
switch(v.getId()) {
case R.id.website:
((AppDetails) getActivity()).tryOpenUri(getApp().webURL);
break;
case R.id.source:
((AppDetails) getActivity()).tryOpenUri(getApp().sourceURL);
break;
case R.id.issues:
((AppDetails) getActivity()).tryOpenUri(getApp().trackerURL);
break;
case R.id.donate:
((AppDetails) getActivity()).tryOpenUri(getApp().donateURL);
break;
case R.id.bitcoin:
((AppDetails) getActivity()).tryOpenUri("bitcoin:" + getApp().bitcoinAddr);
break;
case R.id.litecoin:
((AppDetails) getActivity()).tryOpenUri("litecoin:" + getApp().litecoinAddr);
break;
case R.id.dogecoin:
((AppDetails) getActivity()).tryOpenUri("dogecoin:" + getApp().dogecoinAddr);
break;
case R.id.flattr:
((AppDetails) getActivity()).tryOpenUri("https://flattr.com/thing/" + getApp().flattrID);
break;
}
}
};
private View.OnClickListener expander_description = new View.OnClickListener() {
public void onClick(View v) {
final TextView description = (TextView) ll_view_more_description.findViewById(R.id.description);
final ImageView view_more_permissions = (ImageView) ll_view_more_description.findViewById(R.id.view_more_description);
if (!view_all_description) {
view_all_description = true;
description.setMaxLines(MAX_LINES);
view_more_permissions.setImageResource(R.drawable.ic_expand_more_grey600);
} else {
view_all_description = false;
description.setMaxLines(Integer.MAX_VALUE);
view_more_permissions.setImageResource(R.drawable.ic_expand_less_grey600);
}
}
};
private View.OnClickListener expander_information = new View.OnClickListener() {
public void onClick(View v) {
final TextView informationHeader = (TextView) ll_view_more_information.findViewById(R.id.information);
final LinearLayout information_content = (LinearLayout) ll_view_more_information.findViewById(R.id.ll_information_content);
if (!view_all_information) {
view_all_information = true;
information_content.setVisibility(View.GONE);
informationHeader.setCompoundDrawablesWithIntrinsicBounds(null, null, getActivity().getResources().getDrawable(R.drawable.ic_expand_more_grey600), null);
} else {
view_all_information = false;
information_content.setVisibility(View.VISIBLE);
informationHeader.setCompoundDrawablesWithIntrinsicBounds(null, null, getActivity().getResources().getDrawable(R.drawable.ic_expand_less_grey600), null);
}
}
};
private View.OnClickListener expander_permissions = new View.OnClickListener() {
public void onClick(View v) {
final TextView permissionHeader = (TextView) ll_view_more_permissions.findViewById(R.id.permissions);
final TextView permissionListView = (TextView) ll_view_more_permissions.findViewById(R.id.permissions_list);
if (!view_all_permissions) {
view_all_permissions = true;
permissionListView.setVisibility(View.GONE);
permissionHeader.setCompoundDrawablesWithIntrinsicBounds(null, null, getActivity().getResources().getDrawable(R.drawable.ic_expand_more_grey600), null);
} else {
view_all_permissions = false;
CommaSeparatedList permsList = getApks().getItem(0).permissions;
if (permsList == null) {
permissionListView.setText(getString(R.string.no_permissions));
} else {
Iterator<String> permissions = permsList.iterator();
StringBuilder sb = new StringBuilder();
while (permissions.hasNext()) {
final String permissionName = permissions.next();
try {
final Permission permission = new Permission(getActivity(), permissionName);
// TODO: Make this list RTL friendly
sb.append("\t• ").append(permission.getName()).append('\n');
} catch (PackageManager.NameNotFoundException e) {
Log.e(TAG, "Permission not yet available: " + permissionName);
}
}
if (sb.length() > 0) {
sb.setLength(sb.length() - 1);
}
permissionListView.setText(sb.toString());
}
permissionListView.setVisibility(View.VISIBLE);
permissionHeader.setCompoundDrawablesWithIntrinsicBounds(null, null, getActivity().getResources().getDrawable(R.drawable.ic_expand_less_grey600), null);
}
}
};
private String descAntiFeature(String af) {
switch (af) {
case "Ads":
@ -1324,6 +1446,8 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
private AppDetailsData data;
protected final DisplayImageOptions displayImageOptions;
public static boolean installed = false;
public static boolean updateWanted = false;
public AppDetailsHeaderFragment() {
displayImageOptions = new DisplayImageOptions.Builder()
@ -1359,16 +1483,9 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
ImageView iv = (ImageView) view.findViewById(R.id.icon);
ImageLoader.getInstance().displayImage(getApp().iconUrl, iv, displayImageOptions);
// Set the title and other header details...
// Set the title
TextView tv = (TextView) view.findViewById(R.id.title);
tv.setText(getApp().name);
tv = (TextView) view.findViewById(R.id.license);
tv.setText(getApp().license);
if (getApp().categories != null) {
tv = (TextView) view.findViewById(R.id.categories);
tv.setText(getApp().categories.toString().replaceAll(",", ", "));
}
updateViews(view);
}
@ -1384,18 +1501,78 @@ public class AppDetails extends ActionBarActivity implements ProgressListener, A
}
public void updateViews(View view) {
TextView statusView = (TextView) view.findViewById(R.id.status);
if (getApp().isInstalled()) {
statusView.setText(getString(R.string.details_installed, getApp().installedVersionName));
NfcHelper.setAndroidBeam(getActivity(), getApp().id);
} else {
Button btMain = (Button) view.findViewById(R.id.btn_main);
btMain.setVisibility(View.VISIBLE);
/*
Check count > 0 due to incompatible apps resulting in an empty list.
If App isn't installed
*/
if (!getApp().isInstalled() && getApp().suggestedVercode > 0 && ((AppDetails)getActivity()).adapter.getCount() > 0) {
installed = false;
statusView.setText(getString(R.string.details_notinstalled));
NfcHelper.disableAndroidBeam(getActivity());
// Set Install button and hide second button
btMain.setText(R.string.menu_install);
btMain.setOnClickListener(mOnClickListener);
}
// If App is installed
else if (getApp().isInstalled()) {
installed = true;
statusView.setText(getString(R.string.details_installed, getApp().installedVersionName));
NfcHelper.setAndroidBeam(getActivity(), getApp().id);
if (getApp().canAndWantToUpdate()) {
updateWanted = true;
btMain.setText(R.string.menu_upgrade);
}else {
updateWanted = false;
if (((AppDetails)getActivity()).mPm.getLaunchIntentForPackage(getApp().id) != null){
btMain.setText(R.string.menu_launch);
}
else {
btMain.setText(R.string.menu_uninstall);
}
}
btMain.setOnClickListener(mOnClickListener);
}
TextView currentVersion = (TextView) view.findViewById(R.id.current_version);
if (!getApks().isEmpty()) {
currentVersion.setText(getApks().getItem(0).version);
}else {
currentVersion.setVisibility(View.GONE);
btMain.setVisibility(View.GONE);
}
}
private View.OnClickListener mOnClickListener = new View.OnClickListener() {
public void onClick(View v) {
if (updateWanted) {
if (getApp().suggestedVercode > 0) {
final Apk apkToInstall = ApkProvider.Helper.find(getActivity(), getApp().id, getApp().suggestedVercode);
((AppDetails)getActivity()).install(apkToInstall);
return;
}
}
// If installed
if (installed) {
// If "launchable", launch
if (((AppDetails)getActivity()).mPm.getLaunchIntentForPackage(getApp().id) != null) {
((AppDetails)getActivity()).launchApk(getApp().id);
}
else {
((AppDetails)getActivity()).removeApk(getApp().id);
}
}
// If not installed, install
else if (getApp().suggestedVercode > 0) {
final Apk apkToInstall = ApkProvider.Helper.find(getActivity(), getApp().id, getApp().suggestedVercode);
((AppDetails)getActivity()).install(apkToInstall);
}
}
};
}
public static class AppDetailsListFragment extends ListFragment {

View File

@ -44,7 +44,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
public static final String PREF_ROOTED = "rooted";
public static final String PREF_INCOMP_VER = "incompatibleVersions";
public static final String PREF_THEME = "theme";
public static final String PREF_PERMISSIONS = "showPermissions";
public static final String PREF_COMPACT_LAYOUT = "compactlayout";
public static final String PREF_IGN_TOUCH = "ignoreTouchscreen";
public static final String PREF_CACHE_APK = "cacheDownloaded";
@ -122,10 +121,6 @@ public class Preferences implements SharedPreferences.OnSharedPreferenceChangeLi
return preferences.getBoolean(PREF_INCOMP_VER, DEFAULT_INCOMP_VER);
}
public boolean showPermissions() {
return preferences.getBoolean(PREF_PERMISSIONS, DEFAULT_PERMISSIONS);
}
public boolean showNfcDuringSwap() {
return preferences.getBoolean(PREF_SHOW_NFC_DURING_SWAP, DEFAULT_SHOW_NFC_DURING_SWAP);
}

View File

@ -79,23 +79,25 @@ public final class Utils {
private static final SimpleDateFormat LOG_DATE_FORMAT =
new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH);
public static String getIconsDir(Context context) {
DisplayMetrics metrics = context.getResources().getDisplayMetrics();
if (metrics.densityDpi >= 640) {
public static String getIconsDir(final Context context, final double dpiMultiplier) {
final DisplayMetrics metrics = context.getResources().getDisplayMetrics();
final double dpi = metrics.densityDpi * dpiMultiplier;
if (dpi >= 640) {
return "/icons-640/";
}
if (metrics.densityDpi >= 480) {
if (dpi >= 480) {
return "/icons-480/";
}
if (metrics.densityDpi >= 320) {
if (dpi >= 320) {
return "/icons-320/";
}
if (metrics.densityDpi >= 240) {
if (dpi >= 240) {
return "/icons-240/";
}
if (metrics.densityDpi >= 160) {
if (dpi >= 160) {
return "/icons-160/";
}
return "/icons-120/";
}

View File

@ -788,7 +788,7 @@ public class AppProvider extends FDroidProvider {
updateCompatibleFlags();
updateSuggestedFromLatest();
updateSuggestedFromUpstream();
updateIconUrls();
updateIconUrls(1.0);
}
/**
@ -920,10 +920,14 @@ public class AppProvider extends FDroidProvider {
write().execSQL(updateSql);
}
private void updateIconUrls() {
/**
* Updates URLs to icons
*
* @param dpiMultiplier Lets you grab icons for densities larger or smaller than that of your device by some fraction. Useful, for example, if you want to display a 48dp image at twice the size, 96dp, in which case you'd use a dpiMultiplier of 2.0 to get an image twice as big.
*/
public void updateIconUrls(final double dpiMultiplier) {
Log.d(TAG, "Updating icon paths for apps belonging to repos with version >= " + Repo.VERSION_DENSITY_SPECIFIC_ICONS);
final String iconsDir = Utils.getIconsDir(getContext());
final String iconsDir = Utils.getIconsDir(getContext(), dpiMultiplier);
Log.d(TAG, "Using icon dir '"+iconsDir+"'");
String repoVersion = Integer.toString(Repo.VERSION_DENSITY_SPECIFIC_ICONS);
String query = getIconUpdateQuery();

View File

@ -31,7 +31,6 @@ public class PreferencesFragment extends PreferenceFragment
Preferences.PREF_ROOTED,
Preferences.PREF_INCOMP_VER,
Preferences.PREF_THEME,
Preferences.PREF_PERMISSIONS,
Preferences.PREF_COMPACT_LAYOUT,
Preferences.PREF_IGN_TOUCH,
Preferences.PREF_LOCAL_REPO_BONJOUR,
@ -99,10 +98,6 @@ public class PreferencesFragment extends PreferenceFragment
textSummary(key, R.string.update_history_summ);
break;
case Preferences.PREF_PERMISSIONS:
checkSummary(key, R.string.showPermissions_on);
break;
case Preferences.PREF_COMPACT_LAYOUT:
checkSummary(key, R.string.compactlayout_on);
break;

View File

@ -133,3 +133,9 @@ will. Specifically you can redistribute and/or modify it under the terms of the
[GNU General Public License](https://www.gnu.org/licenses/gpl.html) as
published by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Some icons are made by [Picol](http://www.flaticon.com/authors/picol),
[Icomoon](http://www.flaticon.com/authors/icomoon) or
[Dave Gandy](http://www.flaticon.com/authors/dave-gandy) from
[Flaticon](http://www.flaticon.com) and are licensed by
[Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/).