mirror of
https://github.com/moparisthebest/open-keychain
synced 2024-11-23 09:12:16 -05:00
Use git submodules for libs, fix compilation, remove library sourcecode
This commit is contained in:
parent
b0c65729a9
commit
f7c243564f
21
.gitmodules
vendored
Normal file
21
.gitmodules
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
[submodule "extern/StickyListHeaders"]
|
||||
path = extern/StickyListHeaders
|
||||
url = https://github.com/open-keychain/StickyListHeaders.git
|
||||
[submodule "extern/AndroidBootstrap"]
|
||||
path = extern/AndroidBootstrap
|
||||
url = https://github.com/open-keychain/Android-Bootstrap.git
|
||||
[submodule "extern/zxing-android-integration"]
|
||||
path = extern/zxing-android-integration
|
||||
url = https://github.com/open-keychain/zxing-android-integration.git
|
||||
[submodule "extern/zxing-qr-code"]
|
||||
path = extern/zxing-qr-code
|
||||
url = https://github.com/open-keychain/zxing-qr-code.git
|
||||
[submodule "extern/AppMsg"]
|
||||
path = extern/AppMsg
|
||||
url = https://github.com/open-keychain/Android-AppMsg.git
|
||||
[submodule "extern/spongycastle"]
|
||||
path = extern/spongycastle
|
||||
url = https://github.com/open-keychain/spongycastle.git
|
||||
[submodule "extern/html-textview"]
|
||||
path = extern/html-textview
|
||||
url = https://github.com/open-keychain/html-textview.git
|
@ -12,16 +12,16 @@ dependencies {
|
||||
compile 'com.android.support:appcompat-v7:19.0.1'
|
||||
compile project(':OpenKeychain-API:libraries:openpgp-api-library')
|
||||
compile project(':OpenKeychain-API:libraries:openkeychain-api-library')
|
||||
compile project(':libraries:HtmlTextView')
|
||||
compile project(':libraries:StickyListHeaders:library')
|
||||
compile project(':libraries:AndroidBootstrap')
|
||||
compile project(':libraries:zxing')
|
||||
compile project(':libraries:zxing-android-integration')
|
||||
compile project(':libraries:spongycastle:core')
|
||||
compile project(':libraries:spongycastle:pg')
|
||||
compile project(':libraries:spongycastle:pkix')
|
||||
compile project(':libraries:spongycastle:prov')
|
||||
compile project(':libraries:Android-AppMsg:library')
|
||||
compile project(':extern:html-textview')
|
||||
compile project(':extern:StickyListHeaders:library')
|
||||
compile project(':extern:AndroidBootstrap:AndroidBootstrap')
|
||||
compile project(':extern:zxing-qr-code')
|
||||
compile project(':extern:zxing-android-integration')
|
||||
compile project(':extern:spongycastle:core')
|
||||
compile project(':extern:spongycastle:pg')
|
||||
compile project(':extern:spongycastle:pkix')
|
||||
compile project(':extern:spongycastle:prov')
|
||||
compile project(':extern:AppMsg:library')
|
||||
|
||||
// Dependencies for the `testLocal` task, make sure to list all your global dependencies here as well
|
||||
testLocalCompile 'junit:junit:4.11'
|
||||
@ -31,16 +31,16 @@ dependencies {
|
||||
testLocalCompile 'com.android.support:appcompat-v7:19.0.1'
|
||||
testLocalCompile project(':OpenKeychain-API:libraries:openpgp-api-library')
|
||||
testLocalCompile project(':OpenKeychain-API:libraries:openkeychain-api-library')
|
||||
testLocalCompile project(':libraries:HtmlTextView')
|
||||
testLocalCompile project(':libraries:StickyListHeaders:library')
|
||||
testLocalCompile project(':libraries:AndroidBootstrap')
|
||||
testLocalCompile project(':libraries:zxing')
|
||||
testLocalCompile project(':libraries:zxing-android-integration')
|
||||
testLocalCompile project(':libraries:spongycastle:core')
|
||||
testLocalCompile project(':libraries:spongycastle:pg')
|
||||
testLocalCompile project(':libraries:spongycastle:pkix')
|
||||
testLocalCompile project(':libraries:spongycastle:prov')
|
||||
testLocalCompile project(':libraries:Android-AppMsg:library')
|
||||
testLocalCompile project(':extern:html-textview')
|
||||
testLocalCompile project(':extern:StickyListHeaders:library')
|
||||
testLocalCompile project(':extern:AndroidBootstrap:AndroidBootstrap')
|
||||
testLocalCompile project(':extern:zxing-qr-code')
|
||||
testLocalCompile project(':extern:zxing-android-integration')
|
||||
testLocalCompile project(':extern:spongycastle:core')
|
||||
testLocalCompile project(':extern:spongycastle:pg')
|
||||
testLocalCompile project(':extern:spongycastle:pkix')
|
||||
testLocalCompile project(':extern:spongycastle:prov')
|
||||
testLocalCompile project(':extern:AppMsg:library')
|
||||
}
|
||||
|
||||
android {
|
||||
|
@ -69,7 +69,6 @@ import org.sufficientlysecure.keychain.util.Log;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
|
||||
import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
|
||||
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
|
||||
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
|
||||
|
||||
@ -150,16 +149,14 @@ public class KeyListFragment extends Fragment
|
||||
mStickyList.setAreHeadersSticky(true);
|
||||
mStickyList.setDrawingListUnderStickyHeader(false);
|
||||
mStickyList.setFastScrollEnabled(true);
|
||||
try {
|
||||
mStickyList.setFastScrollAlwaysVisible(true);
|
||||
} catch (ApiLevelTooLowException e) {
|
||||
}
|
||||
|
||||
/*
|
||||
* ActionBarSherlock does not support MultiChoiceModeListener. Thus multi-selection is only
|
||||
* available for Android >= 3.0
|
||||
*/
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mStickyList.setFastScrollAlwaysVisible(true);
|
||||
|
||||
mStickyList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
|
||||
mStickyList.getWrappedList().setMultiChoiceModeListener(new MultiChoiceModeListener() {
|
||||
|
||||
|
@ -21,6 +21,7 @@ import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.LoaderManager;
|
||||
@ -41,7 +42,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainDatabase.Tables;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
|
||||
import se.emilsjolander.stickylistheaders.ApiLevelTooLowException;
|
||||
import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter;
|
||||
import se.emilsjolander.stickylistheaders.StickyListHeadersListView;
|
||||
|
||||
@ -100,9 +100,8 @@ public class ViewKeyCertsFragment extends Fragment
|
||||
mStickyList.setFastScrollEnabled(true);
|
||||
mStickyList.setOnItemClickListener(this);
|
||||
|
||||
try {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
|
||||
mStickyList.setFastScrollAlwaysVisible(true);
|
||||
} catch (ApiLevelTooLowException e) {
|
||||
}
|
||||
|
||||
mStickyList.setEmptyView(getActivity().findViewById(R.id.empty));
|
||||
|
11
README.md
11
README.md
@ -30,14 +30,15 @@ Development mailinglist at http://groups.google.com/d/forum/openpgp-keychain-dev
|
||||
|
||||
### Build with Gradle
|
||||
|
||||
1. Have Android SDK "tools", "platform-tools", and "build-tools" directories in your PATH (http://developer.android.com/sdk/index.html)
|
||||
2. Open the Android SDK Manager (shell command: ``android``).
|
||||
1. Get all external submodules with ``git submodule update --init --recursive``
|
||||
2. Have Android SDK "tools", "platform-tools", and "build-tools" directories in your PATH (http://developer.android.com/sdk/index.html)
|
||||
3. Open the Android SDK Manager (shell command: ``android``).
|
||||
Expand the Tools directory and select "Android SDK Build-tools (Version 19.0.3)".
|
||||
Expand the Extras directory and install "Android Support Repository"
|
||||
Select everything for the newest SDK Platform (API-Level 19)
|
||||
3. Export ANDROID_HOME pointing to your Android SDK
|
||||
4. Execute ``./gradlew build``
|
||||
5. You can install the app with ``adb install -r OpenKeychain/build/apk/OpenKeychain-debug-unaligned.apk``
|
||||
4. Export ANDROID_HOME pointing to your Android SDK
|
||||
5. Execute ``./gradlew build``
|
||||
6. You can install the app with ``adb install -r OpenKeychain/build/apk/OpenKeychain-debug-unaligned.apk``
|
||||
|
||||
### Build API Demo with Gradle
|
||||
|
||||
|
1
extern/AndroidBootstrap
vendored
Submodule
1
extern/AndroidBootstrap
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit bfa160c4ef3a1a53aebd68aca9c05b8e546219e0
|
1
extern/AppMsg
vendored
Submodule
1
extern/AppMsg
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit ca714df97bfce67a7a9a1efefd2c49645b6f22e4
|
1
extern/StickyListHeaders
vendored
Submodule
1
extern/StickyListHeaders
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit efe46c21143cc54a2394303a67822f14580d1d20
|
1
extern/html-textview
vendored
Submodule
1
extern/html-textview
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 30fbf60ccfa8732e8fc4d3c97b94c4809ef871a5
|
1
extern/spongycastle
vendored
Submodule
1
extern/spongycastle
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit eb2c35bd0602d05a65c10c86b9c9834ebd1a81c6
|
1
extern/zxing-android-integration
vendored
Submodule
1
extern/zxing-android-integration
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 34029d4dcac81ec06137a046a189dac608e76efe
|
1
extern/zxing-qr-code
vendored
Submodule
1
extern/zxing-qr-code
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 50193905fd8cef92140ea242f77b04bb31391c9e
|
36
libraries/Android-AppMsg/.gitignore
vendored
36
libraries/Android-AppMsg/.gitignore
vendored
@ -1,36 +0,0 @@
|
||||
#Android generated
|
||||
bin
|
||||
gen
|
||||
|
||||
#Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings
|
||||
|
||||
#IntelliJ IDEA
|
||||
.idea
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
out
|
||||
|
||||
#Maven
|
||||
target
|
||||
release.properties
|
||||
pom.xml.*
|
||||
|
||||
#Ant
|
||||
build.xml
|
||||
local.properties
|
||||
proguard.cfg
|
||||
proguard-project.txt
|
||||
|
||||
#Gradle
|
||||
.gradle
|
||||
build
|
||||
|
||||
#OSX
|
||||
.DS_Store
|
||||
|
||||
#Personal Files
|
||||
signing.properties
|
@ -1,202 +0,0 @@
|
||||
|
||||
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.
|
@ -1,117 +0,0 @@
|
||||
Android AppMsg (Crouton) Library
|
||||
================================
|
||||
|
||||
Implementation of in-layout notifications. Based on [Toast](http://developer.android.com/reference/android/widget/Toast.html) notifications and article [The making of Prixing #4: in-layout notifications](http://android.cyrilmottier.com/?p=773) by [Cyril Mottier](http://www.cyrilmottier.com/).
|
||||
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
Toast is far from being perfect and I am not entirely satisfied with it.
|
||||
Toast can be un-accurate in some cases. Indeed, Toast has one major drawback: it completely breaks contexts.
|
||||
This issue can be reproduced effortless. Let’s say a user is currently in an app firing a Toast and wants to switch to another application using the dedicated “multitask” button.
|
||||
The Toast will remain on screen even if the brought-to-front application has nothing do to with the previously shown app as described on the following figure:
|
||||
![Example Image][1]
|
||||
|
||||
As you can easily notice, the problem with Toasts is they are persistent.
|
||||
Once a Toast has been fired, it is displayed on top of any screen and remains visible for the duration specified at its creation.
|
||||
|
||||
In order to bypass the Toast persistence problem and ensure information is displayed in the correct context, we decided to create a new notification system:
|
||||
Activity-bound notifications. This is what it looks like in the current version of Prixing:
|
||||
![Example Image][2]
|
||||
|
||||
Crouton overcomes the main issue of having a Toast being shown while the menu is open.
|
||||
It sticks to the current screen sliding with it and leaving the menu completely free of any information that would have not been related to it.
|
||||
|
||||
<b>Copyright (C) by Cyril Mottier</b>
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
A sample application is available on Google Play:
|
||||
|
||||
<a href="http://play.google.com/store/apps/details?id=com.devspark.appmsg.sample">
|
||||
<img alt="Get it on Google Play"
|
||||
src="http://www.android.com/images/brand/get_it_on_play_logo_small.png" />
|
||||
</a>
|
||||
|
||||
![Example Image][3]
|
||||
|
||||
The source code is available in this repository.
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
|
||||
This library is compatible from API 4 (Android 1.6).
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
The sample project requires:
|
||||
|
||||
* The library project
|
||||
* [ActionBarSherlock](https://github.com/JakeWharton/ActionBarSherlock)
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Android AppMsg is presented as an [Android library project](http://developer.android.com/guide/developing/projects/projects-eclipse.html).
|
||||
You can include this project by [referencing it as a library project](http://developer.android.com/guide/developing/projects/projects-eclipse.html#ReferencingLibraryProject) in Eclipse or ant.
|
||||
|
||||
To display the item you need the following code:
|
||||
|
||||
* Show AppMsg:
|
||||
|
||||
``` java
|
||||
AppMsg.makeText(/*Activity*/, /*CharSequence*/, /*AppMsg.Style*/).show();
|
||||
```
|
||||
|
||||
Gradle
|
||||
------
|
||||
|
||||
Android-AppMsg Library is now pushed to Maven Central as a AAR, so you just need to add the following dependency to your build.gradle.
|
||||
|
||||
``` xml
|
||||
dependencies {
|
||||
compile 'com.github.johnkil.android-appmsg:appmsg:1.2.0'
|
||||
}
|
||||
```
|
||||
|
||||
Example Gradle project using Android-AppMsg:
|
||||
|
||||
* [Android-AppMsg-Gradle-Sample](https://github.com/johnkil/Android-AppMsg-Gradle-Sample)
|
||||
|
||||
|
||||
Contribution
|
||||
------------
|
||||
|
||||
Please fork [dev](https://github.com/johnkil/Android-AppMsg/tree/dev) repository and contribute back using [pull requests](https://github.com/johnkil/Android-AppMsg/pulls).
|
||||
|
||||
Contributors are recommended to follow the Android [Code Style Guidelines](http://source.android.com/source/code-style.html).
|
||||
|
||||
Any contributions, large or small, major features, bug fixes, additional language translations, unit/integration tests are welcomed and appreciated but will be thoroughly reviewed and discussed.
|
||||
|
||||
Developed By
|
||||
------------
|
||||
* Evgeny Shishkin - <johnkil78@gmail.com>
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
Copyright 2012 Evgeny Shishkin
|
||||
|
||||
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.
|
||||
|
||||
[1]: http://cyrilmottier.com/media/2012/07/the-making-of-prixing-4-activity-tied-notifications/toast_user_flow_fail.png
|
||||
[2]: http://cyrilmottier.com/media/2012/07/the-making-of-prixing-4-activity-tied-notifications/in_layout_notification.png
|
||||
[3]: http://i46.tinypic.com/21kywit.png
|
@ -1,12 +0,0 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.devspark.appmsg"
|
||||
android:versionCode="5"
|
||||
android:versionName="1.2.0">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="4"
|
||||
android:targetSdkVersion="19"/>
|
||||
|
||||
<application/>
|
||||
|
||||
</manifest>
|
@ -1,22 +0,0 @@
|
||||
apply plugin: 'android-library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 19
|
||||
buildToolsVersion '19.0.3'
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion 4
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (project.hasProperty('nexusUsername')) {
|
||||
// Used to push in maven
|
||||
apply from: '../maven_push.gradle'
|
||||
}
|
@ -1,71 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<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/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>com.devspark</groupId>
|
||||
<artifactId>appmsg</artifactId>
|
||||
<version>1.0.1</version>
|
||||
<packaging>apklib</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.android</groupId>
|
||||
<artifactId>android</artifactId>
|
||||
<version>4.1.1.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<sourceDirectory>src</sourceDirectory>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-pmd-plugin</artifactId>
|
||||
<version>2.7.1</version>
|
||||
<configuration>
|
||||
<linkXref>true</linkXref>
|
||||
<sourceEncoding>utf-8</sourceEncoding>
|
||||
<minimumTokens>100</minimumTokens>
|
||||
<targetJdk>1.6</targetJdk>
|
||||
<excludes>
|
||||
<exclude>**/*Bean.java</exclude>
|
||||
<exclude>**/generated/*.java</exclude>
|
||||
</excludes>
|
||||
<excludeRoots>
|
||||
<excludeRoot>target/generated-sources/stubs</excludeRoot>
|
||||
</excludeRoots>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.jayway.maven.plugins.android.generation2</groupId>
|
||||
<artifactId>android-maven-plugin</artifactId>
|
||||
<version>3.6.0</version>
|
||||
<configuration>
|
||||
<androidManifestFile>${project.basedir}/AndroidManifest.xml</androidManifestFile>
|
||||
<assetsDirectory>${project.basedir}/assets</assetsDirectory>
|
||||
<resourceDirectory>${project.basedir}/res</resourceDirectory>
|
||||
<nativeLibrariesDirectory>${project.basedir}/src/main/native</nativeLibrariesDirectory>
|
||||
<sdk>
|
||||
<platform>16</platform>
|
||||
</sdk>
|
||||
<undeployBeforeDeploy>true</undeployBeforeDeploy>
|
||||
</configuration>
|
||||
<extensions>true</extensions>
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<version>2.3.2</version>
|
||||
<configuration>
|
||||
<source>1.6</source>
|
||||
<target>1.6</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
@ -1,15 +0,0 @@
|
||||
# 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-19
|
||||
android.library=true
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:minHeight="48dp"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<TextView
|
||||
android:id="@android:id/message"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:padding="8dp"
|
||||
android:textColor="?android:textColorPrimaryInverse"
|
||||
android:textIsSelectable="false"
|
||||
android:textSize="14sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
</LinearLayout>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<color name="alert">#CC0000</color>
|
||||
<color name="confirm">#FF8800</color>
|
||||
<color name="info">#669900</color>
|
||||
|
||||
</resources>
|
@ -1,587 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 Evgeny Shishkin
|
||||
*
|
||||
* 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 com.devspark.appmsg;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewGroup.LayoutParams;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* In-layout notifications. Based on {@link android.widget.Toast} notifications
|
||||
* and article by Cyril Mottier (http://android.cyrilmottier.com/?p=773).
|
||||
*
|
||||
* @author e.shishkin
|
||||
*/
|
||||
public class AppMsg {
|
||||
|
||||
/**
|
||||
* Show the view or text notification for a short period of time. This time
|
||||
* could be user-definable. This is the default.
|
||||
*
|
||||
* @see #setDuration
|
||||
*/
|
||||
public static final int LENGTH_SHORT = 3000;
|
||||
|
||||
/**
|
||||
* Show the view or text notification for a long period of time. This time
|
||||
* could be user-definable.
|
||||
*
|
||||
* @see #setDuration
|
||||
*/
|
||||
public static final int LENGTH_LONG = 5000;
|
||||
|
||||
/**
|
||||
* <p>Show the view or text notification for an undefined amount of time
|
||||
* -Usually until an invocation of {@link #cancel()}, {@link #cancelAll(android.app.Activity)},
|
||||
* {@link #cancelAll()} or {@link android.app.Activity#onDestroy()}-,
|
||||
* stacking on top of any other {@link com.devspark.appmsg.AppMsg} with this duration.</p>
|
||||
*
|
||||
* <p><b>Note</b>: You are responsible
|
||||
* for calling {@link #cancel()} on such {@link com.devspark.appmsg.AppMsg}.</p>
|
||||
*
|
||||
* @see #setDuration
|
||||
*/
|
||||
public static final int LENGTH_STICKY = -1;
|
||||
|
||||
/**
|
||||
* Lowest priority, messages with this priority will be showed after all messages with priority
|
||||
* {@link #PRIORITY_HIGH} and {@link #PRIORITY_NORMAL} have been shown.
|
||||
*
|
||||
* @see #setPriority(int)
|
||||
*/
|
||||
public static final int PRIORITY_LOW = Integer.MIN_VALUE;
|
||||
/**
|
||||
* Normal priority, messages with this priority will be showed after all messages with priority
|
||||
* {@link #PRIORITY_HIGH} but before {@link #PRIORITY_LOW} have been shown.
|
||||
*
|
||||
* @see #setPriority(int)
|
||||
*/
|
||||
public static final int PRIORITY_NORMAL = 0;
|
||||
/**
|
||||
* Highest priority, messages with this priority will be showed before any other message.
|
||||
*
|
||||
* @see #setPriority(int)
|
||||
*/
|
||||
public static final int PRIORITY_HIGH = Integer.MAX_VALUE;
|
||||
|
||||
/**
|
||||
* Show the text notification for a long period of time with a negative style.
|
||||
*/
|
||||
public static final Style STYLE_ALERT = new Style(LENGTH_LONG, R.color.alert);
|
||||
|
||||
/**
|
||||
* Show the text notification for a short period of time with a positive style.
|
||||
*/
|
||||
public static final Style STYLE_CONFIRM = new Style(LENGTH_SHORT, R.color.confirm);
|
||||
|
||||
/**
|
||||
* Show the text notification for a short period of time with a neutral style.
|
||||
*/
|
||||
public static final Style STYLE_INFO = new Style(LENGTH_SHORT, R.color.info);
|
||||
|
||||
private final Activity mActivity;
|
||||
private int mDuration = LENGTH_SHORT;
|
||||
private View mView;
|
||||
private ViewGroup mParent;
|
||||
private LayoutParams mLayoutParams;
|
||||
private boolean mFloating;
|
||||
Animation mInAnimation, mOutAnimation;
|
||||
int mPriority = PRIORITY_NORMAL;
|
||||
|
||||
/**
|
||||
* Construct an empty AppMsg object. You must call {@link #setView} before
|
||||
* you can call {@link #show}.
|
||||
*
|
||||
* @param activity {@link android.app.Activity} to use.
|
||||
*/
|
||||
public AppMsg(Activity activity) {
|
||||
mActivity = activity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a {@link AppMsg} that just contains a text view.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, CharSequence text, Style style) {
|
||||
return makeText(context, text, style, R.layout.app_msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author mengguoqiang 扩展支持设置字体大小
|
||||
* Make a {@link AppMsg} that just contains a text view.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, CharSequence text, Style style, float textSize) {
|
||||
return makeText(context, text, style, R.layout.app_msg, textSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a {@link AppMsg} with a custom layout. The layout must have a {@link TextView} com id {@link android.R.id.message}
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, CharSequence text, Style style, int layoutId) {
|
||||
LayoutInflater inflate = (LayoutInflater)
|
||||
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View v = inflate.inflate(layoutId, null);
|
||||
|
||||
return makeText(context, text, style, v, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @author mengguoqiang 扩展支持字体大小
|
||||
* Make a {@link AppMsg} with a custom layout. The layout must have a {@link TextView} com id {@link android.R.id.message}
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, CharSequence text, Style style, int layoutId, float textSize) {
|
||||
LayoutInflater inflate = (LayoutInflater)
|
||||
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
View v = inflate.inflate(layoutId, null);
|
||||
|
||||
return makeText(context, text, style, v, true, textSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a non-floating {@link AppMsg} with a custom view presented inside the layout.
|
||||
* It can be used to create non-floating notifications if floating is false.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param customView
|
||||
* View to be used.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, CharSequence text, Style style, View customView) {
|
||||
return makeText(context, text, style, customView, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a {@link AppMsg} with a custom view. It can be used to create non-floating notifications if floating is false.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param view
|
||||
* View to be used.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
* @param floating true if it'll float.
|
||||
*/
|
||||
private static AppMsg makeText(Activity context, CharSequence text, Style style, View view, boolean floating) {
|
||||
return makeText(context, text, style, view, floating, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @author mengguoqiang 扩展支持设置字体大小
|
||||
* Make a {@link AppMsg} with a custom view. It can be used to create non-floating notifications if floating is false.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param view
|
||||
* View to be used.
|
||||
* @param text The text to show. Can be formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
* @param floating true if it'll float.
|
||||
*/
|
||||
private static AppMsg makeText(Activity context, CharSequence text, Style style, View view, boolean floating, float textSize) {
|
||||
AppMsg result = new AppMsg(context);
|
||||
|
||||
view.setBackgroundResource(style.background);
|
||||
|
||||
TextView tv = (TextView) view.findViewById(android.R.id.message);
|
||||
if(textSize > 0) tv.setTextSize(textSize);
|
||||
tv.setText(text);
|
||||
|
||||
result.mView = view;
|
||||
result.mDuration = style.duration;
|
||||
result.mFloating = floating;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a {@link AppMsg} with a custom view. It can be used to create non-floating notifications if floating is false.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param resId The resource id of the string resource to use. Can be
|
||||
* formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
* @param floating true if it'll float.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, int resId, Style style, View customView, boolean floating) {
|
||||
return makeText(context, context.getResources().getText(resId), style, customView, floating);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a {@link AppMsg} that just contains a text view with the text from a
|
||||
* resource.
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param resId The resource id of the string resource to use. Can be
|
||||
* formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
* @throws Resources.NotFoundException if the resource can't be found.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, int resId, Style style)
|
||||
throws Resources.NotFoundException {
|
||||
return makeText(context, context.getResources().getText(resId), style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Make a {@link AppMsg} with a custom layout using the text from a
|
||||
* resource. The layout must have a {@link TextView} com id {@link android.R.id.message}
|
||||
*
|
||||
* @param context The context to use. Usually your
|
||||
* {@link android.app.Activity} object.
|
||||
* @param resId The resource id of the string resource to use. Can be
|
||||
* formatted text.
|
||||
* @param style The style with a background and a duration.
|
||||
* @throws Resources.NotFoundException if the resource can't be found.
|
||||
*/
|
||||
public static AppMsg makeText(Activity context, int resId, Style style, int layoutId)
|
||||
throws Resources.NotFoundException {
|
||||
return makeText(context, context.getResources().getText(resId), style, layoutId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the view for the specified duration.
|
||||
*/
|
||||
public void show() {
|
||||
MsgManager manager = MsgManager.obtain(mActivity);
|
||||
manager.add(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return <code>true</code> if the {@link AppMsg} is being displayed, else <code>false</code>.
|
||||
*/
|
||||
public boolean isShowing() {
|
||||
if (mFloating) {
|
||||
return mView != null && mView.getParent() != null;
|
||||
} else {
|
||||
return mView.getVisibility() == View.VISIBLE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Close the view if it's showing, or don't show it if it isn't showing yet.
|
||||
* You do not normally have to call this. Normally view will disappear on its own
|
||||
* after the appropriate duration.
|
||||
*/
|
||||
public void cancel() {
|
||||
MsgManager.obtain(mActivity).clearMsg(this);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels all queued {@link AppMsg}s, in all Activities. If there is a {@link AppMsg}
|
||||
* displayed currently, it will be the last one displayed.
|
||||
*/
|
||||
public static void cancelAll() {
|
||||
MsgManager.clearAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancels all queued {@link AppMsg}s, in given {@link android.app.Activity}.
|
||||
* If there is a {@link AppMsg} displayed currently, it will be the last one displayed.
|
||||
* @param activity
|
||||
*/
|
||||
public static void cancelAll(Activity activity) {
|
||||
MsgManager.release(activity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the activity.
|
||||
*/
|
||||
public Activity getActivity() {
|
||||
return mActivity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the view to show.
|
||||
*
|
||||
* @see #getView
|
||||
*/
|
||||
public void setView(View view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the view.
|
||||
*
|
||||
* @see #setView
|
||||
*/
|
||||
public View getView() {
|
||||
return mView;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set how long to show the view for.
|
||||
*
|
||||
* @see #LENGTH_SHORT
|
||||
* @see #LENGTH_LONG
|
||||
*/
|
||||
public void setDuration(int duration) {
|
||||
mDuration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the duration.
|
||||
*
|
||||
* @see #setDuration
|
||||
*/
|
||||
public int getDuration() {
|
||||
return mDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the text in a AppMsg that was previously created using one of the makeText() methods.
|
||||
*
|
||||
* @param resId The new text for the AppMsg.
|
||||
*/
|
||||
public void setText(int resId) {
|
||||
setText(mActivity.getText(resId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the text in a AppMsg that was previously created using one of the makeText() methods.
|
||||
*
|
||||
* @param s The new text for the AppMsg.
|
||||
*/
|
||||
public void setText(CharSequence s) {
|
||||
if (mView == null) {
|
||||
throw new RuntimeException("This AppMsg was not created with AppMsg.makeText()");
|
||||
}
|
||||
TextView tv = (TextView) mView.findViewById(android.R.id.message);
|
||||
if (tv == null) {
|
||||
throw new RuntimeException("This AppMsg was not created with AppMsg.makeText()");
|
||||
}
|
||||
tv.setText(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the crouton's layout parameters, constructing a default if necessary.
|
||||
*
|
||||
* @return the layout parameters
|
||||
*/
|
||||
public LayoutParams getLayoutParams() {
|
||||
if (mLayoutParams == null) {
|
||||
mLayoutParams = new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
|
||||
}
|
||||
return mLayoutParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the layout parameters which will be used to display the crouton.
|
||||
*
|
||||
* @param layoutParams The layout parameters to use.
|
||||
* @return <code>this</code>, for chaining.
|
||||
*/
|
||||
public AppMsg setLayoutParams(LayoutParams layoutParams) {
|
||||
mLayoutParams = layoutParams;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs and sets the layout parameters to have some gravity.
|
||||
*
|
||||
* @param gravity the gravity of the Crouton
|
||||
* @return <code>this</code>, for chaining.
|
||||
* @see android.view.Gravity
|
||||
*/
|
||||
public AppMsg setLayoutGravity(int gravity) {
|
||||
mLayoutParams = new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, gravity);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of floating.
|
||||
*
|
||||
* @see #setFloating(boolean)
|
||||
*/
|
||||
public boolean isFloating() {
|
||||
return mFloating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of floating.
|
||||
*
|
||||
* @param mFloating
|
||||
*/
|
||||
public void setFloating(boolean mFloating) {
|
||||
this.mFloating = mFloating;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Animations to be used when displaying/removing the Crouton.
|
||||
* @param inAnimation the Animation resource ID to be used when displaying.
|
||||
* @param outAnimation the Animation resource ID to be used when removing.
|
||||
*/
|
||||
public AppMsg setAnimation(int inAnimation, int outAnimation) {
|
||||
return setAnimation(AnimationUtils.loadAnimation(mActivity, inAnimation),
|
||||
AnimationUtils.loadAnimation(mActivity, outAnimation));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Animations to be used when displaying/removing the Crouton.
|
||||
* @param inAnimation the Animation to be used when displaying.
|
||||
* @param outAnimation the Animation to be used when removing.
|
||||
*/
|
||||
public AppMsg setAnimation(Animation inAnimation, Animation outAnimation) {
|
||||
mInAnimation = inAnimation;
|
||||
mOutAnimation = outAnimation;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Current priority
|
||||
*
|
||||
* @see #PRIORITY_HIGH
|
||||
* @see #PRIORITY_NORMAL
|
||||
* @see #PRIORITY_LOW
|
||||
*/
|
||||
public int getPriority() {
|
||||
return mPriority;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>Set priority for this message</p>
|
||||
* <p><b>Note</b>: This only affects the order in which the messages get shown,
|
||||
* not the stacking order of the views.</p>
|
||||
*
|
||||
* <p>Example: In the queue there are 3 messages [A, B, C],
|
||||
* all of them with priority {@link #PRIORITY_NORMAL}, currently message A is being shown
|
||||
* so we add a new message D with priority {@link #PRIORITY_HIGH}, after A goes away, given that
|
||||
* D has a higher priority than B an the reset, D will be shown, then once that D is gone,
|
||||
* B will be shown, and then finally C.</p>
|
||||
*
|
||||
* @param priority
|
||||
* A value indicating priority, although you can use any integer value, usage of already
|
||||
* defined is highly encouraged.
|
||||
*
|
||||
* @see #PRIORITY_HIGH
|
||||
* @see #PRIORITY_NORMAL
|
||||
* @see #PRIORITY_LOW
|
||||
*/
|
||||
public void setPriority(int priority) {
|
||||
mPriority = priority;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* Provided parent to add {@link #getView()} to using {@link #getLayoutParams()}.
|
||||
*/
|
||||
public ViewGroup getParent() {
|
||||
return mParent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a different parent than Activity decor view
|
||||
* @param parent
|
||||
* Provided parent to add {@link #getView()} to using {@link #getLayoutParams()}.
|
||||
*
|
||||
*/
|
||||
public void setParent(ViewGroup parent) {
|
||||
mParent = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provide a different parent than Activity decor view
|
||||
*
|
||||
* @param parentId
|
||||
* Provided parent id to add {@link #getView()} to using {@link #getLayoutParams()}.
|
||||
*
|
||||
*/
|
||||
public void setParent(int parentId) {
|
||||
setParent((ViewGroup) mActivity.findViewById(parentId));
|
||||
}
|
||||
|
||||
/**
|
||||
* The style for a {@link AppMsg}.
|
||||
*
|
||||
* @author e.shishkin
|
||||
*/
|
||||
public static class Style {
|
||||
|
||||
private final int duration;
|
||||
private final int background;
|
||||
|
||||
/**
|
||||
* Construct an {@link AppMsg.Style} object.
|
||||
*
|
||||
* @param duration How long to display the message. Either
|
||||
* {@link #LENGTH_SHORT} or {@link #LENGTH_LONG}
|
||||
* @param resId resource for AppMsg background
|
||||
*/
|
||||
public Style(int duration, int resId) {
|
||||
this.duration = duration;
|
||||
this.background = resId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the duration in milliseconds.
|
||||
*/
|
||||
public int getDuration() {
|
||||
return duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resource id of background.
|
||||
*/
|
||||
public int getBackground() {
|
||||
return background;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof AppMsg.Style)) {
|
||||
return false;
|
||||
}
|
||||
Style style = (Style) o;
|
||||
return style.duration == duration
|
||||
&& style.background == background;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -1,340 +0,0 @@
|
||||
/*
|
||||
* Copyright 2012 Evgeny Shishkin
|
||||
*
|
||||
* 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 com.devspark.appmsg;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.app.Application;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.AnimationUtils;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.Queue;
|
||||
import java.util.WeakHashMap;
|
||||
|
||||
import static android.app.Application.ActivityLifecycleCallbacks;
|
||||
import static android.os.Build.VERSION.SDK_INT;
|
||||
import static android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH;
|
||||
import static com.devspark.appmsg.AppMsg.LENGTH_STICKY;
|
||||
|
||||
/**
|
||||
* @author Evgeny Shishkin
|
||||
*/
|
||||
class MsgManager extends Handler implements Comparator<AppMsg> {
|
||||
|
||||
private static final int MESSAGE_DISPLAY = 0xc2007;
|
||||
private static final int MESSAGE_ADD_VIEW = 0xc20074dd;
|
||||
private static final int MESSAGE_REMOVE = 0xc2007de1;
|
||||
|
||||
private static WeakHashMap<Activity, MsgManager> sManagers;
|
||||
private static ReleaseCallbacks sReleaseCallbacks;
|
||||
|
||||
private final Queue<AppMsg> msgQueue;
|
||||
private final Queue<AppMsg> stickyQueue;
|
||||
|
||||
private MsgManager() {
|
||||
msgQueue = new PriorityQueue<AppMsg>(1, this);
|
||||
stickyQueue = new LinkedList<AppMsg>();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A {@link MsgManager} instance to be used for given {@link android.app.Activity}.
|
||||
*/
|
||||
static synchronized MsgManager obtain(Activity activity) {
|
||||
if (sManagers == null) {
|
||||
sManagers = new WeakHashMap<Activity, MsgManager>(1);
|
||||
}
|
||||
MsgManager manager = sManagers.get(activity);
|
||||
if (manager == null) {
|
||||
manager = new MsgManager();
|
||||
ensureReleaseOnDestroy(activity);
|
||||
sManagers.put(activity, manager);
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
static void ensureReleaseOnDestroy(Activity activity) {
|
||||
if (SDK_INT < ICE_CREAM_SANDWICH) {
|
||||
return;
|
||||
}
|
||||
if (sReleaseCallbacks == null) {
|
||||
sReleaseCallbacks = new ReleaseCallbacksIcs();
|
||||
}
|
||||
sReleaseCallbacks.register(activity.getApplication());
|
||||
}
|
||||
|
||||
|
||||
static synchronized void release(Activity activity) {
|
||||
if (sManagers != null) {
|
||||
final MsgManager manager = sManagers.remove(activity);
|
||||
if (manager != null) {
|
||||
manager.clearAllMsg();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static synchronized void clearAll() {
|
||||
if (sManagers != null) {
|
||||
final Iterator<MsgManager> iterator = sManagers.values().iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final MsgManager manager = iterator.next();
|
||||
if (manager != null) {
|
||||
manager.clearAllMsg();
|
||||
}
|
||||
iterator.remove();
|
||||
}
|
||||
sManagers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts a {@link AppMsg} to be displayed.
|
||||
*
|
||||
* @param appMsg
|
||||
*/
|
||||
void add(AppMsg appMsg) {
|
||||
msgQueue.add(appMsg);
|
||||
if (appMsg.mInAnimation == null) {
|
||||
appMsg.mInAnimation = AnimationUtils.loadAnimation(appMsg.getActivity(),
|
||||
android.R.anim.fade_in);
|
||||
}
|
||||
if (appMsg.mOutAnimation == null) {
|
||||
appMsg.mOutAnimation = AnimationUtils.loadAnimation(appMsg.getActivity(),
|
||||
android.R.anim.fade_out);
|
||||
}
|
||||
displayMsg();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all {@link AppMsg} from the queue.
|
||||
*/
|
||||
void clearMsg(AppMsg appMsg) {
|
||||
if(msgQueue.contains(appMsg) || stickyQueue.contains(appMsg)){
|
||||
// Avoid the message from being removed twice.
|
||||
removeMessages(MESSAGE_DISPLAY, appMsg);
|
||||
removeMessages(MESSAGE_ADD_VIEW, appMsg);
|
||||
removeMessages(MESSAGE_REMOVE, appMsg);
|
||||
msgQueue.remove(appMsg);
|
||||
stickyQueue.remove(appMsg);
|
||||
removeMsg(appMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes all {@link AppMsg} from the queue.
|
||||
*/
|
||||
void clearAllMsg() {
|
||||
removeMessages(MESSAGE_DISPLAY);
|
||||
removeMessages(MESSAGE_ADD_VIEW);
|
||||
removeMessages(MESSAGE_REMOVE);
|
||||
clearShowing();
|
||||
msgQueue.clear();
|
||||
stickyQueue.clear();
|
||||
}
|
||||
|
||||
void clearShowing() {
|
||||
final Collection<AppMsg> showing = new HashSet<AppMsg>();
|
||||
obtainShowing(msgQueue, showing);
|
||||
obtainShowing(stickyQueue, showing);
|
||||
for (AppMsg msg : showing) {
|
||||
clearMsg(msg);
|
||||
}
|
||||
}
|
||||
|
||||
static void obtainShowing(Collection<AppMsg> from, Collection<AppMsg> appendTo) {
|
||||
for (AppMsg msg : from) {
|
||||
if (msg.isShowing()) {
|
||||
appendTo.add(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the next {@link AppMsg} within the queue.
|
||||
*/
|
||||
private void displayMsg() {
|
||||
if (msgQueue.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
// First peek whether the AppMsg is being displayed.
|
||||
final AppMsg appMsg = msgQueue.peek();
|
||||
final Message msg;
|
||||
if (!appMsg.isShowing()) {
|
||||
// Display the AppMsg
|
||||
msg = obtainMessage(MESSAGE_ADD_VIEW);
|
||||
msg.obj = appMsg;
|
||||
sendMessage(msg);
|
||||
} else if (appMsg.getDuration() != LENGTH_STICKY) {
|
||||
msg = obtainMessage(MESSAGE_DISPLAY);
|
||||
sendMessageDelayed(msg, appMsg.getDuration()
|
||||
+ appMsg.mInAnimation.getDuration() + appMsg.mOutAnimation.getDuration());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the {@link AppMsg}'s view after it's display duration.
|
||||
*
|
||||
* @param appMsg The {@link AppMsg} added to a {@link ViewGroup} and should be removed.s
|
||||
*/
|
||||
private void removeMsg(final AppMsg appMsg) {
|
||||
clearMsg(appMsg);
|
||||
final View view = appMsg.getView();
|
||||
ViewGroup parent = ((ViewGroup) view.getParent());
|
||||
if (parent != null) {
|
||||
appMsg.mOutAnimation.setAnimationListener(new OutAnimationListener(appMsg));
|
||||
view.clearAnimation();
|
||||
view.startAnimation(appMsg.mOutAnimation);
|
||||
}
|
||||
|
||||
Message msg = obtainMessage(MESSAGE_DISPLAY);
|
||||
sendMessage(msg);
|
||||
}
|
||||
|
||||
private void addMsgToView(AppMsg appMsg) {
|
||||
View view = appMsg.getView();
|
||||
if (view.getParent() == null) { // Not added yet
|
||||
final ViewGroup targetParent = appMsg.getParent();
|
||||
final ViewGroup.LayoutParams params = appMsg.getLayoutParams();
|
||||
if (targetParent != null) {
|
||||
targetParent.addView(view, params);
|
||||
} else {
|
||||
appMsg.getActivity().addContentView(view, params);
|
||||
}
|
||||
}
|
||||
view.clearAnimation();
|
||||
view.startAnimation(appMsg.mInAnimation);
|
||||
if (view.getVisibility() != View.VISIBLE) {
|
||||
view.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
final int duration = appMsg.getDuration();
|
||||
if (duration != LENGTH_STICKY) {
|
||||
final Message msg = obtainMessage(MESSAGE_REMOVE);
|
||||
msg.obj = appMsg;
|
||||
sendMessageDelayed(msg, duration);
|
||||
} else { // We are sticky, we don't get removed just yet
|
||||
stickyQueue.add(msgQueue.poll());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleMessage(Message msg) {
|
||||
final AppMsg appMsg;
|
||||
switch (msg.what) {
|
||||
case MESSAGE_DISPLAY:
|
||||
displayMsg();
|
||||
break;
|
||||
case MESSAGE_ADD_VIEW:
|
||||
appMsg = (AppMsg) msg.obj;
|
||||
addMsgToView(appMsg);
|
||||
break;
|
||||
case MESSAGE_REMOVE:
|
||||
appMsg = (AppMsg) msg.obj;
|
||||
removeMsg(appMsg);
|
||||
break;
|
||||
default:
|
||||
super.handleMessage(msg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(AppMsg lhs, AppMsg rhs) {
|
||||
return inverseCompareInt(lhs.mPriority, rhs.mPriority);
|
||||
}
|
||||
|
||||
static int inverseCompareInt(int lhs, int rhs) {
|
||||
return lhs < rhs ? 1 : (lhs == rhs ? 0 : -1);
|
||||
}
|
||||
|
||||
private static class OutAnimationListener implements Animation.AnimationListener {
|
||||
|
||||
private final AppMsg appMsg;
|
||||
|
||||
private OutAnimationListener(AppMsg appMsg) {
|
||||
this.appMsg = appMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationStart(Animation animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animation animation) {
|
||||
final View view = appMsg.getView();
|
||||
if (appMsg.isFloating()) {
|
||||
final ViewGroup parent = ((ViewGroup) view.getParent());
|
||||
if (parent != null) {
|
||||
parent.post(new Runnable() { // One does not simply removeView
|
||||
@Override
|
||||
public void run() {
|
||||
parent.removeView(view);
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
view.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animation animation) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
interface ReleaseCallbacks {
|
||||
void register(Application application);
|
||||
}
|
||||
|
||||
@TargetApi(ICE_CREAM_SANDWICH)
|
||||
static class ReleaseCallbacksIcs implements ActivityLifecycleCallbacks, ReleaseCallbacks {
|
||||
private WeakReference<Application> mLastApp;
|
||||
public void register(Application app) {
|
||||
if (mLastApp != null && mLastApp.get() == app) {
|
||||
return; // Already registered with this app
|
||||
} else {
|
||||
mLastApp = new WeakReference<Application>(app);
|
||||
}
|
||||
app.registerActivityLifecycleCallbacks(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityDestroyed(Activity activity) {
|
||||
release(activity);
|
||||
}
|
||||
@Override public void onActivityCreated(Activity activity, Bundle savedInstanceState) {}
|
||||
@Override public void onActivityStarted(Activity activity) {}
|
||||
@Override public void onActivityResumed(Activity activity) {}
|
||||
@Override public void onActivityPaused(Activity activity) {}
|
||||
@Override public void onActivityStopped(Activity activity) {}
|
||||
@Override public void onActivitySaveInstanceState(Activity activity, Bundle outState) {}
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.beardedhen.androidbootstrap"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0" >
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="7"
|
||||
android:targetSdkVersion="17" />
|
||||
|
||||
<application/>
|
||||
|
||||
</manifest>
|
@ -1,17 +0,0 @@
|
||||
apply plugin: 'android-library'
|
||||
|
||||
android {
|
||||
compileSdkVersion 19
|
||||
buildToolsVersion "19.0.3"
|
||||
defaultConfig {
|
||||
minSdkVersion 7
|
||||
targetSdkVersion 19
|
||||
}
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
}
|
||||
}
|
||||
}
|
Binary file not shown.
@ -1,20 +0,0 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -1,15 +0,0 @@
|
||||
# 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-19
|
||||
android.library=true
|
Binary file not shown.
Before Width: | Height: | Size: 9.2 KiB |
Binary file not shown.
Before Width: | Height: | Size: 5.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 14 KiB |
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_danger_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_danger_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_danger" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,25 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_danger_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_danger_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_danger" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
</selector>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_default_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_default_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_default_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_default_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_default" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_default_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_default_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_default_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_default_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_default_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_default" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_default_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_info_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_info_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_info_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_info_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_info" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_info_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_info_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_info_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_info_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_info_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_info" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_info_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_inverse_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_inverse_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_inverse_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_inverse_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_inverse" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_inverse_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_inverse_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_inverse_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_inverse_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_inverse_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_inverse" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_inverse_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_primary_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_primary_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_primary_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_primary_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_primary" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_primary_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_primary_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_primary_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_primary_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_primary_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_primary" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_primary_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_success_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_success_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_success" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_success_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_success_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_success" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_warning_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning_edge" />
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_warning_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning_disabled_edge" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_warning" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning_edge" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,23 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_pressed="true"><shape>
|
||||
<solid android:color="@color/bbutton_warning_pressed" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_warning_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning_disabled_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bbutton_warning" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning_edge" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bthumbnail_background" />
|
||||
<stroke android:width="1dp" android:color="@color/bthumbnail_border" />
|
||||
<corners android:radius="@dimen/bthumbnail_rounded_corner_radius"/>
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item><shape>
|
||||
<solid android:color="@color/bthumbnail_background" />
|
||||
<stroke android:width="1dp" android:color="@color/bthumbnail_border" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/bthumbnail_placeholder" />
|
||||
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,18 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_primary" />
|
||||
</shape></item>
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_edittext_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_edittext_border" />
|
||||
</shape></item>
|
||||
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_edittext_border" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_danger" />
|
||||
</shape></item>
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,21 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_primary" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
<item android:state_enabled="false"><shape>
|
||||
<solid android:color="@color/bbutton_edittext_disabled" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_edittext_border" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_edittext_border" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,17 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_danger" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_danger" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
|
||||
|
||||
|
||||
</selector>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_success" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_warning" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning" />
|
||||
<corners android:radius="@dimen/bbuton_rounded_corner_radius" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_success" />
|
||||
</shape></item>
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_success" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true"><shape>
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="2dp" android:color="@color/bbutton_warning" />
|
||||
</shape></item>
|
||||
<item><shape android:shape="rectangle">
|
||||
<solid android:color="@color/white" />
|
||||
<stroke android:width="1dp" android:color="@color/bbutton_warning" />
|
||||
</shape></item>
|
||||
|
||||
</selector>
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bthumbnail_placeholder"/>
|
||||
</shape>
|
@ -1,12 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bthumbnail_background" />
|
||||
<stroke android:width="1dp" android:color="@color/bthumbnail_border" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item>
|
||||
<shape
|
||||
android:shape="oval">
|
||||
<solid android:color="@color/bthumbnail_background" />
|
||||
</shape>
|
||||
</item>
|
||||
|
||||
</selector>
|
@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/layout"
|
||||
android:duplicateParentState="true"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblLeft"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingLeft="15dp"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="center_vertical"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblMiddle"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="fill_parent"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingRight="15dp"
|
||||
android:layout_gravity="center"
|
||||
android:gravity="center_horizontal"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblRight"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingRight="15dp"
|
||||
android:visibility="gone"
|
||||
android:layout_gravity="center_vertical"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
@ -1,40 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/layout"
|
||||
android:duplicateParentState="true"
|
||||
android:paddingTop="10dp"
|
||||
android:paddingBottom="10dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblLeft"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingLeft="15dp"
|
||||
android:visibility="gone"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_alignParentLeft="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblRight"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="wrap_content"
|
||||
android:paddingRight="15dp"
|
||||
android:visibility="gone"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_alignParentRight="true"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/lblMiddle"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent"
|
||||
android:paddingLeft="15dp"
|
||||
android:paddingRight="15dp"
|
||||
android:visibility="gone"
|
||||
android:gravity="left|center_vertical"
|
||||
android:layout_toLeftOf="@id/lblRight"
|
||||
android:layout_toRightOf="@id/lblLeft"
|
||||
/>
|
||||
|
||||
</RelativeLayout>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/layout"
|
||||
android:orientation="horizontal">
|
||||
<EditText
|
||||
android:id="@+id/txtText"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_gravity="center"
|
||||
android:hint=""
|
||||
/>
|
||||
</LinearLayout>
|
@ -1,33 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/container"
|
||||
android:duplicateParentState="true"
|
||||
android:padding="@dimen/padding_small"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/placeholder"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center"
|
||||
android:padding="16dp">
|
||||
|
||||
<com.beardedhen.androidbootstrap.utils.AutoResizeTextView
|
||||
android:id="@+id/dimensionsLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:ellipsize="none"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:textSize="100sp"
|
||||
android:textColor="@color/bthumbnail_font"/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/container"
|
||||
android:duplicateParentState="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:id="@+id/placeholder"
|
||||
android:orientation="vertical"
|
||||
android:gravity="center">
|
||||
|
||||
<ImageView
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:id="@+id/image"/>
|
||||
|
||||
<com.beardedhen.androidbootstrap.utils.AutoResizeTextView
|
||||
android:id="@+id/dimensionsLabel"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="100dp"
|
||||
android:ellipsize="none"
|
||||
android:gravity="center"
|
||||
android:maxLines="1"
|
||||
android:textSize="100sp"
|
||||
android:textColor="@color/bthumbnail_font"/>
|
||||
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
@ -1,14 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/layout"
|
||||
android:orientation="horizontal">
|
||||
<TextView
|
||||
android:id="@+id/lblText"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_gravity="center"
|
||||
android:padding="3dp"
|
||||
/>
|
||||
</LinearLayout>
|
@ -1,16 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/lblTitle"
|
||||
android:gravity="left"
|
||||
/>
|
||||
</LinearLayout>
|
@ -1,26 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/lblTitle"
|
||||
android:gravity="center"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/lblSubTitle"
|
||||
android:gravity="center"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -1,28 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="10dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/lblColA"
|
||||
android:gravity="center"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:id="@+id/lblColB"
|
||||
android:gravity="center"
|
||||
/>
|
||||
|
||||
|
||||
|
||||
</LinearLayout>
|
@ -1,9 +0,0 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
|
||||
|
||||
<item
|
||||
android:id="@+id/action_settings"
|
||||
android:orderInCategory="100"
|
||||
android:showAsAction="never"
|
||||
android:title="@string/action_settings"/>
|
||||
|
||||
</menu>
|
@ -1,8 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Customize dimensions originally defined in res/values/dimens.xml (such as
|
||||
screen margins) for sw600dp devices (e.g. 7" tablets) here.
|
||||
-->
|
||||
|
||||
</resources>
|
@ -1,9 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Customize dimensions originally defined in res/values/dimens.xml (such as
|
||||
screen margins) for sw720dp devices (e.g. 10" tablets) in landscape here.
|
||||
-->
|
||||
<dimen name="activity_horizontal_margin">128dp</dimen>
|
||||
|
||||
</resources>
|
@ -1,11 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Base application theme for API 11+. This theme completely replaces
|
||||
AppBaseTheme from res/values/styles.xml on API 11+ devices.
|
||||
-->
|
||||
<style name="AppBaseTheme" parent="android:Theme.Holo.Light">
|
||||
<!-- API 11 theme customizations can go here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -1,12 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Base application theme for API 14+. This theme completely replaces
|
||||
AppBaseTheme from BOTH res/values/styles.xml and
|
||||
res/values-v11/styles.xml on API 14+ devices.
|
||||
-->
|
||||
<style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
|
||||
<!-- API 14 theme customizations can go here. -->
|
||||
</style>
|
||||
|
||||
</resources>
|
@ -1,50 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<declare-styleable name="BootstrapButton">
|
||||
<attr name="bb_type" format="string"/>
|
||||
<attr name="bb_icon_left" format="string"/>
|
||||
<attr name="bb_icon_right" format="string"/>
|
||||
<attr name="bb_roundedCorners" format="boolean"/>
|
||||
<attr name="bb_text_alignment" format="string"/>
|
||||
<attr name="bb_size" format="string"/>
|
||||
<attr name="bb_text_gravity" format="string"/>
|
||||
<attr name="android:textSize"/>
|
||||
<attr name="android:text"/>
|
||||
<attr name="android:enabled"/>
|
||||
<attr name="android:layout_width"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="FontAwesomeText">
|
||||
<attr name="fa_icon" format="string"/>
|
||||
<attr name="android:textSize"/>
|
||||
<attr name="android:textColor"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="BootstrapEditText">
|
||||
<attr name="be_roundedCorners" format="boolean"/>
|
||||
<attr name="be_state" format="string"/>
|
||||
<attr name="android:textSize"/>
|
||||
<attr name="android:text"/>
|
||||
<attr name="android:hint"/>
|
||||
<attr name="android:enabled"/>
|
||||
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="BootstrapThumbnail">
|
||||
<attr name="bt_roundedCorners" format="boolean"/>
|
||||
<attr name="bt_image" format="integer"/>
|
||||
<attr name="bt_width" format="dimension"/>
|
||||
<attr name="bt_height" format="dimension"/>
|
||||
<attr name="bt_inside_padding" format="dimension"/>
|
||||
<attr name="android:text"/>
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="BootstrapCircleThumbnail">
|
||||
<attr name="bct_image" format="integer"/>
|
||||
<attr name="bct_size" format="string" />
|
||||
<attr name="bct_minimal" format="boolean" />
|
||||
<attr name="android:text"/>
|
||||
</declare-styleable>
|
||||
|
||||
</resources>
|
||||
|
@ -1,65 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="white">#ffffffff</color>
|
||||
<color name="black">#ff000000</color>
|
||||
<color name="bbutton_edittext_border">#ccc</color>
|
||||
<color name="bbutton_edittext_disabled">#ffe0e0e0</color>
|
||||
|
||||
<color name="bbutton_primary">#ff428bca</color>
|
||||
<color name="bbutton_primary_edge">#ff357ebd</color>
|
||||
<color name="bbutton_primary_pressed">#ff3276b1</color>
|
||||
<color name="bbutton_primary_pressed_edge">#ff285e8e</color>
|
||||
<color name="bbutton_primary_disabled">#a5428bca</color>
|
||||
<color name="bbutton_primary_disabled_edge">#a5357ebd</color>
|
||||
|
||||
<color name="bbutton_danger">#ffd9534f</color>
|
||||
<color name="bbutton_danger_edge">#ffd43f3a</color>
|
||||
<color name="bbutton_danger_pressed">#ffd2322d</color>
|
||||
<color name="bbutton_danger_pressed_edge">#ffac2925</color>
|
||||
<color name="bbutton_danger_disabled">#a5d9534f</color>
|
||||
<color name="bbutton_danger_disabled_edge">#a5d43f3a</color>
|
||||
|
||||
|
||||
<color name="bbutton_success">#ff5cb85c</color>
|
||||
<color name="bbutton_success_edge">#ff4cae4c</color>
|
||||
<color name="bbutton_success_pressed">#ff47a447</color>
|
||||
<color name="bbutton_success_pressed_edge">#ff398439</color>
|
||||
<color name="bbutton_success_disabled">#a55cb85c</color>
|
||||
<color name="bbutton_success_disabled_edge">#a54cae4c</color>
|
||||
|
||||
|
||||
<color name="bbutton_warning">#fff0ad4e</color>
|
||||
<color name="bbutton_warning_edge">#ffeea236</color>
|
||||
<color name="bbutton_warning_pressed">#ffed9c28</color>
|
||||
<color name="bbutton_warning_pressed_edge">#ffd58512</color>
|
||||
<color name="bbutton_warning_disabled">#a5f0ad4e</color>
|
||||
<color name="bbutton_warning_disabled_edge">#a5eea236</color>
|
||||
|
||||
<color name="bbutton_info">#ff5bc0de</color>
|
||||
<color name="bbutton_info_edge">#ff46b8da</color>
|
||||
<color name="bbutton_info_pressed">#ff39b3d7</color>
|
||||
<color name="bbutton_info_pressed_edge">#ff269abc</color>
|
||||
<color name="bbutton_info_disabled">#a55bc0de</color>
|
||||
<color name="bbutton_info_disabled_edge">#a546b8da</color>
|
||||
|
||||
<color name="bbutton_default">#ffffffff</color>
|
||||
<color name="bbutton_default_edge">#ffcccccc</color>
|
||||
<color name="bbutton_default_pressed">#ffebebeb</color>
|
||||
<color name="bbutton_default_pressed_edge">#ffadadad</color>
|
||||
<color name="bbutton_default_disabled">#a5ffffff</color>
|
||||
<color name="bbutton_default_disabled_edge">#a5cccccc</color>
|
||||
|
||||
<color name="bbutton_inverse">#ff0a0a0a</color>
|
||||
<color name="bbutton_inverse_edge">#ff141414</color>
|
||||
<color name="bbutton_inverse_pressed">#ff1f1f1f</color>
|
||||
<color name="bbutton_inverse_pressed_edge">#ff292929</color>
|
||||
<color name="bbutton_inverse_disabled">#a50a0a0a</color>
|
||||
<color name="bbutton_inverse_disabled_edge">#a5141414</color>
|
||||
|
||||
<color name="bthumbnail_background">#ffffffff</color>
|
||||
<color name="bthumbnail_placeholder">#e9e9e9</color>
|
||||
<color name="bthumbnail_border">#dbdbdb</color>
|
||||
<color name="bthumbnail_font">#7e7e7e</color>
|
||||
|
||||
|
||||
</resources>
|
@ -1,14 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="bbuton_rounded_corner_radius">5dp</dimen>
|
||||
|
||||
<dimen name="bthumbnail_rounded_corner_radius">3dp</dimen>
|
||||
|
||||
<dimen name="padding_micro">4dp</dimen>
|
||||
<dimen name="padding_small">8dp</dimen>
|
||||
<dimen name="padding_medium">12dp</dimen>
|
||||
<dimen name="padding_large">16dp</dimen>
|
||||
</resources>
|
@ -1,8 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<string name="app_name">BButton</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="hello_world">Hello world!</string>
|
||||
|
||||
</resources>
|
@ -1,16 +0,0 @@
|
||||
<resources>
|
||||
|
||||
<!--
|
||||
Base application theme, dependent on API level. This theme is replaced
|
||||
by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
|
||||
-->
|
||||
<style name="AppBaseTheme" parent="android:Theme.Light">
|
||||
<!--
|
||||
Theme customizations available in newer API levels can go in
|
||||
res/values-vXX/styles.xml, while customizations related to
|
||||
backward-compatibility can go here.
|
||||
-->
|
||||
</style>
|
||||
|
||||
|
||||
</resources>
|
@ -1,445 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.Gravity;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.beardedhen.androidbootstrap.R;
|
||||
|
||||
|
||||
public class BootstrapButton extends FrameLayout {
|
||||
|
||||
private static Map<String, BootstrapTypes> bbuttonTypeMap;
|
||||
private static Map<String, BootstrapTypes> bbuttonTypeMapRounded;
|
||||
private static Typeface font;
|
||||
|
||||
private static Map<String, String> faMap;
|
||||
|
||||
private TextView lblMiddle;
|
||||
private TextView lblRight;
|
||||
private TextView lblLeft;
|
||||
private ViewGroup layout;
|
||||
private boolean roundedCorners = false;
|
||||
private boolean fillparent = false;
|
||||
|
||||
private static final String FA_ICON_QUESTION = "fa-question";
|
||||
|
||||
static{
|
||||
|
||||
bbuttonTypeMap = new HashMap<String, BootstrapTypes>();
|
||||
|
||||
bbuttonTypeMap.put("default", BootstrapTypes.DEFAULT);
|
||||
bbuttonTypeMap.put("primary", BootstrapTypes.PRIMARY);
|
||||
bbuttonTypeMap.put("success", BootstrapTypes.SUCCESS);
|
||||
bbuttonTypeMap.put("info", BootstrapTypes.INFO);
|
||||
bbuttonTypeMap.put("warning", BootstrapTypes.WARNING);
|
||||
bbuttonTypeMap.put("danger", BootstrapTypes.DANGER);
|
||||
bbuttonTypeMap.put("inverse", BootstrapTypes.INVERSE);
|
||||
|
||||
bbuttonTypeMapRounded = new HashMap<String, BootstrapTypes>();
|
||||
|
||||
bbuttonTypeMapRounded.put("default", BootstrapTypes.DEFAULT_ROUNDED);
|
||||
bbuttonTypeMapRounded.put("primary", BootstrapTypes.PRIMARY_ROUNDED);
|
||||
bbuttonTypeMapRounded.put("success", BootstrapTypes.SUCCESS_ROUNDED);
|
||||
bbuttonTypeMapRounded.put("info", BootstrapTypes.INFO_ROUNDED);
|
||||
bbuttonTypeMapRounded.put("warning", BootstrapTypes.WARNING_ROUNDED);
|
||||
bbuttonTypeMapRounded.put("danger", BootstrapTypes.DANGER_ROUNDED);
|
||||
bbuttonTypeMapRounded.put("inverse", BootstrapTypes.INVERSE_ROUNDED);
|
||||
|
||||
|
||||
faMap = FontAwesome.getFaMap();
|
||||
|
||||
}
|
||||
|
||||
public BootstrapButton(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapButton(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapButton(Context context) {
|
||||
super(context);
|
||||
initialise(null);
|
||||
}
|
||||
|
||||
//set up the bootstrap types
|
||||
private enum BootstrapTypes
|
||||
{
|
||||
DEFAULT(R.drawable.bbuton_default, R.color.black),
|
||||
PRIMARY(R.drawable.bbuton_primary, R.color.white),
|
||||
SUCCESS(R.drawable.bbuton_success, R.color.white),
|
||||
INFO(R.drawable.bbuton_info, R.color.white),
|
||||
WARNING(R.drawable.bbuton_warning, R.color.white),
|
||||
DANGER(R.drawable.bbuton_danger, R.color.white),
|
||||
INVERSE(R.drawable.bbuton_inverse, R.color.white),
|
||||
|
||||
DEFAULT_ROUNDED(R.drawable.bbuton_default_rounded, R.color.black),
|
||||
PRIMARY_ROUNDED(R.drawable.bbuton_primary_rounded, R.color.white),
|
||||
SUCCESS_ROUNDED(R.drawable.bbuton_success_rounded, R.color.white),
|
||||
INFO_ROUNDED(R.drawable.bbuton_info_rounded, R.color.white),
|
||||
WARNING_ROUNDED(R.drawable.bbuton_warning_rounded, R.color.white),
|
||||
DANGER_ROUNDED(R.drawable.bbuton_danger_rounded, R.color.white),
|
||||
INVERSE_ROUNDED(R.drawable.bbuton_inverse_rounded, R.color.white);
|
||||
|
||||
private int backgroundDrawable;
|
||||
private int textColour;
|
||||
|
||||
BootstrapTypes(int backgroundDrawable, int textColour)
|
||||
{
|
||||
this.backgroundDrawable = backgroundDrawable;
|
||||
this.textColour = textColour;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void initialise( AttributeSet attrs )
|
||||
{
|
||||
LayoutInflater inflator = (LayoutInflater)getContext().getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
//get font
|
||||
readFont(getContext());
|
||||
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||
R.styleable.BootstrapButton);
|
||||
|
||||
//defaults
|
||||
BootstrapTypes type = null;
|
||||
String bootstrapType = "default";
|
||||
String iconLeft = "";
|
||||
String iconRight = "";
|
||||
String text = "";
|
||||
//boolean roundedCorners = false;
|
||||
float fontSize = 14.0f;
|
||||
float scale = getResources().getDisplayMetrics().density; //for padding
|
||||
String size = "default";
|
||||
int paddingA = (int) (10 *scale + 0.5f);
|
||||
int paddingB = (int) (15 *scale + 0.5f);
|
||||
|
||||
|
||||
//attribute values
|
||||
|
||||
if (a.getString(R.styleable.BootstrapButton_bb_type) != null) {
|
||||
bootstrapType = a.getString(R.styleable.BootstrapButton_bb_type);
|
||||
}
|
||||
|
||||
if (a.getString(R.styleable.BootstrapButton_bb_roundedCorners) != null) {
|
||||
roundedCorners = a.getBoolean(R.styleable.BootstrapButton_bb_roundedCorners, false) ;
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapButton_bb_size) != null) {
|
||||
size = a.getString(R.styleable.BootstrapButton_bb_size);
|
||||
}
|
||||
|
||||
if ( a.getString(R.styleable.BootstrapButton_bb_icon_left) != null) {
|
||||
iconLeft = a.getString(R.styleable.BootstrapButton_bb_icon_left );
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapButton_bb_icon_right) != null) {
|
||||
iconRight = a.getString(R.styleable.BootstrapButton_bb_icon_right );
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapButton_android_text) != null) {
|
||||
text = a.getString(R.styleable.BootstrapButton_android_text);
|
||||
}
|
||||
String gravity = "";
|
||||
if(a.getString(R.styleable.BootstrapButton_bb_text_gravity) != null) {
|
||||
gravity = a.getString(R.styleable.BootstrapButton_bb_text_gravity);
|
||||
}
|
||||
|
||||
boolean enabled = true;
|
||||
if(a.getString(R.styleable.BootstrapButton_android_enabled) != null) {
|
||||
enabled = a.getBoolean(R.styleable.BootstrapButton_android_enabled, true);
|
||||
}
|
||||
|
||||
int layoutWidth = 0;
|
||||
if(a.getString(R.styleable.BootstrapButton_android_layout_width) != null) {
|
||||
layoutWidth = a.getInt(R.styleable.BootstrapButton_android_layout_width, 0);
|
||||
}
|
||||
|
||||
//works even if it's fill_parent or match_parent
|
||||
if( (layoutWidth == LayoutParams.MATCH_PARENT)) {
|
||||
fillparent = true;
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapButton_android_textSize) != null) {
|
||||
|
||||
//font sizes
|
||||
String xmlProvidedSize = attrs.getAttributeValue(
|
||||
"http://schemas.android.com/apk/res/android", "textSize");
|
||||
final Pattern PATTERN_FONT_SIZE = Pattern
|
||||
.compile("([0-9]+[.]?[0-9]*)sp");
|
||||
Matcher m = PATTERN_FONT_SIZE.matcher(xmlProvidedSize);
|
||||
|
||||
if (m.find()) {
|
||||
|
||||
if (m.groupCount() == 1) {
|
||||
|
||||
fontSize = Float.valueOf(m.group(1));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
View v = null;
|
||||
if(fillparent){
|
||||
v = inflator.inflate(R.layout.bootstrap_button_fill, null, false);
|
||||
} else {
|
||||
v = inflator.inflate(R.layout.bootstrap_button, null, false);
|
||||
}
|
||||
|
||||
|
||||
//set up font sizes and padding for different button sizes
|
||||
if(size.equals("large")){
|
||||
fontSize = 20.0f;
|
||||
paddingA = (int) (15 *scale + 0.5f);;
|
||||
paddingB = (int) (20 *scale + 0.5f);;
|
||||
}
|
||||
|
||||
if(size.equals("small")){
|
||||
fontSize = 12.0f;
|
||||
paddingA = (int) (5 *scale + 0.5f);;
|
||||
paddingB = (int) (10 *scale + 0.5f);;
|
||||
}
|
||||
|
||||
if(size.equals("xsmall")){
|
||||
fontSize = 10.0f;
|
||||
paddingA = (int) (2 *scale + 0.5f);;
|
||||
paddingB = (int) (5 *scale + 0.5f);;
|
||||
}
|
||||
|
||||
//get layout items
|
||||
layout = (ViewGroup) v.findViewById(R.id.layout);
|
||||
lblLeft = (TextView) v.findViewById(R.id.lblLeft);
|
||||
lblMiddle = (TextView) v.findViewById(R.id.lblMiddle);
|
||||
lblRight = (TextView) v.findViewById(R.id.lblRight);
|
||||
|
||||
//set the background
|
||||
//setBootstrapType(bootstrapType);
|
||||
|
||||
//get the correct background type
|
||||
if(roundedCorners == true)
|
||||
{
|
||||
type = bbuttonTypeMapRounded.get(bootstrapType);
|
||||
} else {
|
||||
type = bbuttonTypeMap.get(bootstrapType);
|
||||
}
|
||||
|
||||
//set up as default
|
||||
if (type == null)
|
||||
{
|
||||
type = BootstrapTypes.DEFAULT;
|
||||
}
|
||||
|
||||
//apply the background type
|
||||
layout.setBackgroundResource(type.backgroundDrawable);
|
||||
lblLeft.setTextColor(getResources().getColor(type.textColour));
|
||||
lblMiddle.setTextColor(getResources().getColor(type.textColour));
|
||||
lblRight.setTextColor(getResources().getColor(type.textColour));
|
||||
|
||||
//set the font awesome icon typeface
|
||||
lblLeft.setTypeface(font);
|
||||
lblRight.setTypeface(font);
|
||||
|
||||
//set up the font size
|
||||
lblLeft.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
|
||||
lblMiddle.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
|
||||
lblRight.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
|
||||
|
||||
//deal with gravity
|
||||
|
||||
if(gravity.length() > 0) {
|
||||
setTextGravity(gravity);
|
||||
}
|
||||
|
||||
|
||||
boolean onlyIcon = true;
|
||||
|
||||
//set the text
|
||||
if(text.length() > 0){
|
||||
lblMiddle.setText(text );
|
||||
lblMiddle.setVisibility(View.VISIBLE);
|
||||
onlyIcon = false;
|
||||
}
|
||||
|
||||
//set up the padding
|
||||
|
||||
if (iconLeft.length() > 0) {
|
||||
//lblLeft.setText(iconLeft);
|
||||
setLeftIcon(iconLeft);
|
||||
lblLeft.setVisibility(View.VISIBLE);
|
||||
|
||||
if (onlyIcon == false){
|
||||
lblLeft.setPadding(paddingB, 0, 0, 0);
|
||||
} else {
|
||||
lblLeft.setPadding(paddingB, 0, paddingB, 0);
|
||||
}
|
||||
|
||||
//padding for symmetry
|
||||
if ( ( iconRight.length() == 0) && onlyIcon == false ) {
|
||||
lblMiddle.setPadding(paddingA, 0, (int) paddingB, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (iconRight.length() > 0) {
|
||||
//lblRight.setText(iconRight);
|
||||
setRightIcon(iconRight);
|
||||
lblRight.setVisibility(View.VISIBLE);
|
||||
|
||||
if (onlyIcon == false){
|
||||
lblRight.setPadding(0, 0, paddingB, 0);
|
||||
}else {
|
||||
lblRight.setPadding(paddingB, 0, paddingB, 0);
|
||||
}
|
||||
|
||||
//padding for symmetry
|
||||
if ( (iconLeft.length() == 0) && onlyIcon == false ) {
|
||||
lblMiddle.setPadding(paddingB, 0, (int) paddingA, 0);
|
||||
}
|
||||
}
|
||||
|
||||
if(iconLeft.length() > 0 && iconRight.length() > 0 )
|
||||
{
|
||||
lblMiddle.setPadding(paddingA, 0, paddingA, 0);
|
||||
}
|
||||
this.setClickable(true);
|
||||
|
||||
this.setEnabled(enabled);
|
||||
|
||||
layout.setPadding(0, paddingB, 0, paddingB);
|
||||
|
||||
addView(v);
|
||||
}
|
||||
|
||||
//static class to read in font
|
||||
private static void readFont(Context context)
|
||||
{
|
||||
|
||||
if(font == null){
|
||||
try {
|
||||
font = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf");
|
||||
} catch (Exception e) {
|
||||
Log.e("BootstrapButton", "Could not get typeface because " + e.getMessage());
|
||||
font = Typeface.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the button text
|
||||
* @param text - String value for what is displayed on the button
|
||||
*/
|
||||
public void setText(String text) {
|
||||
lblMiddle.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the left icon on a BootstrapButton
|
||||
* @param leftIcon- String value for the icon as per http://fortawesome.github.io/Font-Awesome/cheatsheet/
|
||||
*/
|
||||
public void setLeftIcon(String leftIcon) {
|
||||
|
||||
String icon = faMap.get(leftIcon);
|
||||
|
||||
if (icon == null)
|
||||
{
|
||||
icon = faMap.get(FA_ICON_QUESTION);
|
||||
}
|
||||
|
||||
lblLeft.setText(icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the right icon on a BootstrapButton
|
||||
* @param rightIcon - String value for the icon as per http://fortawesome.github.io/Font-Awesome/cheatsheet/
|
||||
*/
|
||||
public void setRightIcon(String rightIcon) {
|
||||
|
||||
String icon = faMap.get(rightIcon);
|
||||
|
||||
if (icon == null)
|
||||
{
|
||||
icon = faMap.get(FA_ICON_QUESTION);
|
||||
}
|
||||
|
||||
lblRight.setText(icon);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the type of BootstrapButton
|
||||
* @param bootstrapType - String value for the type of button e.g. "primary"
|
||||
*/
|
||||
public void setBootstrapType(String bootstrapType) {
|
||||
|
||||
BootstrapTypes type = null;
|
||||
|
||||
//get the correct background type
|
||||
if (roundedCorners == true) {
|
||||
type = bbuttonTypeMapRounded.get(bootstrapType);
|
||||
} else {
|
||||
type = bbuttonTypeMap.get(bootstrapType);
|
||||
}
|
||||
|
||||
//set up as default
|
||||
if (type == null) {
|
||||
type = BootstrapTypes.DEFAULT;
|
||||
}
|
||||
|
||||
|
||||
layout.setBackgroundResource(type.backgroundDrawable);
|
||||
lblLeft.setTextColor(getResources().getColor(type.textColour));
|
||||
lblMiddle.setTextColor(getResources().getColor(type.textColour));
|
||||
lblRight.setTextColor(getResources().getColor(type.textColour));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the BootstrapButton is enabled or disabled
|
||||
* @param enabled - boolean state for either enabled or disabled
|
||||
*/
|
||||
public void setBootstrapButtonEnabled(boolean enabled)
|
||||
{
|
||||
this.setEnabled(enabled);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Changes the gravity for the text on a bootstrap button that is not wrap_content
|
||||
* @param gravity - string for either center, right, or left.
|
||||
*/
|
||||
public void setTextGravity(String gravity) {
|
||||
if(gravity.equals("left")) {
|
||||
lblMiddle.setGravity(Gravity.LEFT | Gravity.CENTER_VERTICAL);
|
||||
} else if (gravity.equals("center")) {
|
||||
lblMiddle.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER_VERTICAL);
|
||||
} else if (gravity.equals("right")) {
|
||||
lblMiddle.setGravity(Gravity.RIGHT | Gravity.CENTER_VERTICAL);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,215 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.beardedhen.androidbootstrap.utils.ImageUtils;
|
||||
|
||||
public class BootstrapCircleThumbnail extends FrameLayout
|
||||
{
|
||||
private static final int PADDING_SMALL = 4;
|
||||
private static final int PADDING_MEDIUM = 4;
|
||||
private static final int PADDING_LARGE = 6;
|
||||
private static final int PADDING_XLARGE = 8;
|
||||
|
||||
private static final int SIZE_SMALL = 48; //dp total size (outer circle)
|
||||
private static final int SIZE_MEDIUM = 80;//dp
|
||||
private static final int SIZE_LARGE = 112;//dp
|
||||
private static final int SIZE_XLARGE = 176;//dp
|
||||
private static final int SIZE_DEFAULT = SIZE_MEDIUM;
|
||||
|
||||
private static final String SMALL = "small";
|
||||
private static final String MEDIUM = "medium";
|
||||
private static final String LARGE = "large";
|
||||
private static final String XLARGE = "xlarge";
|
||||
|
||||
private LinearLayout container;
|
||||
private LinearLayout placeholder;
|
||||
private ImageView image;
|
||||
private TextView dimensionsLabel;
|
||||
private String size = MEDIUM;
|
||||
private boolean minimal = false;//minimal means display just the image, no padding
|
||||
private String text = "";
|
||||
private int imageWidth = SIZE_DEFAULT;
|
||||
private int imageHeight = SIZE_DEFAULT;
|
||||
private int padding = 0;
|
||||
|
||||
public BootstrapCircleThumbnail(Context context, AttributeSet attrs, int defStyle)
|
||||
{
|
||||
super(context, attrs, defStyle);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapCircleThumbnail(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapCircleThumbnail(Context context)
|
||||
{
|
||||
super(context);
|
||||
initialise(null);
|
||||
}
|
||||
|
||||
private void initialise( AttributeSet attrs )
|
||||
{
|
||||
LayoutInflater inflator = (LayoutInflater)getContext().getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||
R.styleable.BootstrapCircleThumbnail);
|
||||
|
||||
|
||||
int imageDrawable = 0;
|
||||
|
||||
if(a.getString(R.styleable.BootstrapCircleThumbnail_bct_image) != null)
|
||||
{
|
||||
imageDrawable = a.getResourceId(R.styleable.BootstrapCircleThumbnail_bct_image, 0);
|
||||
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapCircleThumbnail_android_text) != null)
|
||||
{
|
||||
text = a.getString(R.styleable.BootstrapCircleThumbnail_android_text);
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapCircleThumbnail_bct_size) != null)
|
||||
{
|
||||
this.size = a.getString(R.styleable.BootstrapCircleThumbnail_bct_size);
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapCircleThumbnail_bct_minimal) != null)
|
||||
{
|
||||
this.minimal = a.getBoolean(R.styleable.BootstrapCircleThumbnail_bct_minimal, false);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
|
||||
View v = inflator.inflate(R.layout.bootstrap_thumbnail_circle, null, false);
|
||||
dimensionsLabel = (TextView) v.findViewById(R.id.dimensionsLabel);
|
||||
container = (LinearLayout) v.findViewById(R.id.container);
|
||||
placeholder = (LinearLayout) v.findViewById(R.id.placeholder);
|
||||
image = (ImageView) v.findViewById(R.id.image);
|
||||
float scale = getResources().getDisplayMetrics().density;
|
||||
|
||||
|
||||
|
||||
//small image
|
||||
if(this.size.equals(SMALL))
|
||||
{
|
||||
padding = PADDING_SMALL;
|
||||
imageWidth = SIZE_SMALL;
|
||||
imageHeight = SIZE_SMALL;
|
||||
|
||||
}
|
||||
else if(this.size.equals(MEDIUM))
|
||||
{
|
||||
padding = PADDING_MEDIUM;
|
||||
imageWidth = SIZE_MEDIUM;
|
||||
imageHeight = SIZE_MEDIUM;
|
||||
}
|
||||
else if(this.size.equals(LARGE))
|
||||
{
|
||||
padding = PADDING_LARGE;
|
||||
imageWidth = SIZE_LARGE;
|
||||
imageHeight = SIZE_LARGE;
|
||||
}
|
||||
else if(this.size.equals(XLARGE))
|
||||
{
|
||||
padding = PADDING_XLARGE;
|
||||
imageWidth = SIZE_XLARGE;
|
||||
imageHeight = SIZE_XLARGE;
|
||||
}
|
||||
//no valid size is given, set image to default size
|
||||
else
|
||||
{
|
||||
padding = PADDING_MEDIUM;
|
||||
imageWidth = SIZE_DEFAULT;
|
||||
imageHeight = SIZE_DEFAULT;
|
||||
}
|
||||
|
||||
//convert padding to pixels
|
||||
DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
|
||||
int paddingPX = (int)((padding * scale) + 0.5);
|
||||
|
||||
//convert image size to pixels
|
||||
int imageSizeWidthPX = (int)((imageWidth * scale) + 0.5);
|
||||
int imageSizeHeightPX = (int)((imageHeight * scale) + 0.5);
|
||||
|
||||
//make inner image smaller to compensate for the padding so that entire circle including padding equals the size
|
||||
//ex. small image = 48dp, small padding = 4dp, inner image = 48 - (4 * 2) = 40
|
||||
if(this.minimal == false)
|
||||
{
|
||||
imageSizeWidthPX = imageSizeWidthPX - (paddingPX * 2);
|
||||
imageSizeHeightPX = imageSizeHeightPX - (paddingPX * 2);
|
||||
|
||||
this.container.setPadding(paddingPX, paddingPX, paddingPX, paddingPX);
|
||||
container.setBackgroundResource(R.drawable.thumbnail_circle_container);
|
||||
}
|
||||
else
|
||||
{
|
||||
container.setBackgroundResource(R.drawable.thumbnail_circle_minimal);
|
||||
}
|
||||
|
||||
//if no image is given
|
||||
if(imageDrawable == 0)
|
||||
{
|
||||
this.image.setVisibility(View.GONE);
|
||||
placeholder.setLayoutParams(new LinearLayout.LayoutParams(imageSizeWidthPX, imageSizeHeightPX));
|
||||
placeholder.setPadding(paddingPX, paddingPX, paddingPX, paddingPX);
|
||||
|
||||
//set placeholder image
|
||||
placeholder.setBackgroundResource(R.drawable.thumbnail_circle);
|
||||
|
||||
this.dimensionsLabel.setText(text);
|
||||
}
|
||||
else
|
||||
{
|
||||
placeholder.setPadding(0, 0, 0, 0);
|
||||
this.dimensionsLabel.setVisibility(View.GONE);
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), imageDrawable);
|
||||
|
||||
Bitmap roundBitmap = ImageUtils.getCircleBitmap(bitmap, imageSizeWidthPX, imageSizeHeightPX);
|
||||
image.setImageBitmap(roundBitmap);
|
||||
}
|
||||
|
||||
this.addView(v);
|
||||
}
|
||||
|
||||
public void setImage(int drawable)
|
||||
{
|
||||
Bitmap bitmap = BitmapFactory.decodeResource(getContext().getResources(), drawable);
|
||||
|
||||
float scale = getResources().getDisplayMetrics().density;
|
||||
|
||||
//convert image size to pixels
|
||||
int widthPX = (int)((this.imageWidth * scale) + 0.5);
|
||||
int heightPX = (int)((this.imageHeight * scale) + 0.5);
|
||||
|
||||
int paddingPX = (int)((this.padding * scale) + 0.5);
|
||||
|
||||
if(this.minimal == false)
|
||||
{
|
||||
widthPX = widthPX - (paddingPX * 2);
|
||||
heightPX = heightPX - (paddingPX * 2);
|
||||
}
|
||||
|
||||
Bitmap roundBitmap = ImageUtils.getCircleBitmap(bitmap, widthPX, heightPX);
|
||||
image.setImageBitmap(roundBitmap);
|
||||
|
||||
invalidate();
|
||||
requestLayout();
|
||||
}
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.EditText;
|
||||
|
||||
public class BootstrapEditText extends EditText {
|
||||
|
||||
private boolean roundedCorners = false;
|
||||
|
||||
public BootstrapEditText(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapEditText(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapEditText(Context context) {
|
||||
super(context);
|
||||
initialise(null);
|
||||
}
|
||||
|
||||
public static final String BOOTSTRAP_EDIT_TEXT_DEFAULT = "default";
|
||||
public static final String BOOTSTRAP_EDIT_TEXT_SUCCESS = "success";
|
||||
public static final String BOOTSTRAP_EDIT_TEXT_WARNING = "warning";
|
||||
public static final String BOOTSTRAP_EDIT_TEXT_DANGER = "danger";
|
||||
|
||||
|
||||
private void initialise( AttributeSet attrs )
|
||||
{
|
||||
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.BootstrapEditText);
|
||||
|
||||
//get defaults
|
||||
float fontSize = 14.0f;
|
||||
String state = "default";
|
||||
String text = "";
|
||||
String hint = "";
|
||||
boolean enabled = true;
|
||||
|
||||
//font size
|
||||
if (a.getString(R.styleable.BootstrapEditText_android_textSize) != null) {
|
||||
|
||||
String xmlProvidedSize = attrs.getAttributeValue( "http://schemas.android.com/apk/res/android", "textSize");
|
||||
final Pattern PATTERN_FONT_SIZE = Pattern
|
||||
.compile("([0-9]+[.]?[0-9]*)sp");
|
||||
Matcher m = PATTERN_FONT_SIZE.matcher(xmlProvidedSize);
|
||||
|
||||
if (m.find()) {
|
||||
if (m.groupCount() == 1) {
|
||||
fontSize = Float.valueOf(m.group(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//rounded corners
|
||||
if(a.getString(R.styleable.BootstrapEditText_be_roundedCorners) != null) {
|
||||
roundedCorners = a.getBoolean(R.styleable.BootstrapEditText_be_roundedCorners, false);
|
||||
}
|
||||
|
||||
//state
|
||||
if(a.getString(R.styleable.BootstrapEditText_be_state) != null) {
|
||||
state = a.getString(R.styleable.BootstrapEditText_be_state);
|
||||
}
|
||||
|
||||
//text
|
||||
if(a.getString(R.styleable.BootstrapEditText_android_text) != null) {
|
||||
text = a.getString(R.styleable.BootstrapEditText_android_text);
|
||||
}
|
||||
|
||||
//hint
|
||||
if(a.getString(R.styleable.BootstrapEditText_android_hint) != null) {
|
||||
hint = a.getString(R.styleable.BootstrapEditText_android_hint);
|
||||
}
|
||||
|
||||
//enabled
|
||||
if(a.getString(R.styleable.BootstrapEditText_android_enabled) != null) {
|
||||
enabled = a.getBoolean(R.styleable.BootstrapEditText_android_enabled, true);
|
||||
}
|
||||
|
||||
//set values
|
||||
this.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
|
||||
this.setText(text);
|
||||
this.setHint(hint);
|
||||
this.setEnabled(enabled);
|
||||
|
||||
if (enabled){
|
||||
//work out the right background
|
||||
setBackgroundDrawable(state);
|
||||
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
|
||||
//addView(editTextView);
|
||||
}
|
||||
|
||||
|
||||
private void setBackgroundDrawable(String state)
|
||||
{
|
||||
if(roundedCorners){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_rounded);
|
||||
} else {
|
||||
this.setBackgroundResource(R.drawable.edittext_background);
|
||||
}
|
||||
|
||||
if(roundedCorners){
|
||||
|
||||
if (state.equals(BOOTSTRAP_EDIT_TEXT_SUCCESS)){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_rounded_success);
|
||||
} else if (state.equals(BOOTSTRAP_EDIT_TEXT_WARNING)){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_rounded_warning);
|
||||
} else if (state.equals(BOOTSTRAP_EDIT_TEXT_DANGER)){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_rounded_danger);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (state.equals(BOOTSTRAP_EDIT_TEXT_SUCCESS)){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_success);
|
||||
} else if (state.equals(BOOTSTRAP_EDIT_TEXT_WARNING)){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_warning);
|
||||
} else if (state.equals(BOOTSTRAP_EDIT_TEXT_DANGER)){
|
||||
this.setBackgroundResource(R.drawable.edittext_background_danger);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Change the BootstrapEditTextState
|
||||
* @param state
|
||||
*/
|
||||
public void setState(String state){
|
||||
setBackgroundDrawable(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BootstrapEditText to a successful state
|
||||
*/
|
||||
public void setSuccess()
|
||||
{
|
||||
setBackgroundDrawable(BOOTSTRAP_EDIT_TEXT_SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BootstrapEditText to a warning state
|
||||
*/
|
||||
public void setWarning()
|
||||
{
|
||||
setBackgroundDrawable(BOOTSTRAP_EDIT_TEXT_WARNING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BootstrapEditText to a danger state
|
||||
*/
|
||||
public void setDanger()
|
||||
{
|
||||
setBackgroundDrawable(BOOTSTRAP_EDIT_TEXT_DANGER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the BootstrapEditText to a default state
|
||||
*/
|
||||
public void setDefault()
|
||||
{
|
||||
setBackgroundDrawable(BOOTSTRAP_EDIT_TEXT_DEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether the BootstrapEditText is enabled or disabled
|
||||
* @param enabled - boolean state for either enabled or disabled
|
||||
*/
|
||||
public void setBootstrapEditTextEnabled(boolean enabled)
|
||||
{
|
||||
this.setEnabled(enabled);
|
||||
}
|
||||
|
||||
}
|
@ -1,209 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class BootstrapThumbnail extends FrameLayout
|
||||
{
|
||||
private static final int DEFAULT_WIDTH = 150; //width of thumbnail when no width is given
|
||||
private static final int DEFAULT_HEIGHT = 150;//height of thumbnail when no height is given
|
||||
private static final int DEFAULT_MAX_PADDING = 8; //8dp is max padding size when padding isn't specified by user
|
||||
private static final int DEFAULT_MIN_PADDING = 4; //4dp
|
||||
private static final String DEFAULT_TYPE = "rounded";
|
||||
|
||||
private static Map<String, ThumbnailTypes> bThumbnailTypeMap;
|
||||
private static Typeface font;
|
||||
private ViewGroup container;
|
||||
private LinearLayout placeholder;
|
||||
private TextView dimensionsLabel;
|
||||
private boolean roundedCorners = true;
|
||||
|
||||
static{
|
||||
bThumbnailTypeMap = new HashMap<String, ThumbnailTypes>();
|
||||
|
||||
bThumbnailTypeMap.put("rounded", ThumbnailTypes.ROUNDED);//default is rounded if user doesn't specify to use square
|
||||
bThumbnailTypeMap.put("square", ThumbnailTypes.SQUARE);
|
||||
}
|
||||
|
||||
public BootstrapThumbnail(Context context, AttributeSet attrs, int defStyle)
|
||||
{
|
||||
super(context, attrs, defStyle);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapThumbnail(Context context, AttributeSet attrs)
|
||||
{
|
||||
super(context, attrs);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public BootstrapThumbnail(Context context)
|
||||
{
|
||||
super(context);
|
||||
initialise(null);
|
||||
}
|
||||
|
||||
public void setImage(int drawable)
|
||||
{
|
||||
this.placeholder.setBackgroundResource(drawable);
|
||||
invalidate();
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
//set up the bootstrap types
|
||||
private enum ThumbnailTypes
|
||||
{
|
||||
ROUNDED(R.drawable.bthumbnail_container_rounded, R.drawable.bthumbnail_placeholder_default),
|
||||
SQUARE(R.drawable.bthumbnail_container_square, R.drawable.bthumbnail_placeholder_default);
|
||||
|
||||
private int containerDrawable;
|
||||
private int placeholderDrawable;
|
||||
|
||||
ThumbnailTypes(int containerDrawable, int placeholderDrawable)
|
||||
{
|
||||
this.containerDrawable = containerDrawable;
|
||||
this.placeholderDrawable = placeholderDrawable;
|
||||
}
|
||||
}
|
||||
|
||||
private void initialise( AttributeSet attrs )
|
||||
{
|
||||
LayoutInflater inflator = (LayoutInflater)getContext().getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
readFont(getContext());
|
||||
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs,
|
||||
R.styleable.BootstrapThumbnail);
|
||||
|
||||
//defaults
|
||||
ThumbnailTypes type = null;
|
||||
String thumbnailType = DEFAULT_TYPE;
|
||||
String text = "";
|
||||
int imageDrawable = 0;
|
||||
float scale = getResources().getDisplayMetrics().density; //for padding
|
||||
int width = DEFAULT_WIDTH;
|
||||
int height = DEFAULT_HEIGHT;
|
||||
int padding = 0;
|
||||
int paddingDP = 0;
|
||||
|
||||
//attribute values
|
||||
if(a.getString(R.styleable.BootstrapThumbnail_bt_width) != null) {
|
||||
width = (int) a.getDimension(R.styleable.BootstrapThumbnail_bt_width, 0);
|
||||
Log.v("width", Integer.toString(width));
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapThumbnail_bt_height) != null) {
|
||||
height = (int) a.getDimension(R.styleable.BootstrapThumbnail_bt_height, 0);
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapThumbnail_bt_inside_padding) != null) {
|
||||
paddingDP = (int) a.getDimension(R.styleable.BootstrapThumbnail_bt_inside_padding, 0);
|
||||
}
|
||||
else{
|
||||
padding = (int) (((Math.sqrt(width * height)) / 100) * 2);
|
||||
if(padding > DEFAULT_MAX_PADDING)
|
||||
padding = DEFAULT_MAX_PADDING;
|
||||
if(padding < DEFAULT_MIN_PADDING)
|
||||
padding = DEFAULT_MIN_PADDING;
|
||||
|
||||
paddingDP = (int) (padding * scale + 0.5f);//container padding in DP
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapThumbnail_bt_roundedCorners) != null){
|
||||
roundedCorners = a.getBoolean(R.styleable.BootstrapThumbnail_bt_roundedCorners, false) ;
|
||||
}
|
||||
|
||||
if(a.getString(R.styleable.BootstrapThumbnail_bt_image) != null){
|
||||
imageDrawable = a.getResourceId(R.styleable.BootstrapThumbnail_bt_image, 0);
|
||||
}
|
||||
|
||||
a.recycle();
|
||||
|
||||
text = (int)(width/scale) + "x" + (int)(height/scale);
|
||||
View v = inflator.inflate(R.layout.bootstrap_thumbnail, null, false);
|
||||
|
||||
//get layout items
|
||||
container = (ViewGroup) v.findViewById(R.id.container);
|
||||
placeholder = (LinearLayout) v.findViewById(R.id.placeholder);
|
||||
dimensionsLabel = (TextView) v.findViewById(R.id.dimensionsLabel);
|
||||
|
||||
Log.v("size", "width:" + width + " height:" + height);
|
||||
|
||||
|
||||
type = bThumbnailTypeMap.get(thumbnailType);
|
||||
|
||||
//get the correct background type
|
||||
if(roundedCorners == true)
|
||||
{
|
||||
type = bThumbnailTypeMap.get("rounded");
|
||||
} else {
|
||||
type = bThumbnailTypeMap.get("square");
|
||||
}
|
||||
|
||||
//apply the background type
|
||||
container.setBackgroundResource(type.containerDrawable);
|
||||
|
||||
//if no image is provided by user
|
||||
if(imageDrawable == 0){
|
||||
//set default grey placeholder background
|
||||
placeholder.setBackgroundResource(type.placeholderDrawable);
|
||||
|
||||
//set the text
|
||||
if(text.length() > 0){
|
||||
dimensionsLabel.setText(text);
|
||||
dimensionsLabel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
else{
|
||||
//set background to user's provided image
|
||||
placeholder.setBackgroundResource(imageDrawable);
|
||||
|
||||
//remove textview dimensions
|
||||
dimensionsLabel.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
//placeholder padding
|
||||
int paddingP = (int) (((Math.sqrt(width * height)) / 100) * 4);
|
||||
|
||||
//convert to DP
|
||||
int paddingDPP = (int) (paddingP * scale + 0.5f);//placeholder padding in DP
|
||||
|
||||
container.setPadding(paddingDP, paddingDP, paddingDP, paddingDP);
|
||||
placeholder.setPadding(paddingDPP, paddingDPP, paddingDPP, paddingDPP);
|
||||
|
||||
placeholder.setLayoutParams(new LinearLayout.LayoutParams(width,height));
|
||||
|
||||
//set the font awesome icon typeface
|
||||
dimensionsLabel.setTypeface(font);
|
||||
|
||||
this.setClickable(true);
|
||||
|
||||
addView(v);
|
||||
}
|
||||
|
||||
//static class to read in font
|
||||
private static void readFont(Context context)
|
||||
{
|
||||
if(font == null){
|
||||
try {
|
||||
font = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf");
|
||||
} catch (Exception e) {
|
||||
Log.e("BootstrapButton", "Could not get typeface because " + e.getMessage());
|
||||
font = Typeface.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,390 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class FontAwesome {
|
||||
|
||||
private static Map<String, String> faMap = new HashMap<String, String>();
|
||||
|
||||
//font awesome map as per
|
||||
//http://fortawesome.github.io/Font-Awesome/cheatsheet/
|
||||
|
||||
static {
|
||||
faMap.put("fa-glass", "\uf000");
|
||||
faMap.put("fa-music", "\uf001");
|
||||
faMap.put("fa-search", "\uf002");
|
||||
faMap.put("fa-envelope-o", "\uf003");
|
||||
faMap.put("fa-heart", "\uf004");
|
||||
faMap.put("fa-star", "\uf005");
|
||||
faMap.put("fa-star-o", "\uf006");
|
||||
faMap.put("fa-user", "\uf007");
|
||||
faMap.put("fa-film", "\uf008");
|
||||
faMap.put("fa-th-large", "\uf009");
|
||||
faMap.put("fa-th", "\uf00a");
|
||||
faMap.put("fa-th-list", "\uf00b");
|
||||
faMap.put("fa-check", "\uf00c");
|
||||
faMap.put("fa-times", "\uf00d");
|
||||
faMap.put("fa-search-plus", "\uf00e");
|
||||
faMap.put("fa-search-minus", "\uf010");
|
||||
faMap.put("fa-power-off", "\uf011");
|
||||
faMap.put("fa-signal", "\uf012");
|
||||
faMap.put("fa-cog", "\uf013");
|
||||
faMap.put("fa-trash-o", "\uf014");
|
||||
faMap.put("fa-home", "\uf015");
|
||||
faMap.put("fa-file-o", "\uf016");
|
||||
faMap.put("fa-clock-o", "\uf017");
|
||||
faMap.put("fa-road", "\uf018");
|
||||
faMap.put("fa-download", "\uf019");
|
||||
faMap.put("fa-arrow-circle-o-down", "\uf01a");
|
||||
faMap.put("fa-arrow-circle-o-up", "\uf01b");
|
||||
faMap.put("fa-inbox", "\uf01c");
|
||||
faMap.put("fa-play-circle-o", "\uf01d");
|
||||
faMap.put("fa-repeat", "\uf01e");
|
||||
faMap.put("fa-refresh", "\uf021");
|
||||
faMap.put("fa-list-alt", "\uf022");
|
||||
faMap.put("fa-lock", "\uf023");
|
||||
faMap.put("fa-flag", "\uf024");
|
||||
faMap.put("fa-headphones", "\uf025");
|
||||
faMap.put("fa-volume-off", "\uf026");
|
||||
faMap.put("fa-volume-down", "\uf027");
|
||||
faMap.put("fa-volume-up", "\uf028");
|
||||
faMap.put("fa-qrcode", "\uf029");
|
||||
faMap.put("fa-barcode", "\uf02a");
|
||||
faMap.put("fa-tag", "\uf02b");
|
||||
faMap.put("fa-tags", "\uf02c");
|
||||
faMap.put("fa-book", "\uf02d");
|
||||
faMap.put("fa-bookmark", "\uf02e");
|
||||
faMap.put("fa-print", "\uf02f");
|
||||
faMap.put("fa-camera", "\uf030");
|
||||
faMap.put("fa-font", "\uf031");
|
||||
faMap.put("fa-bold", "\uf032");
|
||||
faMap.put("fa-italic", "\uf033");
|
||||
faMap.put("fa-text-height", "\uf034");
|
||||
faMap.put("fa-text-width", "\uf035");
|
||||
faMap.put("fa-align-left", "\uf036");
|
||||
faMap.put("fa-align-center", "\uf037");
|
||||
faMap.put("fa-align-right", "\uf038");
|
||||
faMap.put("fa-align-justify", "\uf039");
|
||||
faMap.put("fa-list", "\uf03a");
|
||||
faMap.put("fa-outdent", "\uf03b");
|
||||
faMap.put("fa-indent", "\uf03c");
|
||||
faMap.put("fa-video-camera", "\uf03d");
|
||||
faMap.put("fa-picture-o", "\uf03e");
|
||||
faMap.put("fa-pencil", "\uf040");
|
||||
faMap.put("fa-map-marker", "\uf041");
|
||||
faMap.put("fa-adjust", "\uf042");
|
||||
faMap.put("fa-tint", "\uf043");
|
||||
faMap.put("fa-pencil-square-o", "\uf044");
|
||||
faMap.put("fa-share-square-o", "\uf045");
|
||||
faMap.put("fa-check-square-o", "\uf046");
|
||||
faMap.put("fa-move", "\uf047");
|
||||
faMap.put("fa-step-backward", "\uf048");
|
||||
faMap.put("fa-fast-backward", "\uf049");
|
||||
faMap.put("fa-backward", "\uf04a");
|
||||
faMap.put("fa-play", "\uf04b");
|
||||
faMap.put("fa-pause", "\uf04c");
|
||||
faMap.put("fa-stop", "\uf04d");
|
||||
faMap.put("fa-forward", "\uf04e");
|
||||
faMap.put("fa-fast-forward", "\uf050");
|
||||
faMap.put("fa-step-forward", "\uf051");
|
||||
faMap.put("fa-eject", "\uf052");
|
||||
faMap.put("fa-chevron-left", "\uf053");
|
||||
faMap.put("fa-chevron-right", "\uf054");
|
||||
faMap.put("fa-plus-circle", "\uf055");
|
||||
faMap.put("fa-minus-circle", "\uf056");
|
||||
faMap.put("fa-times-circle", "\uf057");
|
||||
faMap.put("fa-check-circle", "\uf058");
|
||||
faMap.put("fa-question-circle", "\uf059");
|
||||
faMap.put("fa-info-circle", "\uf05a");
|
||||
faMap.put("fa-crosshairs", "\uf05b");
|
||||
faMap.put("fa-times-circle-o", "\uf05c");
|
||||
faMap.put("fa-check-circle-o", "\uf05d");
|
||||
faMap.put("fa-ban", "\uf05e");
|
||||
faMap.put("fa-arrow-left", "\uf060");
|
||||
faMap.put("fa-arrow-right", "\uf061");
|
||||
faMap.put("fa-arrow-up", "\uf062");
|
||||
faMap.put("fa-arrow-down", "\uf063");
|
||||
faMap.put("fa-share", "\uf064");
|
||||
faMap.put("fa-resize-full", "\uf065");
|
||||
faMap.put("fa-resize-small", "\uf066");
|
||||
faMap.put("fa-plus", "\uf067");
|
||||
faMap.put("fa-minus", "\uf068");
|
||||
faMap.put("fa-asterisk", "\uf069");
|
||||
faMap.put("fa-exclamation-circle", "\uf06a");
|
||||
faMap.put("fa-gift", "\uf06b");
|
||||
faMap.put("fa-leaf", "\uf06c");
|
||||
faMap.put("fa-fire", "\uf06d");
|
||||
faMap.put("fa-eye", "\uf06e");
|
||||
faMap.put("fa-eye-slash", "\uf070");
|
||||
faMap.put("fa-exclamation-triangle", "\uf071");
|
||||
faMap.put("fa-plane", "\uf072");
|
||||
faMap.put("fa-calendar", "\uf073");
|
||||
faMap.put("fa-random", "\uf074");
|
||||
faMap.put("fa-comment", "\uf075");
|
||||
faMap.put("fa-magnet", "\uf076");
|
||||
faMap.put("fa-chevron-up", "\uf077");
|
||||
faMap.put("fa-chevron-down", "\uf078");
|
||||
faMap.put("fa-retweet", "\uf079");
|
||||
faMap.put("fa-shopping-cart", "\uf07a");
|
||||
faMap.put("fa-folder", "\uf07b");
|
||||
faMap.put("fa-folder-open", "\uf07c");
|
||||
faMap.put("fa-resize-vertical", "\uf07d");
|
||||
faMap.put("fa-resize-horizontal", "\uf07e");
|
||||
faMap.put("fa-bar-chart-o", "\uf080");
|
||||
faMap.put("fa-twitter-square", "\uf081");
|
||||
faMap.put("fa-facebook-square", "\uf082");
|
||||
faMap.put("fa-camera-retro", "\uf083");
|
||||
faMap.put("fa-key", "\uf084");
|
||||
faMap.put("fa-cogs", "\uf085");
|
||||
faMap.put("fa-comments", "\uf086");
|
||||
faMap.put("fa-thumbs-o-up", "\uf087");
|
||||
faMap.put("fa-thumbs-o-down", "\uf088");
|
||||
faMap.put("fa-star-half", "\uf089");
|
||||
faMap.put("fa-heart-o", "\uf08a");
|
||||
faMap.put("fa-sign-out", "\uf08b");
|
||||
faMap.put("fa-linkedin-square", "\uf08c");
|
||||
faMap.put("fa-thumb-tack", "\uf08d");
|
||||
faMap.put("fa-external-link", "\uf08e");
|
||||
faMap.put("fa-sign-in", "\uf090");
|
||||
faMap.put("fa-trophy", "\uf091");
|
||||
faMap.put("fa-github-square", "\uf092");
|
||||
faMap.put("fa-upload", "\uf093");
|
||||
faMap.put("fa-lemon-o", "\uf094");
|
||||
faMap.put("fa-phone", "\uf095");
|
||||
faMap.put("fa-square-o", "\uf096");
|
||||
faMap.put("fa-bookmark-o", "\uf097");
|
||||
faMap.put("fa-phone-square", "\uf098");
|
||||
faMap.put("fa-twitter", "\uf099");
|
||||
faMap.put("fa-facebook", "\uf09a");
|
||||
faMap.put("fa-github", "\uf09b");
|
||||
faMap.put("fa-unlock", "\uf09c");
|
||||
faMap.put("fa-credit-card", "\uf09d");
|
||||
faMap.put("fa-rss", "\uf09e");
|
||||
faMap.put("fa-hdd", "\uf0a0");
|
||||
faMap.put("fa-bullhorn", "\uf0a1");
|
||||
faMap.put("fa-bell", "\uf0f3");
|
||||
faMap.put("fa-certificate", "\uf0a3");
|
||||
faMap.put("fa-hand-o-right", "\uf0a4");
|
||||
faMap.put("fa-hand-o-left", "\uf0a5");
|
||||
faMap.put("fa-hand-o-up", "\uf0a6");
|
||||
faMap.put("fa-hand-o-down", "\uf0a7");
|
||||
faMap.put("fa-arrow-circle-left", "\uf0a8");
|
||||
faMap.put("fa-arrow-circle-right", "\uf0a9");
|
||||
faMap.put("fa-arrow-circle-up", "\uf0aa");
|
||||
faMap.put("fa-arrow-circle-down", "\uf0ab");
|
||||
faMap.put("fa-globe", "\uf0ac");
|
||||
faMap.put("fa-wrench", "\uf0ad");
|
||||
faMap.put("fa-tasks", "\uf0ae");
|
||||
faMap.put("fa-filter", "\uf0b0");
|
||||
faMap.put("fa-briefcase", "\uf0b1");
|
||||
faMap.put("fa-fullscreen", "\uf0b2");
|
||||
faMap.put("fa-group", "\uf0c0");
|
||||
faMap.put("fa-link", "\uf0c1");
|
||||
faMap.put("fa-cloud", "\uf0c2");
|
||||
faMap.put("fa-flask", "\uf0c3");
|
||||
faMap.put("fa-scissors", "\uf0c4");
|
||||
faMap.put("fa-files-o", "\uf0c5");
|
||||
faMap.put("fa-paperclip", "\uf0c6");
|
||||
faMap.put("fa-floppy-o", "\uf0c7");
|
||||
faMap.put("fa-square", "\uf0c8");
|
||||
faMap.put("fa-reorder", "\uf0c9");
|
||||
faMap.put("fa-list-ul", "\uf0ca");
|
||||
faMap.put("fa-list-ol", "\uf0cb");
|
||||
faMap.put("fa-strikethrough", "\uf0cc");
|
||||
faMap.put("fa-underline", "\uf0cd");
|
||||
faMap.put("fa-table", "\uf0ce");
|
||||
faMap.put("fa-magic", "\uf0d0");
|
||||
faMap.put("fa-truck", "\uf0d1");
|
||||
faMap.put("fa-pinterest", "\uf0d2");
|
||||
faMap.put("fa-pinterest-square", "\uf0d3");
|
||||
faMap.put("fa-google-plus-square", "\uf0d4");
|
||||
faMap.put("fa-google-plus", "\uf0d5");
|
||||
faMap.put("fa-money", "\uf0d6");
|
||||
faMap.put("fa-caret-down", "\uf0d7");
|
||||
faMap.put("fa-caret-up", "\uf0d8");
|
||||
faMap.put("fa-caret-left", "\uf0d9");
|
||||
faMap.put("fa-caret-right", "\uf0da");
|
||||
faMap.put("fa-columns", "\uf0db");
|
||||
faMap.put("fa-sort", "\uf0dc");
|
||||
faMap.put("fa-sort-asc", "\uf0dd");
|
||||
faMap.put("fa-sort-desc", "\uf0de");
|
||||
faMap.put("fa-envelope", "\uf0e0");
|
||||
faMap.put("fa-linkedin", "\uf0e1");
|
||||
faMap.put("fa-undo", "\uf0e2");
|
||||
faMap.put("fa-gavel", "\uf0e3");
|
||||
faMap.put("fa-tachometer", "\uf0e4");
|
||||
faMap.put("fa-comment-o", "\uf0e5");
|
||||
faMap.put("fa-comments-o", "\uf0e6");
|
||||
faMap.put("fa-bolt", "\uf0e7");
|
||||
faMap.put("fa-sitemap", "\uf0e8");
|
||||
faMap.put("fa-umbrella", "\uf0e9");
|
||||
faMap.put("fa-clipboard", "\uf0ea");
|
||||
faMap.put("fa-lightbulb-o", "\uf0eb");
|
||||
faMap.put("fa-exchange", "\uf0ec");
|
||||
faMap.put("fa-cloud-download", "\uf0ed");
|
||||
faMap.put("fa-cloud-upload", "\uf0ee");
|
||||
faMap.put("fa-user-md", "\uf0f0");
|
||||
faMap.put("fa-stethoscope", "\uf0f1");
|
||||
faMap.put("fa-suitcase", "\uf0f2");
|
||||
faMap.put("fa-bell-o", "\uf0a2");
|
||||
faMap.put("fa-coffee", "\uf0f4");
|
||||
faMap.put("fa-cutlery", "\uf0f5");
|
||||
faMap.put("fa-file-text-o", "\uf0f6");
|
||||
faMap.put("fa-building", "\uf0f7");
|
||||
faMap.put("fa-hospital", "\uf0f8");
|
||||
faMap.put("fa-ambulance", "\uf0f9");
|
||||
faMap.put("fa-medkit", "\uf0fa");
|
||||
faMap.put("fa-fighter-jet", "\uf0fb");
|
||||
faMap.put("fa-beer", "\uf0fc");
|
||||
faMap.put("fa-h-square", "\uf0fd");
|
||||
faMap.put("fa-plus-square", "\uf0fe");
|
||||
faMap.put("fa-angle-double-left", "\uf100");
|
||||
faMap.put("fa-angle-double-right", "\uf101");
|
||||
faMap.put("fa-angle-double-up", "\uf102");
|
||||
faMap.put("fa-angle-double-down", "\uf103");
|
||||
faMap.put("fa-angle-left", "\uf104");
|
||||
faMap.put("fa-angle-right", "\uf105");
|
||||
faMap.put("fa-angle-up", "\uf106");
|
||||
faMap.put("fa-angle-down", "\uf107");
|
||||
faMap.put("fa-desktop", "\uf108");
|
||||
faMap.put("fa-laptop", "\uf109");
|
||||
faMap.put("fa-tablet", "\uf10a");
|
||||
faMap.put("fa-mobile", "\uf10b");
|
||||
faMap.put("fa-circle-o", "\uf10c");
|
||||
faMap.put("fa-quote-left", "\uf10d");
|
||||
faMap.put("fa-quote-right", "\uf10e");
|
||||
faMap.put("fa-spinner", "\uf110");
|
||||
faMap.put("fa-circle", "\uf111");
|
||||
faMap.put("fa-reply", "\uf112");
|
||||
faMap.put("fa-github-alt", "\uf113");
|
||||
faMap.put("fa-folder-o", "\uf114");
|
||||
faMap.put("fa-folder-open-o", "\uf115");
|
||||
faMap.put("fa-expand-o", "\uf116");
|
||||
faMap.put("fa-collapse-o", "\uf117");
|
||||
faMap.put("fa-smile-o", "\uf118");
|
||||
faMap.put("fa-frown-o", "\uf119");
|
||||
faMap.put("fa-meh-o", "\uf11a");
|
||||
faMap.put("fa-gamepad", "\uf11b");
|
||||
faMap.put("fa-keyboard-o", "\uf11c");
|
||||
faMap.put("fa-flag-o", "\uf11d");
|
||||
faMap.put("fa-flag-checkered", "\uf11e");
|
||||
faMap.put("fa-terminal", "\uf120");
|
||||
faMap.put("fa-code", "\uf121");
|
||||
faMap.put("fa-reply-all", "\uf122");
|
||||
faMap.put("fa-mail-reply-all", "\uf122");
|
||||
faMap.put("fa-star-half-o", "\uf123");
|
||||
faMap.put("fa-location-arrow", "\uf124");
|
||||
faMap.put("fa-crop", "\uf125");
|
||||
faMap.put("fa-code-fork", "\uf126");
|
||||
faMap.put("fa-chain-broken", "\uf127");
|
||||
faMap.put("fa-question", "\uf128");
|
||||
faMap.put("fa-info", "\uf129");
|
||||
faMap.put("fa-exclamation", "\uf12a");
|
||||
faMap.put("fa-superscript", "\uf12b");
|
||||
faMap.put("fa-subscript", "\uf12c");
|
||||
faMap.put("fa-eraser", "\uf12d");
|
||||
faMap.put("fa-puzzle-piece", "\uf12e");
|
||||
faMap.put("fa-microphone", "\uf130");
|
||||
faMap.put("fa-microphone-slash", "\uf131");
|
||||
faMap.put("fa-shield", "\uf132");
|
||||
faMap.put("fa-calendar-o", "\uf133");
|
||||
faMap.put("fa-fire-extinguisher", "\uf134");
|
||||
faMap.put("fa-rocket", "\uf135");
|
||||
faMap.put("fa-maxcdn", "\uf136");
|
||||
faMap.put("fa-chevron-circle-left", "\uf137");
|
||||
faMap.put("fa-chevron-circle-right", "\uf138");
|
||||
faMap.put("fa-chevron-circle-up", "\uf139");
|
||||
faMap.put("fa-chevron-circle-down", "\uf13a");
|
||||
faMap.put("fa-html5", "\uf13b");
|
||||
faMap.put("fa-css3", "\uf13c");
|
||||
faMap.put("fa-anchor", "\uf13d");
|
||||
faMap.put("fa-unlock-o", "\uf13e");
|
||||
faMap.put("fa-bullseye", "\uf140");
|
||||
faMap.put("fa-ellipsis-horizontal", "\uf141");
|
||||
faMap.put("fa-ellipsis-vertical", "\uf142");
|
||||
faMap.put("fa-rss-square", "\uf143");
|
||||
faMap.put("fa-play-circle", "\uf144");
|
||||
faMap.put("fa-ticket", "\uf145");
|
||||
faMap.put("fa-minus-square", "\uf146");
|
||||
faMap.put("fa-minus-square-o", "\uf147");
|
||||
faMap.put("fa-level-up", "\uf148");
|
||||
faMap.put("fa-level-down", "\uf149");
|
||||
faMap.put("fa-check-square", "\uf14a");
|
||||
faMap.put("fa-pencil-square", "\uf14b");
|
||||
faMap.put("fa-external-link-square", "\uf14c");
|
||||
faMap.put("fa-share-square", "\uf14d");
|
||||
faMap.put("fa-compass", "\uf14e");
|
||||
faMap.put("fa-caret-square-o-down", "\uf150");
|
||||
faMap.put("fa-caret-square-o-up", "\uf151");
|
||||
faMap.put("fa-caret-square-o-right", "\uf152");
|
||||
faMap.put("fa-eur", "\uf153");
|
||||
faMap.put("fa-gbp", "\uf154");
|
||||
faMap.put("fa-usd", "\uf155");
|
||||
faMap.put("fa-inr", "\uf156");
|
||||
faMap.put("fa-jpy", "\uf157");
|
||||
faMap.put("fa-rub", "\uf158");
|
||||
faMap.put("fa-krw", "\uf159");
|
||||
faMap.put("fa-btc", "\uf15a");
|
||||
faMap.put("fa-file", "\uf15b");
|
||||
faMap.put("fa-file-text", "\uf15c");
|
||||
faMap.put("fa-sort-alpha-asc", "\uf15d");
|
||||
faMap.put("fa-sort-alpha-desc", "\uf15e");
|
||||
faMap.put("fa-sort-amount-asc", "\uf160");
|
||||
faMap.put("fa-sort-amount-desc", "\uf161");
|
||||
faMap.put("fa-sort-numeric-asc", "\uf162");
|
||||
faMap.put("fa-sort-numeric-desc", "\uf163");
|
||||
faMap.put("fa-thumbs-up", "\uf164");
|
||||
faMap.put("fa-thumbs-down", "\uf165");
|
||||
faMap.put("fa-youtube-square", "\uf166");
|
||||
faMap.put("fa-youtube", "\uf167");
|
||||
faMap.put("fa-xing", "\uf168");
|
||||
faMap.put("fa-xing-square", "\uf169");
|
||||
faMap.put("fa-youtube-play", "\uf16a");
|
||||
faMap.put("fa-dropbox", "\uf16b");
|
||||
faMap.put("fa-stack-overflow", "\uf16c");
|
||||
faMap.put("fa-instagram", "\uf16d");
|
||||
faMap.put("fa-flickr", "\uf16e");
|
||||
faMap.put("fa-adn", "\uf170");
|
||||
faMap.put("fa-bitbucket", "\uf171");
|
||||
faMap.put("fa-bitbucket-square", "\uf172");
|
||||
faMap.put("fa-tumblr", "\uf173");
|
||||
faMap.put("fa-tumblr-square", "\uf174");
|
||||
faMap.put("fa-long-arrow-down", "\uf175");
|
||||
faMap.put("fa-long-arrow-up", "\uf176");
|
||||
faMap.put("fa-long-arrow-left", "\uf177");
|
||||
faMap.put("fa-long-arrow-right", "\uf178");
|
||||
faMap.put("fa-apple", "\uf179");
|
||||
faMap.put("fa-windows", "\uf17a");
|
||||
faMap.put("fa-android", "\uf17b");
|
||||
faMap.put("fa-linux", "\uf17c");
|
||||
faMap.put("fa-dribbble", "\uf17d");
|
||||
faMap.put("fa-skype", "\uf17e");
|
||||
faMap.put("fa-foursquare", "\uf180");
|
||||
faMap.put("fa-trello", "\uf181");
|
||||
faMap.put("fa-female", "\uf182");
|
||||
faMap.put("fa-male", "\uf183");
|
||||
faMap.put("fa-gittip", "\uf184");
|
||||
faMap.put("fa-sun-o", "\uf185");
|
||||
faMap.put("fa-moon-o", "\uf186");
|
||||
faMap.put("fa-archive", "\uf187");
|
||||
faMap.put("fa-bug", "\uf188");
|
||||
faMap.put("fa-vk", "\uf189");
|
||||
faMap.put("fa-weibo", "\uf18a");
|
||||
faMap.put("fa-renren", "\uf18b");
|
||||
faMap.put("fa-pagelines", "\uf18c");
|
||||
faMap.put("fa-stack-exchange", "\uf18d");
|
||||
faMap.put("fa-arrow-circle-o-right", "\uf18e");
|
||||
faMap.put("fa-arrow-circle-o-left", "\uf190");
|
||||
faMap.put("fa-caret-square-o-left", "\uf191");
|
||||
faMap.put("fa-dot-circle-o", "\uf192");
|
||||
faMap.put("fa-wheelchair", "\uf193");
|
||||
faMap.put("fa-vimeo-square", "\uf194");
|
||||
}
|
||||
|
||||
public static Map<String, String> getFaMap()
|
||||
{
|
||||
return faMap;
|
||||
}
|
||||
|
||||
}
|
@ -1,274 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Typeface;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.util.TypedValue;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
import android.view.animation.Animation;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.view.animation.RotateAnimation;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.beardedhen.androidbootstrap.R;
|
||||
|
||||
public class FontAwesomeText extends FrameLayout {
|
||||
|
||||
private static Typeface font;
|
||||
private static Map<String, String> faMap;
|
||||
|
||||
private TextView tv;
|
||||
|
||||
private static final String FA_ICON_QUESTION = "fa-question";
|
||||
|
||||
public enum AnimationSpeed
|
||||
{
|
||||
FAST,
|
||||
MEDIUM,
|
||||
SLOW;
|
||||
}
|
||||
|
||||
static{
|
||||
faMap = FontAwesome.getFaMap();
|
||||
}
|
||||
|
||||
public FontAwesomeText(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public FontAwesomeText(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialise(attrs);
|
||||
}
|
||||
|
||||
public FontAwesomeText(Context context) {
|
||||
super(context);
|
||||
initialise(null);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private void initialise( AttributeSet attrs )
|
||||
{
|
||||
LayoutInflater inflator = (LayoutInflater)getContext().getSystemService(
|
||||
Context.LAYOUT_INFLATER_SERVICE);
|
||||
|
||||
//get font
|
||||
readFont(getContext());
|
||||
|
||||
TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.FontAwesomeText);
|
||||
|
||||
//inflate the view
|
||||
View fontAwesomeTextView = inflator.inflate(R.layout.font_awesome_text, null, false);
|
||||
tv = (TextView)fontAwesomeTextView.findViewById(R.id.lblText);
|
||||
|
||||
String icon = "";
|
||||
float fontSize = 14.0f;
|
||||
|
||||
//icon
|
||||
if (a.getString(R.styleable.FontAwesomeText_fa_icon) != null) {
|
||||
icon = a.getString(R.styleable.FontAwesomeText_fa_icon);
|
||||
}
|
||||
|
||||
//font size
|
||||
if (a.getString(R.styleable.FontAwesomeText_android_textSize) != null) {
|
||||
|
||||
String xmlProvidedSize = attrs.getAttributeValue(
|
||||
"http://schemas.android.com/apk/res/android", "textSize");
|
||||
final Pattern PATTERN_FONT_SIZE = Pattern
|
||||
.compile("([0-9]+[.]?[0-9]*)sp");
|
||||
Matcher m = PATTERN_FONT_SIZE.matcher(xmlProvidedSize);
|
||||
|
||||
if (m.find()) {
|
||||
if (m.groupCount() == 1) {
|
||||
fontSize = Float.valueOf(m.group(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//text colour
|
||||
if(a.getString(R.styleable.FontAwesomeText_android_textColor) != null){
|
||||
tv.setTextColor(a.getColor(R.styleable.FontAwesomeText_android_textColor, R.color.bbutton_inverse));
|
||||
}
|
||||
|
||||
setIcon(icon);
|
||||
|
||||
tv.setTypeface(font);
|
||||
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, fontSize);
|
||||
|
||||
a.recycle();
|
||||
addView(fontAwesomeTextView);
|
||||
}
|
||||
|
||||
private static void readFont(Context context)
|
||||
{
|
||||
|
||||
if(font == null){
|
||||
try {
|
||||
font = Typeface.createFromAsset(context.getAssets(), "fontawesome-webfont.ttf");
|
||||
} catch (Exception e) {
|
||||
Log.e("BButton", "Could not get typeface because " + e.getMessage());
|
||||
font = Typeface.DEFAULT;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to start flashing a FontAwesomeText item
|
||||
* @param context the current applications context
|
||||
* @param forever whether the item should flash repeatedly or just once
|
||||
* @param speed how fast the item should flash, chose between FontAwesomeText.AnimationSpeed.SLOW /
|
||||
* FontAwesomeText.AnimationSpeed.MEDIUM / FontAwesomeText.AnimationSpeed.FAST
|
||||
*/
|
||||
public void startFlashing(Context context, boolean forever, AnimationSpeed speed)
|
||||
{
|
||||
|
||||
Animation fadeIn = new AlphaAnimation(0, 1);
|
||||
|
||||
//set up extra variables
|
||||
fadeIn.setDuration(50);
|
||||
fadeIn.setRepeatMode(Animation.REVERSE);
|
||||
|
||||
//default repeat count is 0, however if user wants, set it up to be infinite
|
||||
fadeIn.setRepeatCount(0);
|
||||
if (forever){
|
||||
fadeIn.setRepeatCount(Animation.INFINITE);
|
||||
}
|
||||
|
||||
//default speed
|
||||
fadeIn.setStartOffset(1000);
|
||||
|
||||
//fast
|
||||
if (speed.equals(AnimationSpeed.FAST))
|
||||
{
|
||||
fadeIn.setStartOffset(200);
|
||||
}
|
||||
|
||||
//medium
|
||||
if (speed.equals(AnimationSpeed.MEDIUM))
|
||||
{
|
||||
fadeIn.setStartOffset(500);
|
||||
}
|
||||
|
||||
//set the new animation to a final animation
|
||||
final Animation animation = fadeIn;
|
||||
|
||||
//run the animation - used to work correctly on older devices
|
||||
tv.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tv.startAnimation(animation);
|
||||
}
|
||||
}, 100);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to start rotating a FontAwesomeText item
|
||||
* @param context the current applications context
|
||||
* @param clockwise true for clockwise, false for anti clockwise spinning
|
||||
* @param speed how fast the item should flash, chose between FontAwesomeText.AnimationSpeed.SLOW /
|
||||
* FontAwesomeText.AnimationSpeed.MEDIUM / FontAwesomeText.AnimationSpeed.FAST
|
||||
*/
|
||||
public void startRotate(Context context, boolean clockwise, AnimationSpeed speed)
|
||||
{
|
||||
Animation rotate;
|
||||
|
||||
//set up the rotation animation
|
||||
if (clockwise){
|
||||
rotate = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
|
||||
} else {
|
||||
rotate = new RotateAnimation(360, 0, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,0.5f);
|
||||
}
|
||||
|
||||
//set up some extra variables
|
||||
rotate.setRepeatCount(Animation.INFINITE);
|
||||
rotate.setInterpolator(new LinearInterpolator());
|
||||
rotate.setStartOffset(0);
|
||||
rotate.setRepeatMode(Animation.RESTART);
|
||||
|
||||
//defaults
|
||||
rotate.setDuration(2000);
|
||||
|
||||
//fast
|
||||
if (speed.equals(AnimationSpeed.FAST))
|
||||
{
|
||||
rotate.setDuration(500);
|
||||
}
|
||||
|
||||
//medium
|
||||
if (speed.equals(AnimationSpeed.MEDIUM))
|
||||
{
|
||||
rotate.setDuration(1000);
|
||||
}
|
||||
|
||||
//send the new animation to a final animation
|
||||
final Animation animation = rotate;
|
||||
|
||||
//run the animation - used to work correctly on older devices
|
||||
tv.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tv.startAnimation(animation);
|
||||
}
|
||||
}, 100);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to stop animating any FontAwesomeText item
|
||||
*/
|
||||
public void stopAnimation(){
|
||||
//stop the animation
|
||||
tv.clearAnimation();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Used to set the icon for a FontAwesomeText item
|
||||
* @param faIcon - String value for the icon as per http://fortawesome.github.io/Font-Awesome/cheatsheet/
|
||||
*/
|
||||
public void setIcon(String faIcon) {
|
||||
|
||||
String icon = faMap.get(faIcon);
|
||||
|
||||
if (icon == null)
|
||||
{
|
||||
icon = faMap.get(FA_ICON_QUESTION);
|
||||
}
|
||||
|
||||
tv.setText(icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the text color of the underlying text view.
|
||||
* @param color - Integer value representing a color resource.
|
||||
*/
|
||||
public void setTextColor(int color) {
|
||||
tv.setTextColor(color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Used to set the text size of the underlying text view.
|
||||
* @param unit - Integer value representing a unit size
|
||||
* @param size - Float value representing text size
|
||||
*/
|
||||
public void setTextSize(int unit, float size) {
|
||||
tv.setTextSize(unit, size);
|
||||
}
|
||||
|
||||
}
|
@ -1,303 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap.utils;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.RectF;
|
||||
import android.os.Build;
|
||||
import android.text.Layout.Alignment;
|
||||
import android.text.StaticLayout;
|
||||
import android.text.TextPaint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.SparseIntArray;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
*
|
||||
* Code from user M-WaJeEh on StackOverflow at
|
||||
* http://stackoverflow.com/questions/5033012/auto-scale-textview-text-to-fit-within-bounds/17782522#17782522
|
||||
*
|
||||
*/
|
||||
|
||||
public class AutoResizeTextView extends TextView {
|
||||
private interface SizeTester {
|
||||
/**
|
||||
*
|
||||
* @param suggestedSize
|
||||
* Size of text to be tested
|
||||
* @param availableSpace
|
||||
* available space in which text must fit
|
||||
* @return an integer < 0 if after applying {@code suggestedSize} to
|
||||
* text, it takes less space than {@code availableSpace}, > 0
|
||||
* otherwise
|
||||
*/
|
||||
public int onTestSize(int suggestedSize, RectF availableSpace);
|
||||
}
|
||||
|
||||
private RectF mTextRect = new RectF();
|
||||
|
||||
private RectF mAvailableSpaceRect;
|
||||
|
||||
private SparseIntArray mTextCachedSizes;
|
||||
|
||||
private TextPaint mPaint;
|
||||
|
||||
private float mMaxTextSize;
|
||||
|
||||
private float mSpacingMult = 1.0f;
|
||||
|
||||
private float mSpacingAdd = 0.0f;
|
||||
|
||||
private float mMinTextSize = 20;
|
||||
|
||||
private int mWidthLimit;
|
||||
|
||||
private static final int NO_LINE_LIMIT = -1;
|
||||
private int mMaxLines;
|
||||
|
||||
private boolean mEnableSizeCache = true;
|
||||
private boolean mInitiallized;
|
||||
|
||||
public AutoResizeTextView(Context context) {
|
||||
super(context);
|
||||
initialize();
|
||||
}
|
||||
|
||||
public AutoResizeTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialize();
|
||||
}
|
||||
|
||||
public AutoResizeTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
mPaint = new TextPaint(getPaint());
|
||||
mMaxTextSize = getTextSize();
|
||||
mAvailableSpaceRect = new RectF();
|
||||
mTextCachedSizes = new SparseIntArray();
|
||||
if (mMaxLines == 0) {
|
||||
// no value was assigned during construction
|
||||
mMaxLines = NO_LINE_LIMIT;
|
||||
}
|
||||
mInitiallized = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setText(final CharSequence text, BufferType type) {
|
||||
super.setText(text, type);
|
||||
adjustTextSize(text.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTextSize(float size) {
|
||||
mMaxTextSize = size;
|
||||
mTextCachedSizes.clear();
|
||||
adjustTextSize(getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxLines(int maxlines) {
|
||||
super.setMaxLines(maxlines);
|
||||
mMaxLines = maxlines;
|
||||
reAdjust();
|
||||
}
|
||||
|
||||
public int getMaxLines() {
|
||||
return mMaxLines;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSingleLine() {
|
||||
super.setSingleLine();
|
||||
mMaxLines = 1;
|
||||
reAdjust();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSingleLine(boolean singleLine) {
|
||||
super.setSingleLine(singleLine);
|
||||
if (singleLine) {
|
||||
mMaxLines = 1;
|
||||
} else {
|
||||
mMaxLines = NO_LINE_LIMIT;
|
||||
}
|
||||
reAdjust();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLines(int lines) {
|
||||
super.setLines(lines);
|
||||
mMaxLines = lines;
|
||||
reAdjust();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTextSize(int unit, float size) {
|
||||
Context c = getContext();
|
||||
Resources r;
|
||||
|
||||
if (c == null)
|
||||
r = Resources.getSystem();
|
||||
else
|
||||
r = c.getResources();
|
||||
mMaxTextSize = TypedValue.applyDimension(unit, size,
|
||||
r.getDisplayMetrics());
|
||||
mTextCachedSizes.clear();
|
||||
adjustTextSize(getText().toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLineSpacing(float add, float mult) {
|
||||
super.setLineSpacing(add, mult);
|
||||
mSpacingMult = mult;
|
||||
mSpacingAdd = add;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the lower text size limit and invalidate the view
|
||||
*
|
||||
* @param minTextSize
|
||||
*/
|
||||
public void setMinTextSize(float minTextSize) {
|
||||
mMinTextSize = minTextSize;
|
||||
reAdjust();
|
||||
}
|
||||
|
||||
private void reAdjust() {
|
||||
adjustTextSize(getText().toString());
|
||||
}
|
||||
|
||||
private void adjustTextSize(String string) {
|
||||
if (!mInitiallized) {
|
||||
return;
|
||||
}
|
||||
int startSize = (int) mMinTextSize;
|
||||
int heightLimit = getMeasuredHeight() - getCompoundPaddingBottom()
|
||||
- getCompoundPaddingTop();
|
||||
mWidthLimit = getMeasuredWidth() - getCompoundPaddingLeft()
|
||||
- getCompoundPaddingRight();
|
||||
mAvailableSpaceRect.right = mWidthLimit;
|
||||
mAvailableSpaceRect.bottom = heightLimit;
|
||||
super.setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
efficientTextSizeSearch(startSize, (int) mMaxTextSize,
|
||||
mSizeTester, mAvailableSpaceRect));
|
||||
}
|
||||
|
||||
private final SizeTester mSizeTester = new SizeTester() {
|
||||
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
|
||||
@Override
|
||||
public int onTestSize(int suggestedSize, RectF availableSPace) {
|
||||
mPaint.setTextSize(suggestedSize);
|
||||
String text = getText().toString();
|
||||
boolean singleline = getMaxLines() == 1;
|
||||
if (singleline) {
|
||||
mTextRect.bottom = mPaint.getFontSpacing();
|
||||
mTextRect.right = mPaint.measureText(text);
|
||||
} else {
|
||||
StaticLayout layout = new StaticLayout(text, mPaint,
|
||||
mWidthLimit, Alignment.ALIGN_NORMAL, mSpacingMult,
|
||||
mSpacingAdd, true);
|
||||
// return early if we have more lines
|
||||
if (getMaxLines() != NO_LINE_LIMIT
|
||||
&& layout.getLineCount() > getMaxLines()) {
|
||||
return 1;
|
||||
}
|
||||
mTextRect.bottom = layout.getHeight();
|
||||
int maxWidth = -1;
|
||||
for (int i = 0; i < layout.getLineCount(); i++) {
|
||||
if (maxWidth < layout.getLineWidth(i)) {
|
||||
maxWidth = (int) layout.getLineWidth(i);
|
||||
}
|
||||
}
|
||||
mTextRect.right = maxWidth;
|
||||
}
|
||||
|
||||
mTextRect.offsetTo(0, 0);
|
||||
if (availableSPace.contains(mTextRect)) {
|
||||
// may be too small, don't worry we will find the best match
|
||||
return -1;
|
||||
} else {
|
||||
// too big
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Enables or disables size caching, enabling it will improve performance
|
||||
* where you are animating a value inside TextView. This stores the font
|
||||
* size against getText().length() Be careful though while enabling it as 0
|
||||
* takes more space than 1 on some fonts and so on.
|
||||
*
|
||||
* @param enable
|
||||
* enable font size caching
|
||||
*/
|
||||
public void enableSizeCache(boolean enable) {
|
||||
mEnableSizeCache = enable;
|
||||
mTextCachedSizes.clear();
|
||||
adjustTextSize(getText().toString());
|
||||
}
|
||||
|
||||
private int efficientTextSizeSearch(int start, int end,
|
||||
SizeTester sizeTester, RectF availableSpace) {
|
||||
if (!mEnableSizeCache) {
|
||||
return binarySearch(start, end, sizeTester, availableSpace);
|
||||
}
|
||||
String text = getText().toString();
|
||||
int key = text == null ? 0 : text.length();
|
||||
int size = mTextCachedSizes.get(key);
|
||||
if (size != 0) {
|
||||
return size;
|
||||
}
|
||||
size = binarySearch(start, end, sizeTester, availableSpace);
|
||||
mTextCachedSizes.put(key, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
private static int binarySearch(int start, int end, SizeTester sizeTester,
|
||||
RectF availableSpace) {
|
||||
int lastBest = start;
|
||||
int lo = start;
|
||||
int hi = end - 1;
|
||||
int mid = 0;
|
||||
while (lo <= hi) {
|
||||
mid = (lo + hi) >>> 1;
|
||||
int midValCmp = sizeTester.onTestSize(mid, availableSpace);
|
||||
if (midValCmp < 0) {
|
||||
lastBest = lo;
|
||||
lo = mid + 1;
|
||||
} else if (midValCmp > 0) {
|
||||
hi = mid - 1;
|
||||
lastBest = hi;
|
||||
} else {
|
||||
return mid;
|
||||
}
|
||||
}
|
||||
// make sure to return last best
|
||||
// this is what should always be returned
|
||||
return lastBest;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onTextChanged(final CharSequence text, final int start,
|
||||
final int before, final int after) {
|
||||
super.onTextChanged(text, start, before, after);
|
||||
reAdjust();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int width, int height, int oldwidth,
|
||||
int oldheight) {
|
||||
mTextCachedSizes.clear();
|
||||
super.onSizeChanged(width, height, oldwidth, oldheight);
|
||||
if (width != oldwidth || height != oldheight) {
|
||||
reAdjust();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
package com.beardedhen.androidbootstrap.utils;
|
||||
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuffXfermode;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Bitmap.Config;
|
||||
import android.graphics.PorterDuff.Mode;
|
||||
|
||||
public class ImageUtils
|
||||
{
|
||||
|
||||
public static Bitmap getCircleBitmap(Bitmap bitmap)
|
||||
{
|
||||
return getCircleBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight());
|
||||
}
|
||||
|
||||
public static Bitmap getCircleBitmap(Bitmap bitmap, int width, int height)
|
||||
{
|
||||
Bitmap croppedBitmap = scaleCenterCrop(bitmap, width, height);
|
||||
Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
|
||||
Canvas canvas = new Canvas(output);
|
||||
|
||||
final int color = 0xff424242;
|
||||
final Paint paint = new Paint();
|
||||
|
||||
final Rect rect = new Rect(0, 0, width, height);
|
||||
final RectF rectF = new RectF(rect);
|
||||
|
||||
paint.setAntiAlias(true);
|
||||
canvas.drawARGB(0, 0, 0, 0);
|
||||
paint.setColor(color);
|
||||
|
||||
int radius = 0;
|
||||
if(width > height)
|
||||
{
|
||||
radius = height / 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
radius = width / 2;
|
||||
}
|
||||
|
||||
canvas.drawCircle(width / 2, height / 2, radius, paint);
|
||||
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
|
||||
canvas.drawBitmap(croppedBitmap, rect, rect, paint);
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
public static Bitmap scaleCenterCrop(Bitmap source, int newHeight, int newWidth)
|
||||
{
|
||||
int sourceWidth = source.getWidth();
|
||||
int sourceHeight = source.getHeight();
|
||||
|
||||
float xScale = (float) newWidth / sourceWidth;
|
||||
float yScale = (float) newHeight / sourceHeight;
|
||||
float scale = Math.max(xScale, yScale);
|
||||
|
||||
float scaledWidth = scale * sourceWidth;
|
||||
float scaledHeight = scale * sourceHeight;
|
||||
|
||||
float left = (newWidth - scaledWidth) / 2;
|
||||
float top = (newHeight - scaledHeight) / 2;
|
||||
|
||||
RectF targetRect = new RectF(left, top, left + scaledWidth, top + scaledHeight);
|
||||
|
||||
Bitmap dest = Bitmap.createBitmap(newWidth, newHeight, source.getConfig());
|
||||
Canvas canvas = new Canvas(dest);
|
||||
canvas.drawBitmap(source, null, targetRect, null);
|
||||
|
||||
return dest;
|
||||
}
|
||||
}
|
30
libraries/HtmlTextView/.gitignore
vendored
30
libraries/HtmlTextView/.gitignore
vendored
@ -1,30 +0,0 @@
|
||||
#Android specific
|
||||
bin
|
||||
gen
|
||||
obj
|
||||
libs/armeabi
|
||||
lint.xml
|
||||
local.properties
|
||||
release.properties
|
||||
ant.properties
|
||||
*.class
|
||||
*.apk
|
||||
|
||||
#Gradle
|
||||
.gradle
|
||||
build
|
||||
gradle.properties
|
||||
|
||||
#Maven
|
||||
target
|
||||
pom.xml.*
|
||||
|
||||
#Eclipse
|
||||
.project
|
||||
.classpath
|
||||
.settings
|
||||
.metadata
|
||||
|
||||
#IntelliJ IDEA
|
||||
.idea
|
||||
*.iml
|
@ -1,13 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.sufficientlysecure.htmltextview"
|
||||
android:versionCode="1"
|
||||
android:versionName="1.0">
|
||||
|
||||
<uses-sdk
|
||||
android:minSdkVersion="7"
|
||||
android:targetSdkVersion="17"/>
|
||||
|
||||
<application/>
|
||||
|
||||
</manifest>
|
@ -1,202 +0,0 @@
|
||||
|
||||
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.
|
@ -1,45 +0,0 @@
|
||||
# HtmlTextView for Android
|
||||
|
||||
This HtmlTextView supports all HTML tags supported by Android's Html class (see [The CommonsBlog](http://commonsware.com/blog/Android/2010/05/26/html-tags-supported-by-textview.html) and [history of Html class](https://github.com/android/platform_frameworks_base/commits/master/core/java/android/text/Html.java) for newer additions).
|
||||
Additionally, list tags are supported (``<ul>``, ``<ol>``, ``<dd>``) and code tags with ``<code>``.
|
||||
|
||||
This also includes a workaround to prevent TextView crashing on [specific Android versions](http://code.google.com/p/android/issues/detail?id=35466).
|
||||
|
||||
This library is kept very tiny with no external dependencies.
|
||||
I am using it to provide Help/About Activities in my apps.
|
||||
|
||||
## Example
|
||||
|
||||
```
|
||||
HtmlTextView text = new HtmlTextView(this);
|
||||
|
||||
// loads html from string
|
||||
text.setHtmlFromString("<b>Hello</b><ul><li>world</li><li>cats</li></ul>");
|
||||
```
|
||||
or
|
||||
```
|
||||
HtmlTextView text = new HtmlTextView(this);
|
||||
|
||||
// loads html from raw resource, i.e., a html file in res/raw/, this allows translatable resource (e.g., res/raw-de/ for german)
|
||||
text.setHtmlFromRawResource(this, R.raw.help);
|
||||
```
|
||||
|
||||
## Use library as Gradle dependency (Android library project)
|
||||
|
||||
1. Copy this folder to your project and include it in ``settings.gradle`` with ``include ':html-textview'``
|
||||
2. Add dependency ``compile project(':html-textview')`` to your project's ``build.gradle``.
|
||||
|
||||
## License
|
||||
|
||||
Apache License v2
|
||||
|
||||
## Authors
|
||||
- This library was hacked together by Dominik Schürmann
|
||||
- Original [TagHandler](https://gist.github.com/mlakkadshaw/5983704) developed by [Mohammed Lakkadshaw](http://blog.mohammedlakkadshaw.com/)
|
||||
- Original [UrlImageGetter](https://gist.github.com/Antarix/4167655) developed by Antarix Tandon
|
||||
- [JellyBeanSpanFixTextView](https://gist.github.com/pyricau/3424004) (with fix from comment) developed by Pierre-Yves Ricau
|
||||
|
||||
## Contributions
|
||||
|
||||
Feel free to fork and do pull requests. I am more than happy to merge them.
|
||||
Please do not introduce external dependencies.
|
@ -1,20 +0,0 @@
|
||||
apply plugin: 'android-library'
|
||||
|
||||
|
||||
android {
|
||||
compileSdkVersion 19
|
||||
buildToolsVersion '19.0.3'
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
manifest.srcFile 'AndroidManifest.xml'
|
||||
java.srcDirs = ['src']
|
||||
res.srcDirs = ['res']
|
||||
}
|
||||
}
|
||||
|
||||
// Do not abort build if lint finds errors
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project name="HtmlTextView" 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>
|
@ -1,20 +0,0 @@
|
||||
# To enable ProGuard in your project, edit project.properties
|
||||
# to define the proguard.config property as described in that file.
|
||||
#
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in ${sdk.dir}/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the ProGuard
|
||||
# include property in project.properties.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
@ -1,15 +0,0 @@
|
||||
# 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-19
|
||||
android.library=true
|
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Mohammed Lakkadshaw
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.htmltextview;
|
||||
|
||||
import java.util.Vector;
|
||||
|
||||
import org.xml.sax.XMLReader;
|
||||
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
import android.text.style.BulletSpan;
|
||||
import android.text.style.LeadingMarginSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import android.util.Log;
|
||||
|
||||
public class HtmlTagHandler implements Html.TagHandler {
|
||||
private int mListItemCount = 0;
|
||||
private Vector<String> mListParents = new Vector<String>();
|
||||
|
||||
@Override
|
||||
public void handleTag(final boolean opening, final String tag, Editable output, final XMLReader xmlReader) {
|
||||
|
||||
if (tag.equals("ul") || tag.equals("ol") || tag.equals("dd")) {
|
||||
if (opening) {
|
||||
mListParents.add(tag);
|
||||
} else mListParents.remove(tag);
|
||||
|
||||
mListItemCount = 0;
|
||||
} else if (tag.equals("li") && !opening) {
|
||||
handleListTag(output);
|
||||
} else if (tag.equalsIgnoreCase("code")) {
|
||||
if (opening) {
|
||||
output.setSpan(new TypefaceSpan("monospace"), output.length(), output.length(), Spannable.SPAN_MARK_MARK);
|
||||
} else {
|
||||
Log.d(HtmlTextView.TAG, "Code tag encountered");
|
||||
Object obj = getLast(output, TypefaceSpan.class);
|
||||
int where = output.getSpanStart(obj);
|
||||
output.setSpan(new TypefaceSpan("monospace"), where, output.length(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Object getLast(Editable text, Class kind) {
|
||||
Object[] objs = text.getSpans(0, text.length(), kind);
|
||||
if (objs.length == 0) {
|
||||
return null;
|
||||
} else {
|
||||
for (int i = objs.length; i > 0; i--) {
|
||||
if (text.getSpanFlags(objs[i - 1]) == Spannable.SPAN_MARK_MARK) {
|
||||
return objs[i - 1];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private void handleListTag(Editable output) {
|
||||
if (mListParents.lastElement().equals("ul")) {
|
||||
output.append("\n");
|
||||
String[] split = output.toString().split("\n");
|
||||
|
||||
int lastIndex = split.length - 1;
|
||||
int start = output.length() - split[lastIndex].length() - 1;
|
||||
output.setSpan(new BulletSpan(15 * mListParents.size()), start, output.length(), 0);
|
||||
} else if (mListParents.lastElement().equals("ol")) {
|
||||
mListItemCount++;
|
||||
|
||||
output.append("\n");
|
||||
String[] split = output.toString().split("\n");
|
||||
|
||||
int lastIndex = split.length - 1;
|
||||
int start = output.length() - split[lastIndex].length() - 1;
|
||||
output.insert(start, mListItemCount + ". ");
|
||||
output.setSpan(new LeadingMarginSpan.Standard(15 * mListParents.size()), start, output.length(), 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.htmltextview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.Html;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
public class HtmlTextView extends JellyBeanSpanFixTextView {
|
||||
|
||||
public static final String TAG = "HtmlTextView";
|
||||
|
||||
public HtmlTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public HtmlTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public HtmlTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/309424/read-convert-an-inputstream-to-a-string
|
||||
*
|
||||
* @param is
|
||||
* @return
|
||||
*/
|
||||
static private String convertStreamToString(java.io.InputStream is) {
|
||||
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
|
||||
return s.hasNext() ? s.next() : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads HTML from a raw resource, i.e., a HTML file in res/raw/.
|
||||
* This allows translatable resource (e.g., res/raw-de/ for german).
|
||||
* The containing HTML is parsed to Android's Spannable format and then displayed.
|
||||
*
|
||||
* @param context
|
||||
* @param id for example: R.raw.help
|
||||
*/
|
||||
public void setHtmlFromRawResource(Context context, int id) {
|
||||
// load html from html file from /res/raw
|
||||
InputStream inputStreamText = context.getResources().openRawResource(id);
|
||||
|
||||
setHtmlFromString(convertStreamToString(inputStreamText));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses String containing HTML to Android's Spannable format and displays it in this TextView.
|
||||
*
|
||||
* @param html String containing HTML, for example: "<b>Hello world!</b>"
|
||||
*/
|
||||
public void setHtmlFromString(String html) {
|
||||
// this uses Android's Html class for basic parsing, and HtmlTagHandler
|
||||
setText(Html.fromHtml(html, new UrlImageGetter(this, getContext()), new HtmlTagHandler()));
|
||||
|
||||
// make links work
|
||||
setMovementMethod(LinkMovementMethod.getInstance());
|
||||
|
||||
// no flickering when clicking textview for Android < 4
|
||||
// text.setTextColor(getResources().getColor(android.R.color.secondary_text_dark_nodisable));
|
||||
}
|
||||
}
|
@ -1,212 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Dominik Schürmann <dominik@dominikschuermann.de>
|
||||
* Copyright (C) 2012 Pierre-Yves Ricau <py.ricau@gmail.com>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.htmltextview;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.widget.TextView;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* A {@link android.widget.TextView} that insert spaces around its text spans where needed to prevent
|
||||
* {@link IndexOutOfBoundsException} in {@link #onMeasure(int, int)} on Jelly Bean.
|
||||
* <p>
|
||||
* When {@link #onMeasure(int, int)} throws an exception, we try to fix the text by adding spaces
|
||||
* around spans, until it works again. We then try removing some of the added spans, to minimize the
|
||||
* insertions.
|
||||
* <p>
|
||||
* The fix is time consuming (a few ms, it depends on the size of your text), but it should only
|
||||
* happen once per text change.
|
||||
* <p>
|
||||
* See http://code.google.com/p/android/issues/detail?id=35466
|
||||
*
|
||||
*/
|
||||
public class JellyBeanSpanFixTextView extends TextView {
|
||||
|
||||
private static class FixingResult {
|
||||
public final boolean fixed;
|
||||
public final List<Object> spansWithSpacesBefore;
|
||||
public final List<Object> spansWithSpacesAfter;
|
||||
|
||||
public static FixingResult fixed(List<Object> spansWithSpacesBefore,
|
||||
List<Object> spansWithSpacesAfter) {
|
||||
return new FixingResult(true, spansWithSpacesBefore, spansWithSpacesAfter);
|
||||
}
|
||||
|
||||
public static FixingResult notFixed() {
|
||||
return new FixingResult(false, null, null);
|
||||
}
|
||||
|
||||
private FixingResult(boolean fixed, List<Object> spansWithSpacesBefore,
|
||||
List<Object> spansWithSpacesAfter) {
|
||||
this.fixed = fixed;
|
||||
this.spansWithSpacesBefore = spansWithSpacesBefore;
|
||||
this.spansWithSpacesAfter = spansWithSpacesAfter;
|
||||
}
|
||||
}
|
||||
|
||||
public JellyBeanSpanFixTextView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
public JellyBeanSpanFixTextView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public JellyBeanSpanFixTextView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
try {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
fixOnMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If possible, fixes the Spanned text by adding spaces around spans when needed.
|
||||
*/
|
||||
private void fixOnMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
CharSequence text = getText();
|
||||
if (text instanceof Spanned) {
|
||||
SpannableStringBuilder builder = new SpannableStringBuilder(text);
|
||||
fixSpannedWithSpaces(builder, widthMeasureSpec, heightMeasureSpec);
|
||||
} else {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(HtmlTextView.TAG, "The text isn't a Spanned");
|
||||
}
|
||||
fallbackToString(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add spaces around spans until the text is fixed, and then removes the unneeded spaces
|
||||
*/
|
||||
private void fixSpannedWithSpaces(SpannableStringBuilder builder, int widthMeasureSpec,
|
||||
int heightMeasureSpec) {
|
||||
long startFix = System.currentTimeMillis();
|
||||
|
||||
FixingResult result = addSpacesAroundSpansUntilFixed(builder, widthMeasureSpec,
|
||||
heightMeasureSpec);
|
||||
|
||||
if (result.fixed) {
|
||||
removeUnneededSpaces(widthMeasureSpec, heightMeasureSpec, builder, result);
|
||||
} else {
|
||||
fallbackToString(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
if (BuildConfig.DEBUG) {
|
||||
long fixDuration = System.currentTimeMillis() - startFix;
|
||||
Log.d(HtmlTextView.TAG, "fixSpannedWithSpaces() duration in ms: " + fixDuration);
|
||||
}
|
||||
}
|
||||
|
||||
private FixingResult addSpacesAroundSpansUntilFixed(SpannableStringBuilder builder,
|
||||
int widthMeasureSpec, int heightMeasureSpec) {
|
||||
|
||||
Object[] spans = builder.getSpans(0, builder.length(), Object.class);
|
||||
List<Object> spansWithSpacesBefore = new ArrayList<Object>(spans.length);
|
||||
List<Object> spansWithSpacesAfter = new ArrayList<Object>(spans.length);
|
||||
|
||||
for (Object span : spans) {
|
||||
int spanStart = builder.getSpanStart(span);
|
||||
if (isNotSpace(builder, spanStart - 1)) {
|
||||
builder.insert(spanStart, " ");
|
||||
spansWithSpacesBefore.add(span);
|
||||
}
|
||||
|
||||
int spanEnd = builder.getSpanEnd(span);
|
||||
if (isNotSpace(builder, spanEnd)) {
|
||||
builder.insert(spanEnd, " ");
|
||||
spansWithSpacesAfter.add(span);
|
||||
}
|
||||
|
||||
try {
|
||||
setTextAndMeasure(builder, widthMeasureSpec, heightMeasureSpec);
|
||||
return FixingResult.fixed(spansWithSpacesBefore, spansWithSpacesAfter);
|
||||
} catch (IndexOutOfBoundsException notFixed) {
|
||||
}
|
||||
}
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(HtmlTextView.TAG, "Could not fix the Spanned by adding spaces around spans");
|
||||
}
|
||||
return FixingResult.notFixed();
|
||||
}
|
||||
|
||||
private boolean isNotSpace(CharSequence text, int where) {
|
||||
if (where < 0)
|
||||
return true;
|
||||
return text.charAt(where) != ' ';
|
||||
}
|
||||
|
||||
private void setTextAndMeasure(CharSequence text, int widthMeasureSpec, int heightMeasureSpec) {
|
||||
setText(text);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private void removeUnneededSpaces(int widthMeasureSpec, int heightMeasureSpec,
|
||||
SpannableStringBuilder builder, FixingResult result) {
|
||||
|
||||
for (Object span : result.spansWithSpacesAfter) {
|
||||
int spanEnd = builder.getSpanEnd(span);
|
||||
builder.delete(spanEnd, spanEnd + 1);
|
||||
try {
|
||||
setTextAndMeasure(builder, widthMeasureSpec, heightMeasureSpec);
|
||||
} catch (IndexOutOfBoundsException ignored) {
|
||||
builder.insert(spanEnd, " ");
|
||||
}
|
||||
}
|
||||
|
||||
boolean needReset = true;
|
||||
for (Object span : result.spansWithSpacesBefore) {
|
||||
int spanStart = builder.getSpanStart(span);
|
||||
builder.delete(spanStart - 1, spanStart);
|
||||
try {
|
||||
setTextAndMeasure(builder, widthMeasureSpec, heightMeasureSpec);
|
||||
needReset = false;
|
||||
} catch (IndexOutOfBoundsException ignored) {
|
||||
needReset = true;
|
||||
int newSpanStart = spanStart - 1;
|
||||
builder.insert(newSpanStart, " ");
|
||||
}
|
||||
}
|
||||
|
||||
if (needReset) {
|
||||
setText(builder);
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
private void fallbackToString(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
Log.d(HtmlTextView.TAG, "Fallback to unspanned text");
|
||||
}
|
||||
String fallbackText = getText().toString();
|
||||
setTextAndMeasure(fallbackText, widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
}
|
@ -1,128 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2013 Antarix Tandon
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.sufficientlysecure.htmltextview;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.Html.ImageGetter;
|
||||
import android.view.View;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.impl.client.DefaultHttpClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
public class UrlImageGetter implements ImageGetter {
|
||||
Context c;
|
||||
View container;
|
||||
|
||||
/**
|
||||
* Construct the URLImageParser which will execute AsyncTask and refresh the container
|
||||
*
|
||||
* @param t
|
||||
* @param c
|
||||
*/
|
||||
public UrlImageGetter(View t, Context c) {
|
||||
this.c = c;
|
||||
this.container = t;
|
||||
}
|
||||
|
||||
public Drawable getDrawable(String source) {
|
||||
UrlDrawable urlDrawable = new UrlDrawable();
|
||||
|
||||
// get the actual source
|
||||
ImageGetterAsyncTask asyncTask = new ImageGetterAsyncTask(urlDrawable);
|
||||
|
||||
asyncTask.execute(source);
|
||||
|
||||
// return reference to URLDrawable where I will change with actual image from
|
||||
// the src tag
|
||||
return urlDrawable;
|
||||
}
|
||||
|
||||
public class ImageGetterAsyncTask extends AsyncTask<String, Void, Drawable> {
|
||||
UrlDrawable urlDrawable;
|
||||
|
||||
public ImageGetterAsyncTask(UrlDrawable d) {
|
||||
this.urlDrawable = d;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Drawable doInBackground(String... params) {
|
||||
String source = params[0];
|
||||
return fetchDrawable(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Drawable result) {
|
||||
// set the correct bound according to the result from HTTP call
|
||||
urlDrawable.setBounds(0, 0, 0 + result.getIntrinsicWidth(), 0 + result.getIntrinsicHeight());
|
||||
|
||||
// change the reference of the current drawable to the result
|
||||
// from the HTTP call
|
||||
urlDrawable.drawable = result;
|
||||
|
||||
// redraw the image by invalidating the container
|
||||
UrlImageGetter.this.container.invalidate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Drawable from URL
|
||||
*
|
||||
* @param urlString
|
||||
* @return
|
||||
*/
|
||||
public Drawable fetchDrawable(String urlString) {
|
||||
try {
|
||||
InputStream is = fetch(urlString);
|
||||
Drawable drawable = Drawable.createFromStream(is, "src");
|
||||
drawable.setBounds(0, 0, 0 + drawable.getIntrinsicWidth(), 0 + drawable.getIntrinsicHeight());
|
||||
return drawable;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InputStream fetch(String urlString) throws MalformedURLException, IOException {
|
||||
DefaultHttpClient httpClient = new DefaultHttpClient();
|
||||
HttpGet request = new HttpGet(urlString);
|
||||
HttpResponse response = httpClient.execute(request);
|
||||
return response.getEntity().getContent();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class UrlDrawable extends BitmapDrawable {
|
||||
// the drawable that you need to set, you could set the initial drawing
|
||||
// with the loading image if you need to
|
||||
protected Drawable drawable;
|
||||
|
||||
@Override
|
||||
public void draw(Canvas canvas) {
|
||||
// override the draw to facilitate refresh function later
|
||||
if (drawable != null) {
|
||||
drawable.draw(canvas);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
98
libraries/StickyListHeaders/.gitignore
vendored
98
libraries/StickyListHeaders/.gitignore
vendored
@ -1,98 +0,0 @@
|
||||
###Android###
|
||||
|
||||
# built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
|
||||
# files for the dex VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# generated files
|
||||
bin/
|
||||
gen/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
|
||||
|
||||
###Eclipse###
|
||||
|
||||
*.pydevproject
|
||||
.project
|
||||
.metadata
|
||||
bin/**
|
||||
tmp/**
|
||||
tmp/**/*
|
||||
*.tmp
|
||||
*.bak
|
||||
*.swp
|
||||
*~.nib
|
||||
local.properties
|
||||
.classpath
|
||||
.settings/
|
||||
.loadpath
|
||||
|
||||
# External tool builders
|
||||
.externalToolBuilders/
|
||||
|
||||
# Locally stored "Eclipse launch configurations"
|
||||
*.launch
|
||||
|
||||
# CDT-specific
|
||||
.cproject
|
||||
|
||||
# PDT-specific
|
||||
.buildpath
|
||||
|
||||
|
||||
###Maven###
|
||||
|
||||
target/
|
||||
|
||||
|
||||
###Gradle###
|
||||
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
|
||||
###IntelliJ###
|
||||
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
|
||||
|
||||
###Actionscript###
|
||||
|
||||
# Build and Release Folders
|
||||
bin/
|
||||
bin-debug/
|
||||
bin-release/
|
||||
|
||||
# Project property files
|
||||
.actionScriptProperties
|
||||
.flexProperties
|
||||
.settings/
|
||||
.project
|
||||
|
||||
###OSX###
|
||||
|
||||
.DS_Store
|
||||
|
||||
# Thumbnails
|
||||
._*
|
||||
|
||||
# Files that might appear on external disk
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
|
||||
|
@ -1,191 +0,0 @@
|
||||
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:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
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
|
||||
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.
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user