Browse Source

Use the Crouton library to display errors and success messages.

pull/11/head
Eric Kok 12 years ago
parent
commit
d335ff70df
  1. 1
      core/project.properties
  2. 2
      core/res/values/colors.xml
  3. 34
      core/src/org/transdroid/core/gui/DetailsActivity.java
  4. 48
      core/src/org/transdroid/core/gui/TorrentsActivity.java
  5. 17
      core/src/org/transdroid/core/gui/navigation/NavigationHelper.java
  6. 41
      external/Crouton/.gitignore
  7. 202
      external/Crouton/LICENSE
  8. 199
      external/Crouton/README.markdown
  9. 0
      external/Crouton/build.gradle
  10. 8
      external/Crouton/library/.classpath
  11. 33
      external/Crouton/library/.project
  12. 25
      external/Crouton/library/AndroidManifest.xml
  13. 92
      external/Crouton/library/build.xml
  14. 112
      external/Crouton/library/pom.xml
  15. 17
      external/Crouton/library/project.properties
  16. 825
      external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/Crouton.java
  17. 85
      external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/DefaultAnimationsBuilder.java
  18. 24
      external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/LifecycleCallback.java
  19. 403
      external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/Manager.java
  20. 539
      external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/Style.java
  21. 102
      external/Crouton/pom.xml

1
core/project.properties

@ -15,3 +15,4 @@ target=android-16
android.library.reference.1=../external/JakeWharton-ActionBarSherlock/library android.library.reference.1=../external/JakeWharton-ActionBarSherlock/library
android.library.reference.2=../external/ColorPickerPreference android.library.reference.2=../external/ColorPickerPreference
android.library=true android.library=true
android.library.reference.3=../external/Crouton/library

2
core/res/values/colors.xml

@ -2,4 +2,6 @@
<resources> <resources>
<color name="green">#8acc12</color> <color name="green">#8acc12</color>
<color name="ledgreen">#7dbb21</color> <color name="ledgreen">#7dbb21</color>
<color name="crouton_error">#c81113</color>
<color name="crouton_info">#aada62</color>
</resources> </resources>

34
core/src/org/transdroid/core/gui/DetailsActivity.java

@ -17,6 +17,8 @@ import org.transdroid.core.R;
import org.transdroid.core.app.settings.ApplicationSettings; import org.transdroid.core.app.settings.ApplicationSettings;
import org.transdroid.core.app.settings.ServerSetting; import org.transdroid.core.app.settings.ServerSetting;
import org.transdroid.core.gui.lists.LocalTorrent; import org.transdroid.core.gui.lists.LocalTorrent;
import org.transdroid.core.gui.log.Log;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.daemon.Daemon; import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.IDaemonAdapter; import org.transdroid.daemon.IDaemonAdapter;
import org.transdroid.daemon.Torrent; import org.transdroid.daemon.Torrent;
@ -43,12 +45,13 @@ import org.transdroid.daemon.task.StopTask;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Intent; import android.content.Intent;
import android.os.Build; import android.os.Build;
import android.widget.Toast;
import com.actionbarsherlock.app.SherlockFragmentActivity; import com.actionbarsherlock.app.SherlockFragmentActivity;
@EActivity(resName="activity_details") import de.keyboardsurfer.android.widget.crouton.Crouton;
@OptionsMenu(resName="activity_details")
@EActivity(resName = "activity_details")
@OptionsMenu(resName = "activity_details")
public class DetailsActivity extends SherlockFragmentActivity implements TorrentTasksExecutor { public class DetailsActivity extends SherlockFragmentActivity implements TorrentTasksExecutor {
@Extra @Extra
@ -57,11 +60,13 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
// Settings // Settings
@Bean @Bean
protected NavigationHelper navigationHelper;
@Bean
protected ApplicationSettings applicationSettings; protected ApplicationSettings applicationSettings;
private IDaemonAdapter currentConnection = null; private IDaemonAdapter currentConnection = null;
// Details view components // Details view components
@FragmentById(resName="torrent_details") @FragmentById(resName = "torrent_details")
protected DetailsFragment fragmentDetails; protected DetailsFragment fragmentDetails;
@AfterViews @AfterViews
@ -94,7 +99,7 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
TorrentsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start(); TorrentsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
} }
@OptionsItem(resName="action_refresh") @OptionsItem(resName = "action_refresh")
protected void refreshScreen() { protected void refreshScreen() {
refreshTorrent(); refreshTorrent();
refreshTorrentDetails(); refreshTorrentDetails();
@ -107,9 +112,10 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
DaemonTaskResult result = RetrieveTask.create(currentConnection).execute(); DaemonTaskResult result = RetrieveTask.create(currentConnection).execute();
fragmentDetails.updateIsLoading(false); fragmentDetails.updateIsLoading(false);
if (result instanceof RetrieveTaskSuccessResult) { if (result instanceof RetrieveTaskSuccessResult) {
onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(), ((RetrieveTaskSuccessResult) result).getLabels()); onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(),
((RetrieveTaskSuccessResult) result).getLabels());
} else { } else {
onCommunicationError((DaemonTaskFailureResult)result); onCommunicationError((DaemonTaskFailureResult) result);
} }
} }
@ -121,7 +127,7 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
if (result instanceof GetTorrentDetailsTaskSuccessResult) { if (result instanceof GetTorrentDetailsTaskSuccessResult) {
onTorrentDetailsRetrieved(((GetTorrentDetailsTaskSuccessResult) result).getTorrentDetails()); onTorrentDetailsRetrieved(((GetTorrentDetailsTaskSuccessResult) result).getTorrentDetails());
} else { } else {
onCommunicationError((DaemonTaskFailureResult)result); onCommunicationError((DaemonTaskFailureResult) result);
} }
} }
@ -133,7 +139,7 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
if (result instanceof GetFileListTaskSuccessResult) { if (result instanceof GetFileListTaskSuccessResult) {
onTorrentFilesRetrieved(((GetFileListTaskSuccessResult) result).getFiles()); onTorrentFilesRetrieved(((GetFileListTaskSuccessResult) result).getFiles());
} else { } else {
onCommunicationError((DaemonTaskFailureResult)result); onCommunicationError((DaemonTaskFailureResult) result);
} }
} }
@ -233,15 +239,15 @@ public class DetailsActivity extends SherlockFragmentActivity implements Torrent
@UiThread @UiThread
protected void onTaskSucceeded(DaemonTaskSuccessResult result, int successMessageId, String... messageParams) { protected void onTaskSucceeded(DaemonTaskSuccessResult result, int successMessageId, String... messageParams) {
// TODO: Properly report this success Crouton.showText(this, getString(successMessageId, (Object[]) messageParams),
Toast.makeText(this, getString(successMessageId, (Object[]) messageParams), Toast.LENGTH_LONG).show(); navigationHelper.CROUTON_INFO_STYLE);
} }
@UiThread @UiThread
protected void onCommunicationError(DaemonTaskFailureResult result) { protected void onCommunicationError(DaemonTaskFailureResult result) {
// TODO: Properly report this error Log.i(this, result.getException().toString());
Toast.makeText(this, getString(LocalTorrent.getResourceForDaemonException(result.getException())), Crouton.showText(this, getString(LocalTorrent.getResourceForDaemonException(result.getException())),
Toast.LENGTH_LONG).show(); navigationHelper.CROUTON_ERROR_STYLE);
} }
@UiThread @UiThread

48
core/src/org/transdroid/core/gui/TorrentsActivity.java

@ -21,7 +21,10 @@ import org.transdroid.core.gui.lists.LocalTorrent;
import org.transdroid.core.gui.lists.SimpleListItem; import org.transdroid.core.gui.lists.SimpleListItem;
import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.log.Log;
import org.transdroid.core.gui.navigation.*; import org.transdroid.core.gui.navigation.*;
import org.transdroid.core.gui.navigation.NavigationFilter;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.gui.navigation.NavigationSelectionView.NavigationFilterManager; import org.transdroid.core.gui.navigation.NavigationSelectionView.NavigationFilterManager;
import org.transdroid.core.gui.navigation.StatusType;
import org.transdroid.core.gui.settings.*; import org.transdroid.core.gui.settings.*;
import org.transdroid.daemon.Daemon; import org.transdroid.daemon.Daemon;
import org.transdroid.daemon.IDaemonAdapter; import org.transdroid.daemon.IDaemonAdapter;
@ -51,7 +54,6 @@ import android.os.Build;
import android.view.View; import android.view.View;
import android.widget.AdapterView; import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener; import android.widget.AdapterView.OnItemSelectedListener;
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;
@ -61,9 +63,12 @@ import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.SherlockListView; import com.actionbarsherlock.view.SherlockListView;
import com.actionbarsherlock.widget.SearchView; import com.actionbarsherlock.widget.SearchView;
@EActivity(resName="activity_torrents") import de.keyboardsurfer.android.widget.crouton.Crouton;
@OptionsMenu(resName="activity_torrents")
public class TorrentsActivity extends SherlockFragmentActivity implements OnNavigationListener, TorrentTasksExecutor, NavigationFilterManager { @EActivity(resName = "activity_torrents")
@OptionsMenu(resName = "activity_torrents")
public class TorrentsActivity extends SherlockFragmentActivity implements OnNavigationListener, TorrentTasksExecutor,
NavigationFilterManager {
// Navigation components // Navigation components
@Bean @Bean
@ -87,11 +92,11 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
protected boolean turleModeEnabled = false; protected boolean turleModeEnabled = false;
// Torrents list components // Torrents list components
@FragmentById(resName="torrent_list") @FragmentById(resName = "torrent_list")
protected TorrentsFragment fragmentTorrents; protected TorrentsFragment fragmentTorrents;
// Details view components // Details view components
@FragmentById(resName="torrent_details") @FragmentById(resName = "torrent_details")
protected DetailsFragment fragmentDetails; protected DetailsFragment fragmentDetails;
@AfterViews @AfterViews
@ -229,6 +234,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
filterSelected((SimpleListItem) filtersList.getAdapter().getItem(position)); filterSelected((SimpleListItem) filtersList.getAdapter().getItem(position));
} }
@Override @Override
public void onNothingSelected(AdapterView<?> parent) { public void onNothingSelected(AdapterView<?> parent) {
// TODO: Check if this happens // TODO: Check if this happens
@ -290,7 +296,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
*/ */
private void updateFragmentVisibility(boolean hasServerSettings) { private void updateFragmentVisibility(boolean hasServerSettings) {
if (filtersList != null) if (filtersList != null)
filtersList.setVisibility(hasServerSettings? View.VISIBLE: View.GONE); filtersList.setVisibility(hasServerSettings ? View.VISIBLE : View.GONE);
if (fragmentDetails != null) if (fragmentDetails != null)
getSupportFragmentManager().beginTransaction().hide(fragmentDetails).commit(); getSupportFragmentManager().beginTransaction().hide(fragmentDetails).commit();
} }
@ -302,28 +308,28 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
// TODO: Handle start intent // TODO: Handle start intent
} }
@OptionsItem(resName="action_refresh") @OptionsItem(resName = "action_refresh")
protected void refreshScreen() { protected void refreshScreen() {
refreshTorrents(); refreshTorrents();
getAdditionalStats(); getAdditionalStats();
} }
@OptionsItem(resName="action_enableturtle") @OptionsItem(resName = "action_enableturtle")
protected void enableTurtleMode() { protected void enableTurtleMode() {
updateTurtleMode(true); updateTurtleMode(true);
} }
@OptionsItem(resName="action_disableturtle") @OptionsItem(resName = "action_disableturtle")
protected void disableTurtleMode() { protected void disableTurtleMode() {
updateTurtleMode(false); updateTurtleMode(false);
} }
@OptionsItem(resName="action_settings") @OptionsItem(resName = "action_settings")
protected void openSettings() { protected void openSettings() {
MainSettingsActivity_.intent(this).start(); MainSettingsActivity_.intent(this).start();
} }
@OptionsItem(resName="action_help") @OptionsItem(resName = "action_help")
protected void openHelp() { protected void openHelp() {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.transdroid.org/download/"))); startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.transdroid.org/download/")));
} }
@ -342,9 +348,10 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
DaemonTaskResult result = RetrieveTask.create(currentConnection).execute(); DaemonTaskResult result = RetrieveTask.create(currentConnection).execute();
fragmentTorrents.updateIsLoading(false); fragmentTorrents.updateIsLoading(false);
if (result instanceof RetrieveTaskSuccessResult) { if (result instanceof RetrieveTaskSuccessResult) {
onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(), ((RetrieveTaskSuccessResult) result).getLabels()); onTorrentsRetrieved(((RetrieveTaskSuccessResult) result).getTorrents(),
((RetrieveTaskSuccessResult) result).getLabels());
} else { } else {
onCommunicationError((DaemonTaskFailureResult)result); onCommunicationError((DaemonTaskFailureResult) result);
} }
} }
@ -354,7 +361,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
if (result instanceof GetStatsTaskSuccessResult) { if (result instanceof GetStatsTaskSuccessResult) {
onTurtleModeRetrieved(((GetStatsTaskSuccessResult) result).isAlternativeModeEnabled()); onTurtleModeRetrieved(((GetStatsTaskSuccessResult) result).isAlternativeModeEnabled());
} else { } else {
onCommunicationError((DaemonTaskFailureResult)result); onCommunicationError((DaemonTaskFailureResult) result);
} }
} }
@ -365,7 +372,7 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
// Success; no need to retrieve it again - just update the visual indicator // Success; no need to retrieve it again - just update the visual indicator
onTurtleModeRetrieved(enable); onTurtleModeRetrieved(enable);
} else { } else {
onCommunicationError((DaemonTaskFailureResult)result); onCommunicationError((DaemonTaskFailureResult) result);
} }
} }
@ -465,16 +472,15 @@ public class TorrentsActivity extends SherlockFragmentActivity implements OnNavi
@UiThread @UiThread
protected void onTaskSucceeded(DaemonTaskSuccessResult result, int successMessageId, String... messageParams) { protected void onTaskSucceeded(DaemonTaskSuccessResult result, int successMessageId, String... messageParams) {
// TODO: Properly report this success Crouton.showText(this, getString(successMessageId, (Object[]) messageParams),
Toast.makeText(this, getString(successMessageId, (Object[]) messageParams), Toast.LENGTH_LONG).show(); navigationHelper.CROUTON_INFO_STYLE);
} }
@UiThread @UiThread
protected void onCommunicationError(DaemonTaskFailureResult result) { protected void onCommunicationError(DaemonTaskFailureResult result) {
Log.i(this, result.getException().toString()); Log.i(this, result.getException().toString());
// TODO: Properly report this error Crouton.showText(this, getString(LocalTorrent.getResourceForDaemonException(result.getException())),
Toast.makeText(this, getString(LocalTorrent.getResourceForDaemonException(result.getException())), navigationHelper.CROUTON_ERROR_STYLE);
Toast.LENGTH_LONG).show();
} }
@UiThread @UiThread

17
core/src/org/transdroid/core/gui/navigation/NavigationHelper.java

@ -4,18 +4,31 @@ import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext; import org.androidannotations.annotations.RootContext;
import org.transdroid.core.R; import org.transdroid.core.R;
import android.annotation.SuppressLint;
import android.annotation.TargetApi; import android.annotation.TargetApi;
import android.content.Context; import android.content.Context;
import android.content.pm.PackageInfo; import android.content.pm.PackageInfo;
import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Build; import android.os.Build;
import de.keyboardsurfer.android.widget.crouton.Style;
/**
* Helper for activities to make navigation-related decisions, such as when a device can display a larger, tablet style
* layout or how to display errors.
* @author Eric Kok
*/
@SuppressLint("ResourceAsColor")
@EBean @EBean
public class NavigationHelper { public class NavigationHelper {
@RootContext @RootContext
protected Context context; protected Context context;
public Style CROUTON_ERROR_STYLE = new Style.Builder().setBackgroundColor(R.color.crouton_error).setTextSize(13)
.build();
public Style CROUTON_INFO_STYLE = new Style.Builder().setBackgroundColor(R.color.crouton_info).setTextSize(13)
.build();
/** /**
* Whether any search-related UI components should be shown in the interface. At the moment returns false only if we * Whether any search-related UI components should be shown in the interface. At the moment returns false only if we
* run as Transdroid Lite version. * run as Transdroid Lite version.
@ -32,8 +45,8 @@ public class NavigationHelper {
} }
/** /**
* Returns whether the device is considered small (i.e. a phone) rather than large (i.e. a tablet). Can, for example, * Returns whether the device is considered small (i.e. a phone) rather than large (i.e. a tablet). Can, for
* be used to determine if a dialog should be shown full screen. Currently is true if the device's smallest * example, be used to determine if a dialog should be shown full screen. Currently is true if the device's smallest
* dimension is 500 dip. * dimension is 500 dip.
* @return True if the app runs on a small device, false otherwise * @return True if the app runs on a small device, false otherwise
*/ */

41
external/Crouton/.gitignore vendored

@ -0,0 +1,41 @@
# built application files
*.apk
*.ap_
*.jar
gen-external-apklibs
# keystore
*.keystore
# files for the dex VM
*.dex
# Java class files
*.class
# generated files
bin/
gen/
target/
# Local configuration file (sdk path, etc)
local.properties
# Eclipse project files
.classpath
.project
.metadata
.settings
# IntelliJ files
.idea
*.iml
# OSX files
.DS_Store
#vi swap files
*.swp
# maven target
target

202
external/Crouton/LICENSE vendored

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
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.

199
external/Crouton/README.markdown vendored

@ -0,0 +1,199 @@
# Crouton
![Crouton](https://raw.github.com/keyboardsurfer/Crouton/master/sample/res/drawable-xhdpi/ic_launcher.png "Crouton logo")
Context sensitive notifications for Android
## Overview
**Crouton** is a class that can be used by Android developers that feel the need for an **alternative to the Context insensitive [Toast](http://developer.android.com/reference/android/widget/Toast.html)**.
A Crouton will be displayed at the position the developer decides.
Standard will be the of an application window.
You can line up multiple Croutons for display, that will be shown one after another.
You can check some features in the Crouton Demo.
<a href="http://play.google.com/store/apps/details?id=de.keyboardsurfer.app.demo.crouton">
<img alt="Crouton Demo on Google Play"
src="http://developer.android.com/images/brand/en_generic_rgb_wo_60.png" />
</a>
If you're already using Crouton and just want to download the latest version of the library, follow [this link](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22de.keyboardsurfer.android.widget%22).
### Changelog
#### Current version: 1.7
####[1.7](https://github.com/keyboardsurfer/Crouton/tree/1.7)
- `Crouton.setOnClickListener(OnClickListener)` has been introduced.
- Infinite display of Crouton is possible via `Style.setDuration(Style.DURATION_INFINITE)`
- Via `Crouton.hide(Crouton)` a Crouton can be hidden.
####[1.6](https://github.com/keyboardsurfer/Crouton/tree/1.6)
- Crouton now can be used on any Android device with **API level 4+**.
- Changes the package name to `de.keyboardsurfer.android.widget`
- Adds possibility to set a custom width
- Can now be added to any ViewGroup (@coreform)
- Integration with TalkBack (@coreform)
- Adds Accessibility features (@coreform)
- Fixes bug that got Crouton out of sync with reality (@coreform)
- New [LifecycleCallback](https://github.com/keyboardsurfer/Crouton/blob/master/library/src/de/keyboardsurfer/android/widget/crouton/LifecycleCallback.java) (@coreform)
- initializeCroutonView was refactored, to make it easier on the eyes
- removes redundant initialization within Style.Builder
- documentation improvments
#### older versions
Please see the `git log`
## Usage
The API is kept as simple as the Toast API:
Create a Crouton for any CharSequence:
Crouton.makeText(Activity, CharSequence, [Style]).show();
Create a Crouton with a String from your application's resources:
Crouton.makeText(Activity, int, Style).show();
Further you can attach a Crouton to any view like this:
Crouton.makeText(Activity, int, Style, int).show();
If you would like a more graphical introduction to Crouton check out [this presentation](https://speakerdeck.com/keyboardsurfer/crouton-devfest-berlin-2012).
##Important!
In your Activity.onDestroy() make sure to call
Crouton.cancelAllCroutons();
to cancel cancel all scheduled Croutons.
This is a workaround and further description is available in #24.
## Basic Examples
Currently you can use the three different Style attributes displayed below out of the box:
![Alert](https://github.com/keyboardsurfer/Crouton/raw/master/res/Alert.png "Example of Style.ALERT")
![Confirm](https://github.com/keyboardsurfer/Crouton/raw/master/res/Confirm.png "Example of Style.CONFIRM")
![Info](https://github.com/keyboardsurfer/Crouton/raw/master/res/Info.png "Example of Style.INFO")
## Extension and Modification
The whole design of a Crouton is defined by [Style](https://github.com/keyboardsurfer/Crouton/blob/master/library/src/de/keyboardsurfer/android/widget/crouton/Style.java).
You can use one of the styles Crouton ships with: **Style.ALERT**, **Style.CONFIRM** and **Style.INFO**. Or you can create your own Style.
In general you can modify
- display duration
- dimension settings
- options for the text to display
- custom Views
- appearance & disappearance Animation
- displayed Image
Since [Style](https://github.com/keyboardsurfer/Crouton/blob/master/library/src/de/keyboardsurfer/android/widget/crouton/Style.java) is the general entry point for tweaking Croutons, go and see for yourself what can be done with it.
## Maven
### From maven central
Crouton is available in the maven central repository.
To use crouton simply add
```xml
<dependency>
<artifactId>crouton</artifactId>
<version>1.7</version>
<groupId>de.keyboardsurfer.android.widget</groupId>
</dependency>
```
to your pom.xml
If you also want the sources or javadoc add the respective classifier
```xml
<classifier>sources</classifier>
```
or
```xml
<classifier>javadoc</classifier>
```
to the dependency.
If you are referencing a newer version of the Android Support Library in your application, you might want to exclude Crouton's dependency like this:
```xml
<dependency>
<artifactId>crouton</artifactId>
<version>${crouton.version}</version>
<groupId>de.keyboardsurfer.android.widget</groupId>
<exclusions>
<exclusion>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
</exclusion>
</exclusions>
</dependency>
```
### DIY
The build requires Maven. Operations are very simple:
* `mvn -f library/pom.xml clean package` will build a `jar` library;
* `mvn clean package` will build a `jar` library and the sample application `apk`;
* `mvn -f library/pom.xml clean install` will put Crouton in your local Maven repository.
After putting Crouton in the repository you can add it as a dependency.
```xml
<dependency>
<artifactId>crouton</artifactId>
<version>1.6</version>
<groupId>de.keyboardsurfer.android.widget</groupId>
</dependency>
```
## Contribution
### Pull requests welcome
Feel free to contribute to Crouton.
Either you found a bug or have created a new and awesome feature, just create a pull request.
If you want to start to create a new feature or have any other questions regarding Crouton, [file an issue](https://github.com/keyboardsurfer/Crouton/issues/new).
I'll try to answer as soon as I find the time.
### Formatting
For contributors using Eclipse there's a formatter available at the [download section](https://github.com/downloads/keyboardsurfer/Crouton/Crouton_Eclipseformatter.xml).
In order to reduce merging pains on my end, please use this formatter or format your commit in a way similar to it's example.
If you're using IDEA, the Eclipse Formatter plugin should allow you to use the formatter as well.
## License
* [Apache Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
## Attributions
The initial version was written by <a href="https://plus.google.com/u/0/117509657298845443204?rel=author">Benjamin Weiss</a> at [Neofonie Mobile GmbH](http://mobile.neofonie.de).
The name and the idea of [Crouton](https://github.com/keyboardsurfer/Crouton/blob/master/library/src/de/keyboardsurfer/android/widget/crouton/Crouton.java) originates in a [blog article](http://android.cyrilmottier.com/?p=773) by Cyril Mottier.
The Crouton logo has been created by [Marie Schweiz](http://marie-schweiz.de).

0
external/Crouton/build.gradle vendored

8
external/Crouton/library/.classpath vendored

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>

33
external/Crouton/library/.project vendored

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Crouton</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

25
external/Crouton/library/AndroidManifest.xml vendored

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright 2012 Neofonie Mobile GmbH
~ Copyright 2012 - 2013 Benjamin Weiss
~
~ 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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.keyboardsurfer.mobile.app.android.widget.crouton"
android:versionCode="1"
android:versionName="1.7"
android:minSdkVersion="4">
</manifest>

92
external/Crouton/library/build.xml vendored

@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="library" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contains the path to the SDK. It should *NOT* be checked into
Version Control Systems. -->
<property file="local.properties" />
<!-- The ant.properties file can be created by you. It is only edited by the
'android' tool to add properties to it.
This is the place to change some Ant specific build properties.
Here are some properties you may want to change/update:
source.dir
The name of the source directory. Default is 'src'.
out.dir
The name of the output directory. Default is 'bin'.
For other overridable properties, look at the beginning of the rules
files in the SDK, at tools/ant/build.xml
Properties related to the SDK location or the project target should
be updated using the 'android' tool with the 'update' action.
This file is an integral part of the build system for your
application and should be checked into Version Control Systems.
-->
<property file="ant.properties" />
<!-- if sdk.dir was not set from one of the property file, then
get it from the ANDROID_HOME env var.
This must be done before we load project.properties since
the proguard config can use sdk.dir -->
<property environment="env" />
<condition property="sdk.dir" value="${env.ANDROID_HOME}">
<isset property="env.ANDROID_HOME" />
</condition>
<!-- The project.properties file is created and updated by the 'android'
tool, as well as ADT.
This contains project specific properties such as project target, and library
dependencies. Lower level build properties are stored in ant.properties
(or in .classpath for Eclipse projects).
This file is an integral part of the build system for your
application and should be checked into Version Control Systems. -->
<loadproperties srcFile="project.properties" />
<!-- quick check on sdk.dir -->
<fail
message="sdk.dir is missing. Make sure to generate local.properties using 'android update project' or to inject it through the ANDROID_HOME environment variable."
unless="sdk.dir"
/>
<!--
Import per project custom build rules if present at the root of the project.
This is the place to put custom intermediary targets such as:
-pre-build
-pre-compile
-post-compile (This is typically used for code obfuscation.
Compiled code location: ${out.classes.absolute.dir}
If this is not done in place, override ${out.dex.input.absolute.dir})
-post-package
-post-build
-pre-clean
-->
<import file="custom_rules.xml" optional="true" />
<!-- Import the actual build file.
To customize existing targets, there are two options:
- Customize only one target:
- copy/paste the target into this file, *before* the
<import> task.
- customize it to your needs.
- Customize the whole content of build.xml
- copy/paste the content of the rules files (minus the top node)
into this file, replacing the <import> task.
- customize to your needs.
***********************
****** IMPORTANT ******
***********************
In all cases you must update the value of version-tag below to read 'custom' instead of an integer,
in order to avoid having your file be overridden by tools such as "android update project"
-->
<!-- version-tag: 1 -->
<import file="${sdk.dir}/tools/ant/build.xml" />
</project>

112
external/Crouton/library/pom.xml vendored

@ -0,0 +1,112 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2012 - 2013 Benjamin Weiss
~ Copyright 2012 Neofonie Mobile GmbH
~
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Crouton</name>
<description>Context sensitive notifications for Android</description>
<url>https://github.com/keyboardsurfer/Crouton</url>
<artifactId>crouton</artifactId>
<groupId>de.keyboardsurfer.android.widget</groupId>
<version>1.7</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<android.version>4.1.1.4</android.version>
<android.version.platform>16</android.version.platform>
</properties>
<developers>
<developer>
<id>keyboardsurfer</id>
<name>Benjamin Weiss</name>
</developer>
</developers>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git@github.com:keyboardsurfer/Crouton.git</url>
<developerConnection>scm:git:git@github.com:keyboardsurfer/Crouton.git</developerConnection>
<connection>scm:git:git@github.com:keyboardsurfer/Crouton.git</connection>
</scm>
<dependencies>
<dependency>
<artifactId>android</artifactId>
<version>${android.version}</version>
<groupId>com.google.android</groupId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.android</groupId>
<artifactId>support-v4</artifactId>
<version>r11</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2.1</version>
<executions>
<execution>
<id>attach-sources</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.5.0</version>
</plugin>
</plugins>
</build>
</project>

17
external/Crouton/library/project.properties vendored

@ -0,0 +1,17 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system edit
# "ant.properties", and override values to adapt the script to your
# project structure.
#
# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home):
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
target=android-16
android.library=true
android.library.reference.1=../../JakeWharton-ActionBarSherlock/library

825
external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/Crouton.java vendored

@ -0,0 +1,825 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.util.TypedValue;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
/*
* Based on an article by Cyril Mottier (http://android.cyrilmottier.com/?p=773) <br>
*/
/**
* Displays information in a non-invasive context related manner. Like
* {@link android.widget.Toast}, but better.
* <p/>
* <b>Important: </b>
* Call {@link Crouton#clearCroutonsForActivity(Activity)} within
* {@link android.app.Activity#onDestroy()} to avoid {@link Context} leaks.
*/
public final class Crouton {
private static final int IMAGE_ID = 0x100;
private static final int TEXT_ID = 0x101;
private final CharSequence text;
private final Style style;
private final View customView;
private OnClickListener onClickListener;
private Activity activity;
private ViewGroup viewGroup;
private FrameLayout croutonView;
private Animation inAnimation;
private Animation outAnimation;
private LifecycleCallback lifecycleCallback = null;
/**
* Creates the {@link Crouton}.
*
* @param activity
* The {@link Activity} that the {@link Crouton} should be attached
* to.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
*/
private Crouton(Activity activity, CharSequence text, Style style) {
if ((activity == null) || (text == null) || (style == null)) {
throw new IllegalArgumentException("Null parameters are not accepted");
}
this.activity = activity;
this.viewGroup = null;
this.text = text;
this.style = style;
this.customView = null;
}
/**
* Creates the {@link Crouton}.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*/
private Crouton(Activity activity, CharSequence text, Style style, ViewGroup viewGroup) {
if ((activity == null) || (text == null) || (style == null)) {
throw new IllegalArgumentException("Null parameters are not accepted");
}
this.activity = activity;
this.text = text;
this.style = style;
this.viewGroup = viewGroup;
this.customView = null;
}
/**
* Creates the {@link Crouton}.
*
* @param activity
* The {@link Activity} that the {@link Crouton} should be attached
* to.
* @param customView
* The custom {@link View} to display
*/
private Crouton(Activity activity, View customView) {
if ((activity == null) || (customView == null)) {
throw new IllegalArgumentException("Null parameters are not accepted");
}
this.activity = activity;
this.viewGroup = null;
this.customView = customView;
this.style = new Style.Builder().build();
this.text = null;
}
/**
* Creates the {@link Crouton}.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param customView
* The custom {@link View} to display
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*/
private Crouton(Activity activity, View customView, ViewGroup viewGroup) {
if ((activity == null) || (customView == null)) {
throw new IllegalArgumentException("Null parameters are not accepted");
}
this.activity = activity;
this.customView = customView;
this.viewGroup = viewGroup;
this.style = new Style.Builder().build();
this.text = null;
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity.
*
* @param activity
* The {@link Activity} that the {@link Crouton} should be attached
* to.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
*
* @return The created {@link Crouton}.
*/
public static Crouton makeText(Activity activity, CharSequence text, Style style) {
return new Crouton(activity, text, style);
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*
* @return The created {@link Crouton}.
*/
public static Crouton makeText(Activity activity, CharSequence text, Style style, ViewGroup viewGroup) {
return new Crouton(activity, text, style, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text and style for a given
* activity.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroupResId
* The resource id of the {@link ViewGroup} that this {@link Crouton} should be added to.
*
* @return The created {@link Crouton}.
*/
public static Crouton makeText(Activity activity, CharSequence text, Style style, int viewGroupResId) {
return new Crouton(activity, text, style, (ViewGroup) activity.findViewById(viewGroupResId));
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity.
*
* @param activity
* The {@link Activity} that the {@link Crouton} should be attached
* to.
* @param textResourceId
* The resource id of the text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
*
* @return The created {@link Crouton}.
*/
public static Crouton makeText(Activity activity, int textResourceId, Style style) {
return makeText(activity, activity.getString(textResourceId), style);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param textResourceId
* The resource id of the text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*
* @return The created {@link Crouton}.
*/
public static Crouton makeText(Activity activity, int textResourceId, Style style, ViewGroup viewGroup) {
return makeText(activity, activity.getString(textResourceId), style, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param textResourceId
* The resource id of the text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroupResId
* The resource id of the {@link ViewGroup} that this {@link Crouton} should be added to.
*
* @return The created {@link Crouton}.
*/
public static Crouton makeText(Activity activity, int textResourceId, Style style, int viewGroupResId) {
return makeText(activity, activity.getString(textResourceId), style,
(ViewGroup) activity.findViewById(viewGroupResId));
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity.
*
* @param activity
* The {@link Activity} that the {@link Crouton} should be attached
* to.
* @param customView
* The custom {@link View} to display
*
* @return The created {@link Crouton}.
*/
public static Crouton make(Activity activity, View customView) {
return new Crouton(activity, customView);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param customView
* The custom {@link View} to display
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*
* @return The created {@link Crouton}.
*/
public static Crouton make(Activity activity, View customView, ViewGroup viewGroup) {
return new Crouton(activity, customView, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param customView
* The custom {@link View} to display
* @param viewGroupResId
* The resource id of the {@link ViewGroup} that this {@link Crouton} should be added to.
*
* @return The created {@link Crouton}.
*/
public static Crouton make(Activity activity, View customView, int viewGroupResId) {
return new Crouton(activity, customView, (ViewGroup) activity.findViewById(viewGroupResId));
}
/**
* Creates a {@link Crouton} with provided text and style for a given activity
* and displays it directly.
*
* @param activity
* The {@link android.app.Activity} that the {@link Crouton} should
* be attached to.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
*/
public static void showText(Activity activity, CharSequence text, Style style) {
makeText(activity, text, style).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given activity
* and displays it directly.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*/
public static void showText(Activity activity, CharSequence text, Style style, ViewGroup viewGroup) {
makeText(activity, text, style, viewGroup).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given activity
* and displays it directly.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param text
* The text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroupResId
* The resource id of the {@link ViewGroup} that this {@link Crouton} should be added to.
*/
public static void showText(Activity activity, CharSequence text, Style style, int viewGroupResId) {
makeText(activity, text, style, (ViewGroup) activity.findViewById(viewGroupResId)).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given activity
* and displays it directly.
*
* @param activity
* The {@link android.app.Activity} that the {@link Crouton} should
* be attached to.
* @param customView
* The custom {@link View} to display
*/
public static void show(Activity activity, View customView) {
make(activity, customView).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given activity
* and displays it directly.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param customView
* The custom {@link View} to display
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*/
public static void show(Activity activity, View customView, ViewGroup viewGroup) {
make(activity, customView, viewGroup).show();
}
/**
* Creates a {@link Crouton} with provided text and style for a given activity
* and displays it directly.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param customView
* The custom {@link View} to display
* @param viewGroupResId
* The resource id of the {@link ViewGroup} that this {@link Crouton} should be added to.
*/
public static void show(Activity activity, View customView, int viewGroupResId) {
make(activity, customView, viewGroupResId).show();
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity and displays it directly.
*
* @param activity
* The {@link Activity} that the {@link Crouton} should be attached
* to.
* @param textResourceId
* The resource id of the text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
*/
public static void showText(Activity activity, int textResourceId, Style style) {
showText(activity, activity.getString(textResourceId), style);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity and displays it directly.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param textResourceId
* The resource id of the text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroup
* The {@link ViewGroup} that this {@link Crouton} should be added to.
*/
public static void showText(Activity activity, int textResourceId, Style style, ViewGroup viewGroup) {
showText(activity, activity.getString(textResourceId), style, viewGroup);
}
/**
* Creates a {@link Crouton} with provided text-resource and style for a given
* activity and displays it directly.
*
* @param activity
* The {@link Activity} that represents the context in which the Crouton should exist.
* @param textResourceId
* The resource id of the text you want to display.
* @param style
* The style that this {@link Crouton} should be created with.
* @param viewGroupResId
* The resource id of the {@link ViewGroup} that this {@link Crouton} should be added to.
*/
public static void showText(Activity activity, int textResourceId, Style style, int viewGroupResId) {
showText(activity, activity.getString(textResourceId), style, viewGroupResId);
}
/**
* Allows hiding of a previously displayed {@link Crouton}.
* @param crouton The {@link Crouton} you want to hide.
*/
public static void hide(Crouton crouton) {
Manager.getInstance().removeCrouton(crouton);
}
/**
* Cancels all queued {@link Crouton}s. If there is a {@link Crouton}
* displayed currently, it will be the last one displayed.
*/
public static void cancelAllCroutons() {
Manager.getInstance().clearCroutonQueue();
}
/**
* Clears (and removes from {@link Activity}'s content view, if necessary) all
* croutons for the provided activity
*
* @param activity
* - The {@link Activity} to clear the croutons for.
*/
public static void clearCroutonsForActivity(Activity activity) {
Manager.getInstance().clearCroutonsForActivity(activity);
}
/**
* Cancels a {@link Crouton} immediately.
*/
public void cancel() {
Manager manager = Manager.getInstance();
manager.removeCroutonImmediately(this);
}
/**
* Displays the {@link Crouton}. If there's another {@link Crouton} visible at
* the time, this {@link Crouton} will be displayed afterwards.
*/
public void show() {
Manager.getInstance().add(this);
}
public Animation getInAnimation() {
if ((null == this.inAnimation) && (null != this.activity)) {
if (getStyle().inAnimationResId > 0) {
this.inAnimation = AnimationUtils.loadAnimation(getActivity(), getStyle().inAnimationResId);
} else {
this.inAnimation = DefaultAnimationsBuilder.buildDefaultSlideInDownAnimation();
}
}
return inAnimation;
}
public Animation getOutAnimation() {
if ((null == this.outAnimation) && (null != this.activity)) {
if (getStyle().outAnimationResId > 0) {
this.outAnimation = AnimationUtils.loadAnimation(getActivity(), getStyle().outAnimationResId);
} else {
this.outAnimation = DefaultAnimationsBuilder.buildDefaultSlideOutUpAnimation();
}
}
return outAnimation;
}
/**
* @param lifecycleCallback
* Callback object for notable events in the life of a Crouton.
*/
public void setLifecycleCallback(LifecycleCallback lifecycleCallback) {
this.lifecycleCallback = lifecycleCallback;
}
/**
* Convenience method to get the license text for embedding within your application.
* @return
* The license text.
*/
public String getLicenseText() {
return "This application uses the Crouton library.\n\n" +
"Copyright 2012 - 2013 Benjamin Weiss \n" +
"Copyright 2012 Neofonie Mobile GmbH\n" +
"\n" +
"Licensed under the Apache License, Version 2.0 (the \"License\");\n" +
"you may not use this file except in compliance with the License.\n" +
"You may obtain a copy of the License at\n" +
"\n" +
" http://www.apache.org/licenses/LICENSE-2.0\n" +
"\n" +
"Unless required by applicable law or agreed to in writing, software\n" +
"distributed under the License is distributed on an \"AS IS\" BASIS,\n" +
"WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n" +
"See the License for the specific language governing permissions and\n" +
"limitations under the License.";
}
/**
* Allows setting of an {@link OnClickListener} directly to a {@link Crouton} without having to use a custom view.
* @param onClickListener The {@link OnClickListener} to set.
* @return this {@link Crouton}.
*/
public Crouton setOnClickListener(OnClickListener onClickListener){
this.onClickListener = onClickListener;
return this;
}
/**
* @return <code>true</code> if the {@link Crouton} is being displayed, else
* <code>false</code>.
*/
boolean isShowing() {
return (null != activity) && (null != croutonView) && (null != croutonView.getParent());
}
/**
* Removes the activity reference this {@link Crouton} is holding
*/
void detachActivity() {
activity = null;
}
/**
* Removes the viewGroup reference this {@link Crouton} is holding
*/
void detachViewGroup() {
viewGroup = null;
}
/**
* Removes the lifecycleCallback reference this {@link Crouton} is holding
*/
void detachLifecycleCallback() {
lifecycleCallback = null;
}
/**
* @return the lifecycleCallback
*/
LifecycleCallback getLifecycleCallback() {
return lifecycleCallback;
}
/**
* @return the style
*/
Style getStyle() {
return style;
}
/**
* @return the activity
*/
Activity getActivity() {
return activity;
}
/**
* @return the viewGroup
*/
ViewGroup getViewGroup() {
return viewGroup;
}
/**
* @return the text
*/
CharSequence getText() {
return text;
}
/**
* @return the view
*/
View getView() {
// return the custom view if one exists
if (null != this.customView) {
return this.customView;
}
// if already setup return the view
if (null == this.croutonView) {
initializeCroutonView();
}
return croutonView;
}
private void initializeCroutonView() {
Resources resources = this.activity.getResources();
this.croutonView = initializeCroutonViewGroup(resources);
// create content view
RelativeLayout contentView = initializeContentView(resources);
this.croutonView.addView(contentView);
}
private FrameLayout initializeCroutonViewGroup(Resources resources) {
FrameLayout croutonView = new FrameLayout(this.activity);
if(null != onClickListener)
croutonView.setOnClickListener(onClickListener);
final int height;
if (this.style.heightDimensionResId > 0) {
height = resources.getDimensionPixelSize(this.style.heightDimensionResId);
} else {
height = this.style.heightInPixels;
}
final int width;
if (this.style.widthDimensionResId > 0) {
width = resources.getDimensionPixelSize(this.style.widthDimensionResId);
} else {
width = this.style.widthInPixels;
}
croutonView.setLayoutParams(
new FrameLayout.LayoutParams(width != 0 ? width : FrameLayout.LayoutParams.MATCH_PARENT, height));
// set background
if (this.style.backgroundColorValue != -1) {
croutonView.setBackgroundColor(this.style.backgroundColorValue);
} else {
croutonView.setBackgroundColor(resources.getColor(this.style.backgroundColorResourceId));
}
// set the background drawable if set. This will override the background
// color.
if (this.style.backgroundDrawableResourceId != 0) {
Bitmap background = BitmapFactory.decodeResource(resources, this.style.backgroundDrawableResourceId);
BitmapDrawable drawable = new BitmapDrawable(resources, background);
if (this.style.isTileEnabled) {
drawable.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
}
croutonView.setBackgroundDrawable(drawable);
}
return croutonView;
}
private RelativeLayout initializeContentView(final Resources resources) {
RelativeLayout contentView = new RelativeLayout(this.activity);
contentView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
// set padding
int padding = this.style.paddingInPixels;
// if a padding dimension has been set, this will overwrite any padding
// in pixels
if (this.style.paddingDimensionResId > 0) {
padding = resources.getDimensionPixelSize(this.style.paddingDimensionResId);
}
contentView.setPadding(padding, padding, padding, padding);
// only setup image if one is requested
ImageView image = null;
if ((null != this.style.imageDrawable) || (0 != this.style.imageResId)) {
image = initializeImageView();
contentView.addView(image, image.getLayoutParams());
}
TextView text = initializeTextView(resources);
RelativeLayout.LayoutParams textParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
if (null != image) {
textParams.addRule(RelativeLayout.RIGHT_OF, image.getId());
}
contentView.addView(text, textParams);
return contentView;
}
private TextView initializeTextView(final Resources resources) {
TextView text = new TextView(this.activity);
text.setId(TEXT_ID);
text.setText(this.text);
text.setTypeface(Typeface.DEFAULT_BOLD);
text.setGravity(this.style.gravity);
// set the text color if set
if (this.style.textColorResourceId != 0) {
text.setTextColor(resources.getColor(this.style.textColorResourceId));
}
// Set the text size. If the user has set a text size and text
// appearance, the text size in the text appearance
// will override this.
if (this.style.textSize != 0) {
text.setTextSize(TypedValue.COMPLEX_UNIT_SP, this.style.textSize);
}
// Setup the shadow if requested
if (this.style.textShadowColorResId != 0) {
initializeTextViewShadow(resources, text);
}
// Set the text appearance
if (this.style.textAppearanceResId != 0) {
text.setTextAppearance(this.activity, this.style.textAppearanceResId);
}
return text;
}
private void initializeTextViewShadow(final Resources resources, final TextView text) {
int textShadowColor = resources.getColor(this.style.textShadowColorResId);
float textShadowRadius = this.style.textShadowRadius;
float textShadowDx = this.style.textShadowDx;
float textShadowDy = this.style.textShadowDy;
text.setShadowLayer(textShadowRadius, textShadowDx, textShadowDy, textShadowColor);
}
private ImageView initializeImageView() {
ImageView image;
image = new ImageView(this.activity);
image.setId(IMAGE_ID);
image.setAdjustViewBounds(true);
image.setScaleType(this.style.imageScaleType);
// set the image drawable if not null
if (null != this.style.imageDrawable) {
image.setImageDrawable(this.style.imageDrawable);
}
// set the image resource if not 0. This will overwrite the drawable
// if both are set
if (this.style.imageResId != 0) {
image.setImageResource(this.style.imageResId);
}
RelativeLayout.LayoutParams imageParams = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
imageParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT, RelativeLayout.TRUE);
imageParams.addRule(RelativeLayout.CENTER_VERTICAL, RelativeLayout.TRUE);
image.setLayoutParams(imageParams);
return image;
}
@Override
public String toString() {
return "Crouton{" +
"text=" + text +
", style=" + style +
", customView=" + customView +
", activity=" + activity +
", viewGroup=" + viewGroup +
", croutonView=" + croutonView +
", inAnimation=" + inAnimation +
", outAnimation=" + outAnimation +
", lifecycleCallback=" + lifecycleCallback +
'}';
}
}

85
external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/DefaultAnimationsBuilder.java vendored

@ -0,0 +1,85 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
/**
* Builds the default animations for showing and hiding a {@link Crouton}.
*/
final class DefaultAnimationsBuilder {
private static Animation slideInDownAnimation, slideOutUpAnimation;
protected static final class SlideInDownAnimationParameters {
private SlideInDownAnimationParameters() {
/* no-op */
}
public static final float FROM_X_DELTA = 0;
public static final float TO_X_DELTA = 0;
public static final float FROM_Y_DELTA = -50;
public static final float TO_Y_DELTA = 0;
public static final long DURATION = 400;
}
protected static final class SlideOutUpAnimationParameters {
private SlideOutUpAnimationParameters() {
/* no-op */
}
public static final float FROM_X_DELTA = 0;
public static final float TO_X_DELTA = 0;
public static final float FROM_Y_DELTA = 0;
public static final float TO_Y_DELTA = -50;
public static final long DURATION = 400;
}
private DefaultAnimationsBuilder() {
/* no-op */
}
/**
* @return The default Animation for a showing {@link Crouton}.
*/
public static Animation buildDefaultSlideInDownAnimation() {
if (null == slideInDownAnimation) {
slideInDownAnimation = new TranslateAnimation(SlideInDownAnimationParameters.FROM_X_DELTA,
SlideInDownAnimationParameters.TO_X_DELTA,
SlideInDownAnimationParameters.FROM_Y_DELTA, SlideInDownAnimationParameters.TO_Y_DELTA);
slideInDownAnimation.setDuration(SlideInDownAnimationParameters.DURATION);
}
return slideInDownAnimation;
}
/**
* @return The default Animation for a hiding {@link Crouton}.
*/
public static Animation buildDefaultSlideOutUpAnimation() {
if (null == slideOutUpAnimation) {
slideOutUpAnimation = new TranslateAnimation(SlideOutUpAnimationParameters.FROM_X_DELTA,
SlideOutUpAnimationParameters.TO_X_DELTA,
SlideOutUpAnimationParameters.FROM_Y_DELTA, SlideOutUpAnimationParameters.TO_Y_DELTA);
slideOutUpAnimation.setDuration(SlideOutUpAnimationParameters.DURATION);
}
return slideOutUpAnimation;
}
}

24
external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/LifecycleCallback.java vendored

@ -0,0 +1,24 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
public interface LifecycleCallback {
public void onDisplayed();
public void onRemoved();
//public void onCeasarDressing();
}

403
external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/Manager.java vendored

@ -0,0 +1,403 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.widget.FrameLayout;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Manages the lifecycle of {@link Crouton}s.
*/
final class Manager extends Handler {
private static final class Messages {
private Messages() { /* no-op */
}
public static final int DISPLAY_CROUTON = 0xc2007;
public static final int ADD_CROUTON_TO_VIEW = 0xc20074dd;
public static final int REMOVE_CROUTON = 0xc2007de1;
}
private static Manager INSTANCE;
private Queue<Crouton> croutonQueue;
private Manager() {
croutonQueue = new LinkedBlockingQueue<Crouton>();
}
/**
* @return The currently used instance of the {@link Manager}.
*/
static synchronized Manager getInstance() {
if (null == INSTANCE) {
INSTANCE = new Manager();
}
return INSTANCE;
}
/**
* Inserts a {@link Crouton} to be displayed.
*
* @param crouton
* The {@link Crouton} to be displayed.
*/
void add(Crouton crouton) {
croutonQueue.add(crouton);
displayCrouton();
}
/**
* Displays the next {@link Crouton} within the queue.
*/
private void displayCrouton() {
if (croutonQueue.isEmpty()) {
return;
}
// First peek whether the Crouton has an activity.
final Crouton currentCrouton = croutonQueue.peek();
// If the activity is null we poll the Crouton off the queue.
if (null == currentCrouton.getActivity()) {
croutonQueue.poll();
}
if (!currentCrouton.isShowing()) {
// Display the Crouton
sendMessage(currentCrouton, Messages.ADD_CROUTON_TO_VIEW);
if (null != currentCrouton.getLifecycleCallback()) {
currentCrouton.getLifecycleCallback().onDisplayed();
}
} else {
sendMessageDelayed(currentCrouton, Messages.DISPLAY_CROUTON, calculateCroutonDuration(currentCrouton));
}
}
private long calculateCroutonDuration(Crouton crouton) {
long croutonDuration = crouton.getStyle().durationInMilliseconds;
croutonDuration += crouton.getInAnimation().getDuration();
croutonDuration += crouton.getOutAnimation().getDuration();
return croutonDuration;
}
/**
* Sends a {@link Crouton} within a {@link Message}.
*
* @param crouton
* The {@link Crouton} that should be sent.
* @param messageId
* The {@link Message} id.
*/
private void sendMessage(Crouton crouton, final int messageId) {
final Message message = obtainMessage(messageId);
message.obj = crouton;
sendMessage(message);
}
/**
* Sends a {@link Crouton} within a delayed {@link Message}.
*
* @param crouton
* The {@link Crouton} that should be sent.
* @param messageId
* The {@link Message} id.
* @param delay
* The delay in milliseconds.
*/
private void sendMessageDelayed(Crouton crouton, final int messageId, final long delay) {
Message message = obtainMessage(messageId);
message.obj = crouton;
sendMessageDelayed(message, delay);
}
/*
* (non-Javadoc)
*
* @see android.os.Handler#handleMessage(android.os.Message)
*/
@Override
public void handleMessage(Message message) {
final Crouton crouton = (Crouton) message.obj;
switch (message.what) {
case Messages.DISPLAY_CROUTON: {
displayCrouton();
break;
}
case Messages.ADD_CROUTON_TO_VIEW: {
addCroutonToView(crouton);
break;
}
case Messages.REMOVE_CROUTON: {
removeCrouton(crouton);
if (null != crouton.getLifecycleCallback()) {
crouton.getLifecycleCallback().onRemoved();
}
break;
}
default: {
super.handleMessage(message);
break;
}
}
}
/**
* Adds a {@link Crouton} to the {@link ViewParent} of it's {@link Activity}.
*
* @param crouton
* The {@link Crouton} that should be added.
*/
private void addCroutonToView(Crouton crouton) {
// don't add if it is already showing
if (crouton.isShowing()) {
return;
}
View croutonView = crouton.getView();
if (null == croutonView.getParent()) {
ViewGroup.LayoutParams params = croutonView.getLayoutParams();
if (null == params) {
params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
// display Crouton in ViewGroup is it has been supplied
if (null != crouton.getViewGroup()) {
// TODO implement add to last position feature (need to align with how this will be requested for activity)
if (crouton.getViewGroup() instanceof FrameLayout) {
crouton.getViewGroup().addView(croutonView, params);
} else {
crouton.getViewGroup().addView(croutonView, 0, params);
}
} else {
Activity activity = crouton.getActivity();
if (null == activity || activity.isFinishing()) {
return;
}
activity.addContentView(croutonView, params);
}
}
croutonView.startAnimation(crouton.getInAnimation());
announceForAccessibilityCompat(crouton.getActivity(), crouton.getText());
if (Style.DURATION_INFINITE != crouton.getStyle().durationInMilliseconds) {
sendMessageDelayed(crouton, Messages.REMOVE_CROUTON,
crouton.getStyle().durationInMilliseconds + crouton.getInAnimation().getDuration());
}
}
/**
* Removes the {@link Crouton}'s view after it's display
* durationInMilliseconds.
*
* @param crouton
* The {@link Crouton} added to a {@link ViewGroup} and should be
* removed.
*/
protected void removeCrouton(Crouton crouton) {
View croutonView = crouton.getView();
ViewGroup croutonParentView = (ViewGroup) croutonView.getParent();
if (null != croutonParentView) {
croutonView.startAnimation(crouton.getOutAnimation());
// Remove the Crouton from the queue.
Crouton removed = croutonQueue.poll();
// Remove the crouton from the view's parent.
croutonParentView.removeView(croutonView);
if (null != removed) {
removed.detachActivity();
removed.detachViewGroup();
if (null != removed.getLifecycleCallback()) {
removed.getLifecycleCallback().onRemoved();
}
removed.detachLifecycleCallback();
}
// Send a message to display the next crouton but delay it by the out
// animation duration to make sure it finishes
sendMessageDelayed(crouton, Messages.DISPLAY_CROUTON, crouton.getOutAnimation().getDuration());
}
}
/**
* Removes a {@link Crouton} immediately, even when it's currently being
* displayed.
*
* @param crouton
* The {@link Crouton} that should be removed.
*/
void removeCroutonImmediately(Crouton crouton) {
// if Crouton has already been displayed then it may not be in the queue (because it was popped).
// This ensures the displayed Crouton is removed from its parent immediately, whether another instance
// of it exists in the queue or not.
// Note: crouton.isShowing() is false here even if it really is showing, as croutonView object in
// Crouton seems to be out of sync with reality!
if (null != crouton.getActivity() && null != crouton.getView() && null != crouton.getView().getParent()) {
((ViewGroup) crouton.getView().getParent()).removeView(crouton.getView());
// remove any messages pending for the crouton
removeAllMessagesForCrouton(crouton);
}
// remove any matching croutons from queue
if (null != croutonQueue) {
final Iterator<Crouton> croutonIterator = croutonQueue.iterator();
while (croutonIterator.hasNext()) {
final Crouton c = croutonIterator.next();
if (c.equals(crouton) && (null != c.getActivity())) {
// remove the crouton from the content view
if (crouton.isShowing()) {
((ViewGroup) c.getView().getParent()).removeView(c.getView());
}
// remove any messages pending for the crouton
removeAllMessagesForCrouton(c);
// remove the crouton from the queue
croutonIterator.remove();
// we have found our crouton so just break
break;
}
}
}
}
/**
* Removes all {@link Crouton}s from the queue.
*/
void clearCroutonQueue() {
removeAllMessages();
if (null != croutonQueue) {
// remove any views that may already have been added to the activity's
// content view
for (Crouton crouton : croutonQueue) {
if (crouton.isShowing()) {
((ViewGroup) crouton.getView().getParent()).removeView(crouton.getView());
}
}
croutonQueue.clear();
}
}
/**
* Removes all {@link Crouton}s for the provided activity. This will remove
* crouton from {@link Activity}s content view immediately.
*/
void clearCroutonsForActivity(Activity activity) {
if (null != croutonQueue) {
Iterator<Crouton> croutonIterator = croutonQueue.iterator();
while (croutonIterator.hasNext()) {
Crouton crouton = croutonIterator.next();
if ((null != crouton.getActivity()) && crouton.getActivity().equals(activity)) {
// remove the crouton from the content view
if (crouton.isShowing()) {
((ViewGroup) crouton.getView().getParent()).removeView(crouton.getView());
}
removeAllMessagesForCrouton(crouton);
// remove the crouton from the queue
croutonIterator.remove();
}
}
}
}
private void removeAllMessages() {
removeMessages(Messages.ADD_CROUTON_TO_VIEW);
removeMessages(Messages.DISPLAY_CROUTON);
removeMessages(Messages.REMOVE_CROUTON);
}
private void removeAllMessagesForCrouton(Crouton crouton) {
removeMessages(Messages.ADD_CROUTON_TO_VIEW, crouton);
removeMessages(Messages.DISPLAY_CROUTON, crouton);
removeMessages(Messages.REMOVE_CROUTON, crouton);
}
/**
* Generates and dispatches an SDK-specific spoken announcement.
* <p>
* For backwards compatibility, we're constructing an event from scratch
* using the appropriate event type. If your application only targets SDK
* 16+, you can just call View.announceForAccessibility(CharSequence).
* </p>
* <p/>
* note: AccessibilityManager is only available from API lvl 4.
* <p/>
* Adapted from https://http://eyes-free.googlecode.com/files/accessibility_codelab_demos_v2_src.zip
* via https://github.com/coreform/android-formidable-validation
*
* @param context
* Used to get {@link AccessibilityManager}
* @param text
* The text to announce.
*/
public static void announceForAccessibilityCompat(Context context, CharSequence text) {
if (Build.VERSION.SDK_INT >= 4) {
AccessibilityManager accessibilityManager = (AccessibilityManager) context.getSystemService(
Context.ACCESSIBILITY_SERVICE);
if (!accessibilityManager.isEnabled()) {
return;
}
// Prior to SDK 16, announcements could only be made through FOCUSED
// events. Jelly Bean (SDK 16) added support for speaking text verbatim
// using the ANNOUNCEMENT event type.
final int eventType;
if (Build.VERSION.SDK_INT < 16) {
eventType = AccessibilityEvent.TYPE_VIEW_FOCUSED;
} else {
eventType = AccessibilityEventCompat.TYPE_ANNOUNCEMENT;
}
// Construct an accessibility event with the minimum recommended
// attributes. An event without a class name or package may be dropped.
final AccessibilityEvent event = AccessibilityEvent.obtain(eventType);
event.getText().add(text);
event.setClassName(Manager.class.getName());
event.setPackageName(context.getPackageName());
// Sends the event directly through the accessibility manager. If your
// application only targets SDK 14+, you should just call
// getParent().requestSendAccessibilityEvent(this, event);
accessibilityManager.sendAccessibilityEvent(event);
}
}
}

539
external/Crouton/library/src/de/keyboardsurfer/android/widget/crouton/Style.java vendored

@ -0,0 +1,539 @@
/*
* Copyright 2012 - 2013 Benjamin Weiss
* Copyright 2012 Neofonie Mobile GmbH
*
* 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 de.keyboardsurfer.android.widget.crouton;
import android.graphics.drawable.Drawable;
import android.view.Gravity;
import android.view.ViewGroup.LayoutParams;
import android.widget.ImageView;
/**
* The style for a {@link Crouton}.
*/
public class Style {
/**
* Display a {@link Crouton} for an infinite amount of time or
* until {@link de.keyboardsurfer.android.widget.crouton.Crouton#cancel()} has been called.
*/
public static final int DURATION_INFINITE = -1;
/**
* Default style for alerting the user.
*/
public static final Style ALERT;
/**
* Default style for confirming an action.
*/
public static final Style CONFIRM;
/**
* Default style for general information.
*/
public static final Style INFO;
public static final int holoRedLight = 0xffff4444;
public static final int holoGreenLight = 0xff99cc00;
public static final int holoBlueLight = 0xff33b5e5;
static {
ALERT = new Builder().setDuration(5000).setBackgroundColorValue(holoRedLight).setHeight(LayoutParams.WRAP_CONTENT)
.build();
CONFIRM = new Builder().setDuration(3000).setBackgroundColorValue(holoGreenLight).setHeight(
LayoutParams.WRAP_CONTENT).build();
INFO = new Builder().setDuration(3000).setBackgroundColorValue(holoBlueLight).setHeight(LayoutParams.WRAP_CONTENT)
.build();
}
/**
* The durationInMilliseconds the {@link Crouton} will be displayed in
* milliseconds.
*/
final int durationInMilliseconds;
/**
* The resource id of the backgroundResourceId.
* <p/>
* 0 for no backgroundResourceId.
*/
final int backgroundColorResourceId;
/**
* The resource id of the backgroundDrawableResourceId.
* <p/>
* 0 for no backgroundDrawableResourceId.
*/
final int backgroundDrawableResourceId;
/**
* The backgroundColorResourceValue's e.g. 0xffff4444;
* <p/>
* -1 for no value.
*/
final int backgroundColorValue;
/**
* Whether we should isTileEnabled the backgroundResourceId or not.
*/
final boolean isTileEnabled;
/**
* The text colorResourceId's resource id.
* <p/>
* 0 sets the text colorResourceId to the system theme default.
*/
final int textColorResourceId;
/**
* The height of the {@link Crouton} in pixels.
*/
final int heightInPixels;
/**
* Resource ID for the height of the {@link Crouton}.
*/
final int heightDimensionResId;
/**
* The width of the {@link Crouton} in pixels.
*/
final int widthInPixels;
/**
* Resource ID for the width of the {@link Crouton}.
*/
final int widthDimensionResId;
/**
* The text's gravity as provided by {@link Gravity}.
*/
final int gravity;
/**
* An additional image to display in the {@link Crouton}.
*/
final Drawable imageDrawable;
/**
* An additional image to display in the {@link Crouton}.
*/
final int imageResId;
/**
* The {@link ImageView.ScaleType} for the image to display in the
* {@link Crouton}.
*/
final ImageView.ScaleType imageScaleType;
/**
* The text size in sp
* <p/>
* 0 sets the text size to the system theme default
*/
final int textSize;
/**
* The text shadow color's resource id
*/
final int textShadowColorResId;
/**
* The text shadow radius
*/
final float textShadowRadius;
/**
* The text shadow vertical offset
*/
final float textShadowDy;
/**
* The text shadow horizontal offset
*/
final float textShadowDx;
/**
* The text appearance resource id for the text.
*/
final int textAppearanceResId;
/**
* The resource id for the in animation
*/
final int inAnimationResId;
/**
* The resource id for the out animation
*/
final int outAnimationResId;
/**
* The padding for the crouton view content in pixels
*/
final int paddingInPixels;
/**
* The resource id for the padding for the view content
*/
final int paddingDimensionResId;
private Style(final Builder builder) {
this.durationInMilliseconds = builder.durationInMilliseconds;
this.backgroundColorResourceId = builder.backgroundColorResourceId;
this.backgroundDrawableResourceId = builder.backgroundDrawableResourceId;
this.isTileEnabled = builder.isTileEnabled;
this.textColorResourceId = builder.textColorResourceId;
this.heightInPixels = builder.heightInPixels;
this.heightDimensionResId = builder.heightDimensionResId;
this.widthInPixels = builder.widthInPixels;
this.widthDimensionResId = builder.widthDimensionResId;
this.gravity = builder.gravity;
this.imageDrawable = builder.imageDrawable;
this.textSize = builder.textSize;
this.textShadowColorResId = builder.textShadowColorResId;
this.textShadowRadius = builder.textShadowRadius;
this.textShadowDx = builder.textShadowDx;
this.textShadowDy = builder.textShadowDy;
this.textAppearanceResId = builder.textAppearanceResId;
this.inAnimationResId = builder.inAnimationResId;
this.outAnimationResId = builder.outAnimationResId;
this.imageResId = builder.imageResId;
this.imageScaleType = builder.imageScaleType;
this.paddingInPixels = builder.paddingInPixels;
this.paddingDimensionResId = builder.paddingDimensionResId;
this.backgroundColorValue = builder.backgroundColorValue;
}
/**
* Builder for the {@link Style} object.
*/
public static class Builder {
private int durationInMilliseconds;
private int backgroundColorValue;
private int backgroundColorResourceId;
private int backgroundDrawableResourceId;
private boolean isTileEnabled;
private int textColorResourceId;
private int heightInPixels;
private int heightDimensionResId;
private int widthInPixels;
private int widthDimensionResId;
private int gravity;
private Drawable imageDrawable;
private int textSize;
private int textShadowColorResId;
private float textShadowRadius;
private float textShadowDx;
private float textShadowDy;
private int textAppearanceResId;
private int inAnimationResId;
private int outAnimationResId;
private int imageResId;
private ImageView.ScaleType imageScaleType;
private int paddingInPixels;
private int paddingDimensionResId;
public Builder() {
durationInMilliseconds = 3000;
paddingInPixels = 10;
backgroundColorResourceId = android.R.color.holo_blue_light;
backgroundDrawableResourceId = 0;
backgroundColorValue = -1;
isTileEnabled = false;
textColorResourceId = android.R.color.white;
heightInPixels = LayoutParams.WRAP_CONTENT;
widthInPixels = LayoutParams.MATCH_PARENT;
gravity = Gravity.CENTER;
imageDrawable = null;
inAnimationResId = 0;
outAnimationResId = 0;
imageResId = 0;
imageScaleType = ImageView.ScaleType.FIT_XY;
}
/**
* Set the durationInMilliseconds option of the {@link Crouton}.
*
* @param duration
* The durationInMilliseconds the crouton will be displayed
* {@link Crouton} in milliseconds.
* @return the {@link Builder}.
*/
public Builder setDuration(int duration) {
this.durationInMilliseconds = duration;
return this;
}
/**
* Set the backgroundColorResourceId option of the {@link Crouton}.
*
* @param backgroundColorResourceId
* The backgroundColorResourceId's resource id.
* @return the {@link Builder}.
*/
public Builder setBackgroundColor(int backgroundColorResourceId) {
this.backgroundColorResourceId = backgroundColorResourceId;
return this;
}
/**
* Set the backgroundColorResourceValue option of the {@link Crouton}.
*
* @param backgroundColorValue
* The backgroundColorResourceValue's e.g. 0xffff4444;
* @return the {@link Builder}.
*/
public Builder setBackgroundColorValue(int backgroundColorValue) {
this.backgroundColorValue = backgroundColorValue;
return this;
}
/**
* Set the backgroundDrawableResourceId option for the {@link Crouton}.
*
* @param backgroundDrawableResourceId
* Resource ID of a backgroundDrawableResourceId image drawable.
* @return the {@link Builder}.
*/
public Builder setBackgroundDrawable(int backgroundDrawableResourceId) {
this.backgroundDrawableResourceId = backgroundDrawableResourceId;
return this;
}
/**
* Set the heightInPixels option for the {@link Crouton}.
*
* @param height
* The height of the {@link Crouton} in pixel. Can also be
* {@link LayoutParams#MATCH_PARENT} or
* {@link LayoutParams#WRAP_CONTENT}.
* @return the {@link Builder}.
*/
public Builder setHeight(int height) {
this.heightInPixels = height;
return this;
}
/**
* Set the resource id for the height option for the {@link Crouton}.
*
* @param heightDimensionResId
* Resource ID of a dimension for the height of the {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setHeightDimensionResId(int heightDimensionResId) {
this.heightDimensionResId = heightDimensionResId;
return this;
}
/**
* Set the widthInPixels option for the {@link Crouton}.
*
* @param width
* The width of the {@link Crouton} in pixel. Can also be
* {@link LayoutParams#MATCH_PARENT} or
* {@link LayoutParams#WRAP_CONTENT}.
* @return the {@link Builder}.
*/
public Builder setWidth(int width) {
this.widthInPixels = width;
return this;
}
/**
* Set the resource id for the width option for the {@link Crouton}.
*
* @param widthDimensionResId
* Resource ID of a dimension for the width of the {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setWidthDimensionResId(int widthDimensionResId) {
this.widthDimensionResId = widthDimensionResId;
return this;
}
/**
* Set the isTileEnabled option for the {@link Crouton}.
*
* @param isTileEnabled
* <code>true</code> if you want the backgroundResourceId to be
* tiled, else <code>false</code>.
* @return the {@link Builder}.
*/
public Builder setTileEnabled(boolean isTileEnabled) {
this.isTileEnabled = isTileEnabled;
return this;
}
/**
* Set the textColorResourceId option for the {@link Crouton}.
*
* @param textColor
* The resource id of the text colorResourceId.
* @return the {@link Builder}.
*/
public Builder setTextColor(int textColor) {
this.textColorResourceId = textColor;
return this;
}
/**
* Set the gravity option for the {@link Crouton}.
*
* @param gravity
* The text's gravity as provided by {@link Gravity}.
* @return the {@link Builder}.
*/
public Builder setGravity(int gravity) {
this.gravity = gravity;
return this;
}
/**
* Set the image option for the {@link Crouton}.
*
* @param imageDrawable
* An additional image to display in the {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setImageDrawable(Drawable imageDrawable) {
this.imageDrawable = imageDrawable;
return this;
}
/**
* Set the image resource option for the {@link Crouton}.
*
* @param imageResId
* An additional image to display in the {@link Crouton}.
* @return the {@link Builder}.
*/
public Builder setImageResource(int imageResId) {
this.imageResId = imageResId;
return this;
}
/**
* The text size in sp
*/
public Builder setTextSize(int textSize) {
this.textSize = textSize;
return this;
}
/**
* The text shadow color's resource id
*/
public Builder setTextShadowColor(int textShadowColorResId) {
this.textShadowColorResId = textShadowColorResId;
return this;
}
/**
* The text shadow radius
*/
public Builder setTextShadowRadius(float textShadowRadius) {
this.textShadowRadius = textShadowRadius;
return this;
}
/**
* The text shadow horizontal offset
*/
public Builder setTextShadowDx(float textShadowDx) {
this.textShadowDx = textShadowDx;
return this;
}
/**
* The text shadow vertical offset
*/
public Builder setTextShadowDy(float textShadowDy) {
this.textShadowDy = textShadowDy;
return this;
}
/**
* The text appearance resource id for the text.
*/
public Builder setTextAppearance(int textAppearanceResId) {
this.textAppearanceResId = textAppearanceResId;
return this;
}
/**
* The resource id for the in animation
*/
public Builder setInAnimation(int inAnimationResId) {
this.inAnimationResId = inAnimationResId;
return this;
}
/**
* The resource id for the out animation
*/
public Builder setOutAnimation(int outAnimationResId) {
this.outAnimationResId = outAnimationResId;
return this;
}
/**
* The {@link android.widget.ImageView.ScaleType} for the image
*/
public Builder setImageScaleType(ImageView.ScaleType imageScaleType) {
this.imageScaleType = imageScaleType;
return this;
}
/**
* The padding for the crouton view's content in pixels
*/
public Builder setPaddingInPixels(int padding) {
this.paddingInPixels = padding;
return this;
}
/**
* The resource id for the padding for the crouton view's content
*/
public Builder setPaddingDimensionResId(int paddingResId) {
this.paddingDimensionResId = paddingResId;
return this;
}
/**
* @return a configured {@link Style} object.
*/
public Style build() {
return new Style(this);
}
}
}

102
external/Crouton/pom.xml vendored

@ -0,0 +1,102 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ Copyright 2012 - 2013 Benjamin Weiss
~ Copyright 2012 Neofonie Mobile GmbH
~
~ 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.
-->
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<name>Crouton Parent</name>
<artifactId>crouton-parent</artifactId>
<version>1.7</version>
<groupId>de.keyboardsurfer.android.widget</groupId>
<packaging>pom</packaging>
<developers>
<developer>
<id>keyboardsurfer</id>
<name>Benjamin Weiss</name>
</developer>
</developers>
<licenses>
<license>
<name>The Apache Software License, Version 2.0</name>
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
<distribution>repo</distribution>
</license>
</licenses>
<scm>
<url>git@github.com:keyboardsurfer/Crouton.git</url>
<developerConnection>scm:git:git@github.com:keyboardsurfer/Crouton.git</developerConnection>
<connection>scm:git:git@github.com:keyboardsurfer/Crouton.git</connection>
</scm>
<modules>
<module>library</module>
<module>sample</module>
</modules>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<android.version>4.1.1.4</android.version>
<android.version.platform>16</android.version.platform>
</properties>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>2.2</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9</version>
</plugin>
<plugin>
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
<artifactId>android-maven-plugin</artifactId>
<version>3.4.1</version>
<extensions>true</extensions>
<configuration>
<sdk>
<platform>${android.version.platform}</platform>
</sdk>
<undeployBeforeDeploy>true</undeployBeforeDeploy>
<lazyLibraryUnpack>true</lazyLibraryUnpack>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Loading…
Cancel
Save