diff --git a/.gitignore b/.gitignore
index af74b48..78cc783 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,21 +3,13 @@ bin
gen
lint.xml
+
#Eclipse
.project
.classpath
.settings
.checkstyle
-#IntelliJ IDEA
-.idea
-*.iml
-*.ipr
-*.iws
-out
-classes
-gen-external-apklibs
-
#Maven
target
release.properties
@@ -31,4 +23,23 @@ proguard.cfg
proguard-project.txt
#Other
-.DS_Store
\ No newline at end of file
+.DS_Store
+#svn
+.svn
+
+# Android Studio
+.idea/
+.gradle
+gradle
+/*/local.properties
+/*/out
+/*/*/build
+/*/*/production
+*.iml
+*.iws
+*.ipr
+*~
+*.swp
+/gradlew.bat
+/gradlew
+build
diff --git a/ProgressSwitcher-Sample.apk b/ProgressSwitcher-Sample.apk
new file mode 100644
index 0000000..4b0b981
Binary files /dev/null and b/ProgressSwitcher-Sample.apk differ
diff --git a/ProgressSwitcher.aar b/ProgressSwitcher.aar
new file mode 100644
index 0000000..8aa174e
Binary files /dev/null and b/ProgressSwitcher.aar differ
diff --git a/README.md b/README.md
index 478f6b4..e5fcdce 100644
--- a/README.md
+++ b/README.md
@@ -1,79 +1,186 @@
-Android-ProgressFragment
+Android-ProgressSwitcher
========================
-Implementation of the fragment with the ability to display indeterminate progress indicator when you are waiting for the initial data. Based on [ListFragment](http://developer.android.com/reference/android/app/ListFragment.html).
+The library is used to switch between content, progress, empty or error views. The main The progress is displayed during initial data loading. If data is empty then empty view is displayed. The same goes for error view. The work was based on [Android-ProgressFragment](https://github.com/johnkil/Android-ProgressFragment) project, but with a more declarative setup and state persistence.
+[Sample apk](https://github.com/Drnkn/Android-ProgressSwitcher/blob/master/ProgressSwitcher-Sample.apk)
+
+Dependencies
+-------------
+
+[AAR](https://github.com/Drnkn/Android-ProgressSwitcher/blob/master/ProgressSwitcher.aar)
+
+The project now in Maven Central, so you can add dependency
+``` xml
+dependencies {
+ compile 'com.github.drnkn:progress-switcher:1.1.3@aar'
+}
+```
+
+Compatibility
+-------------
+
+This library is compatible from API 4 (Android 1.6).
Sample
------
-A sample application is available on Google Play:
+A sample can be found on Google Play:
-
+
-![screenshot][1]
+Usage
+-----
+The library consist of three main classes: ProgressWidget, ProgressSwitcher and ProgressFragment. All classes implement Switcher interface. The most important methods are:
-Compatibility
--------------
+For changing state:
-This library is compatible from API 4 (Android 1.6).
+```java
+public void showContent()
+```
+```java
+public void showProgress()
+```
+```java
+public void showEmpty()
+```
+```java
+public void showError()
+```
+For configure switcher:
-Usage
------
+```java
+public void setEmptyText(int resId)
+```
+```java
+public void setErrorText(int resId)
+```
+```java
+public void setOnEmptyViewClickListener(OnClickListener onClickListener, int viewId)
+```
+```java
+public void setOnErrorViewClickListener(OnClickListener onClickListener, int viewId)
+```
-To display the progress fragment you need the following code:
+* ProgressWidget
-* Create your implementation of progress fragment
+Declare widget in layout:
+``` xml
+
-``` java
-public class MyProgressFragment extends ProgressFragment {
- // your code of fragment
-}
-```
+
+
+
+```
-* Setup content view and empty text (optional) in `onActivityCreate()` method.
+... and that's it. Now you can get widget in your fragment and do what yout want.
+
+* ProgressSwitcher
+
+One way of using ProgressSwitcher is setup it with content view.
+Inflate your content view:
``` java
-@Override
-public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- // Setup content view
- setContentView(R.layout.content);
- // Setup text for empty content
- setEmptyText(R.string.empty);
- // ...
-}
-```
+ @Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ mContentView = inflater.inflate(R.layout.view_content, container, false);
+
+ return mContentView;
+ }
+```
-* Display of indeterminate progress indicator
+Setup switcher with fromContentView method:
``` java
-setContentShown(false);
-```
+ @Override
+ public void onActivityCreated(final Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mProgressSwitcher = ProgressSwitcher
+ .fromContentView(getActivity(), mContentView);
+ }
+```
+
+The second way is provide complete layout:
+
+``` xml
+
+
+
+
+
+
+
+
+
+```
+
+And setup switcher with fromRootView method and add content view:
+``` java
+ @Override
+ public void onActivityCreated(final Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ mProgressSwitcher = ProgressSwitcher
+ .fromRootView(getActivity(), mContentView);
+ mProgressSwitcher.addContentView(R.layout.view_content)
+ }
+```
+
+* ProgressFragment
-* When the data is loaded to set whether the content is empty and show content
+Extend ProgressFragment:
``` java
-setContentEmpty(/* true if content is empty else false */);
-setContentShown(true);
-```
+public class CustomProgressFragment extends ProgressFragment {
+}
+```
+
+Setup content view:
+``` java
+@Override
+public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ setContentView(R.layout.view_content);
+}
+```
Developed By
------------
-* Evgeny Shishkin -
+* Dmitry Zaitsev -
License
-------
- Copyright 2013 Evgeny Shishkin
+ Copyright 2014 Dmitry Zaitsev
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -86,5 +193,3 @@ License
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://i50.tinypic.com/2b9jy9.png
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..f351ae4
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,18 @@
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
+buildscript {
+ repositories {
+ mavenCentral()
+ }
+ dependencies {
+ classpath 'com.android.tools.build:gradle:0.12.+'
+ }
+}
+
+allprojects {
+ version = VERSION_NAME
+ group = GROUP
+
+ repositories {
+ mavenCentral()
+ }
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..4eab181
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,13 @@
+VERSION_NAME = 1.1.3
+VERSION_CODE = 4
+GROUP = com.github.drnkn
+
+POM_DESCRIPTION = Set of tools with the ability to display indeterminate progress indicator when you are waiting for the initial data
+POM_URL = https://github.com/Drnkn/Android-ProgressSwitcher
+POM_SCM_URL = https://github.com/Drnkn/Android-ProgressSwitcher
+POM_SCM_CONNECTION = scm:git@github.com:Drnkn/Android-ProgressSwitcher.git
+POM_SCM_DEV_CONNECTION = scm:git@github.com:gabrielemariotti/changeloglib.git
+POM_LICENCE_NAME = The Apache Software License, Version 2.0
+POM_LICENCE_URL = http://www.apache.org/licenses/LICENSE-2.0.txt
+POM_LICENCE_DIST = repo
+POM_DEVELOPER_NAME = Dmitry Zaytsev
\ No newline at end of file
diff --git a/library/AndroidManifest.xml b/library/AndroidManifest.xml
index 51f7ac7..1a23bb3 100644
--- a/library/AndroidManifest.xml
+++ b/library/AndroidManifest.xml
@@ -1,10 +1,10 @@
+ android:targetSdkVersion="19"/>
diff --git a/library/build.gradle b/library/build.gradle
new file mode 100644
index 0000000..7ecd2b6
--- /dev/null
+++ b/library/build.gradle
@@ -0,0 +1,44 @@
+apply plugin: 'com.android.library'
+apply plugin: 'maven'
+
+dependencies {
+ compile 'com.android.support:support-v4:19.0.+'
+}
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion '19.1.0'
+ sourceSets {
+ main {
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = ['src']
+ resources.srcDirs = ['src']
+ aidl.srcDirs = ['src']
+ renderscript.srcDirs = ['src']
+ res.srcDirs = ['res']
+ assets.srcDirs = ['assets']
+ }
+
+ // Move the tests to tests/java, tests/res, etc...
+ instrumentTest.setRoot('tests')
+
+ // Move the build types to build-types/
+ // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
+ // This moves them out of them default location under src//... which would
+ // conflict with src/ being used by the main source set.
+ // Adding new build types or product flavors should be accompanied
+ // by a similar customization.
+ debug.setRoot('build-types/debug')
+ release.setRoot('build-types/release')
+ }
+ defaultConfig {
+ minSdkVersion 4
+ targetSdkVersion 19
+ versionName project.VERSION_NAME
+ versionCode Integer.parseInt(project.VERSION_CODE)
+ }
+ productFlavors {
+ }
+}
+
+apply from: '../maven_push.gradle'
diff --git a/library/gradle.properties b/library/gradle.properties
new file mode 100644
index 0000000..0835d76
--- /dev/null
+++ b/library/gradle.properties
@@ -0,0 +1,21 @@
+# Project-wide Gradle settings.
+
+# IDE (e.g. Android Studio) users:
+# Settings specified in this file will override any Gradle settings
+# configured through the IDE.
+
+# For more details on how to configure your build environment visit
+# http://www.gradle.org/docs/current/userguide/build_environment.html
+
+# Specifies the JVM arguments used for the daemon process.
+# The setting is particularly useful for tweaking memory settings.
+# Default value: -Xmx10248m -XX:MaxPermSize=256m
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
+
+# When configured, Gradle will run in incubating parallel mode.
+# This option should only be used with decoupled projects. More details, visit
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
+# org.gradle.parallel=true
+POM_NAME = Android-ProgressSwitcher
+POM_ARTIFACT_ID = progress-switcher
+POM_PACKAGING = aar
\ No newline at end of file
diff --git a/library/libs/android-support-v4.jar b/library/libs/android-support-v4.jar
deleted file mode 100644
index 6080877..0000000
Binary files a/library/libs/android-support-v4.jar and /dev/null differ
diff --git a/library/project.properties b/library/project.properties
index 4a46b9d..61afc8f 100644
--- a/library/project.properties
+++ b/library/project.properties
@@ -12,4 +12,4 @@
android.library=true
# Project target.
-target=android-17
+target=android-19
diff --git a/library/res/layout/fragment_progress.xml b/library/res/layout/fragment_progress.xml
deleted file mode 100644
index d6ab2d4..0000000
--- a/library/res/layout/fragment_progress.xml
+++ /dev/null
@@ -1,58 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/library/res/layout/ps_empty_view.xml b/library/res/layout/ps_empty_view.xml
new file mode 100644
index 0000000..317658d
--- /dev/null
+++ b/library/res/layout/ps_empty_view.xml
@@ -0,0 +1,9 @@
+
+
diff --git a/library/res/layout/ps_error_view.xml b/library/res/layout/ps_error_view.xml
new file mode 100644
index 0000000..7031eb8
--- /dev/null
+++ b/library/res/layout/ps_error_view.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
diff --git a/library/res/layout/ps_progress_view.xml b/library/res/layout/ps_progress_view.xml
new file mode 100644
index 0000000..d3f23e6
--- /dev/null
+++ b/library/res/layout/ps_progress_view.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/res/layout/retry_button.xml b/library/res/layout/retry_button.xml
new file mode 100644
index 0000000..e847881
--- /dev/null
+++ b/library/res/layout/retry_button.xml
@@ -0,0 +1,10 @@
+
+
\ No newline at end of file
diff --git a/library/res/layout/switcher_layout.xml b/library/res/layout/switcher_layout.xml
new file mode 100644
index 0000000..2b919e2
--- /dev/null
+++ b/library/res/layout/switcher_layout.xml
@@ -0,0 +1,13 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/res/values/attrs.xml b/library/res/values/attrs.xml
new file mode 100644
index 0000000..2c6a5f3
--- /dev/null
+++ b/library/res/values/attrs.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/res/values/ids.xml b/library/res/values/ids.xml
new file mode 100644
index 0000000..7ea779c
--- /dev/null
+++ b/library/res/values/ids.xml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/library/res/values/string.xml b/library/res/values/string.xml
new file mode 100644
index 0000000..83b0bc9
--- /dev/null
+++ b/library/res/values/string.xml
@@ -0,0 +1,6 @@
+
+
+ No content
+ An error has occurred
+ Retry
+
\ No newline at end of file
diff --git a/library/src/com/devspark/progressfragment/ProgressFragment.java b/library/src/com/devspark/progressfragment/ProgressFragment.java
deleted file mode 100644
index 47dc6ae..0000000
--- a/library/src/com/devspark/progressfragment/ProgressFragment.java
+++ /dev/null
@@ -1,292 +0,0 @@
-/*
- * Copyright (C) 2013 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.progressfragment;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.animation.AnimationUtils;
-import android.widget.TextView;
-
-/**
- * The implementation of the fragment to display content. Based on {@link android.support.v4.app.ListFragment}.
- * If you are waiting for the initial data, you'll can displaying during this time an indeterminate progress indicator.
- *
- * @author Evgeny Shishkin
- */
-public class ProgressFragment extends Fragment {
-
- private View mProgressContainer;
- private View mContentContainer;
- private View mContentView;
- private View mEmptyView;
- private boolean mContentShown;
- private boolean mIsContentEmpty;
-
- /**
- * Provide default implementation to return a simple view. Subclasses
- * can override to replace with their own layout. If doing so, the
- * returned view hierarchy must have a progress container whose id
- * is {@link R.id#progress_container R.id.progress_container}, content container whose id
- * is {@link R.id#content_container R.id.content_container} and can optionally
- * have a sibling view id {@link android.R.id#empty android.R.id.empty}
- * that is to be shown when the content is empty.
- *
- *
If you are overriding this method with your own custom content,
- * consider including the standard layout {@link R.layout#fragment_progress}
- * in your layout file, so that you continue to retain all of the standard
- * behavior of ProgressFragment. In particular, this is currently the only
- * way to have the built-in indeterminant progress state be shown.
- */
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- return inflater.inflate(R.layout.fragment_progress, container, false);
- }
-
- /**
- * Attach to view once the view hierarchy has been created.
- */
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
- ensureContent();
- }
-
- /**
- * Detach from view.
- */
- @Override
- public void onDestroyView() {
- mContentShown = false;
- mIsContentEmpty = false;
- mProgressContainer = mContentContainer = mContentView = mEmptyView = null;
- super.onDestroyView();
- }
-
- /**
- * Return content view or null if the content view has not been initialized.
- *
- * @return content view or null
- * @see #setContentView(android.view.View)
- * @see #setContentView(int)
- */
- public View getContentView() {
- return mContentView;
- }
-
- /**
- * Set the content content from a layout resource.
- *
- * @param layoutResId Resource ID to be inflated.
- * @see #setContentView(android.view.View)
- * @see #getContentView()
- */
- public void setContentView(int layoutResId) {
- LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
- View contentView = layoutInflater.inflate(layoutResId, null);
- setContentView(contentView);
- }
-
- /**
- * Set the content view to an explicit view. If the content view was installed earlier,
- * the content will be replaced with a new view.
- *
- * @param view The desired content to display. Value can't be null.
- * @see #setContentView(int)
- * @see #getContentView()
- */
- public void setContentView(View view) {
- ensureContent();
- if (view == null) {
- throw new IllegalArgumentException("Content view can't be null");
- }
- if (mContentContainer instanceof ViewGroup) {
- ViewGroup contentContainer = (ViewGroup) mContentContainer;
- if (mContentView == null) {
- contentContainer.addView(view);
- } else {
- int index = contentContainer.indexOfChild(mContentView);
- // replace content view
- contentContainer.removeView(mContentView);
- contentContainer.addView(view, index);
- }
- mContentView = view;
- } else {
- throw new IllegalStateException("Can't be used with a custom content view");
- }
- }
-
- /**
- * The default content for a ProgressFragment has a TextView that can be shown when
- * the content is empty {@link #setContentEmpty(boolean)}.
- * If you would like to have it shown, call this method to supply the text it should use.
- *
- * @param resId Identification of string from a resources
- * @see #setEmptyText(CharSequence)
- */
- public void setEmptyText(int resId) {
- setEmptyText(getString(resId));
- }
-
- /**
- * The default content for a ProgressFragment has a TextView that can be shown when
- * the content is empty {@link #setContentEmpty(boolean)}.
- * If you would like to have it shown, call this method to supply the text it should use.
- *
- * @param text Text for empty view
- * @see #setEmptyText(int)
- */
- public void setEmptyText(CharSequence text) {
- ensureContent();
- if (mEmptyView != null && mEmptyView instanceof TextView) {
- ((TextView) mEmptyView).setText(text);
- } else {
- throw new IllegalStateException("Can't be used with a custom content view");
- }
- }
-
- /**
- * Control whether the content is being displayed. You can make it not
- * displayed if you are waiting for the initial data to show in it. During
- * this time an indeterminant progress indicator will be shown instead.
- *
- * @param shown If true, the content view is shown; if false, the progress
- * indicator. The initial value is true.
- * @see #setContentShownNoAnimation(boolean)
- */
- public void setContentShown(boolean shown) {
- setContentShown(shown, true);
- }
-
- /**
- * Like {@link #setContentShown(boolean)}, but no animation is used when
- * transitioning from the previous state.
- *
- * @param shown If true, the content view is shown; if false, the progress
- * indicator. The initial value is true.
- * @see #setContentShown(boolean)
- */
- public void setContentShownNoAnimation(boolean shown) {
- setContentShown(shown, false);
- }
-
- /**
- * Control whether the content is being displayed. You can make it not
- * displayed if you are waiting for the initial data to show in it. During
- * this time an indeterminant progress indicator will be shown instead.
- *
- * @param shown If true, the content view is shown; if false, the progress
- * indicator. The initial value is true.
- * @param animate If true, an animation will be used to transition to the
- * new state.
- */
- private void setContentShown(boolean shown, boolean animate) {
- ensureContent();
- if (mContentShown == shown) {
- return;
- }
- mContentShown = shown;
- if (shown) {
- if (animate) {
- mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
- mContentContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
- } else {
- mProgressContainer.clearAnimation();
- mContentContainer.clearAnimation();
- }
- mProgressContainer.setVisibility(View.GONE);
- mContentContainer.setVisibility(View.VISIBLE);
- } else {
- if (animate) {
- mProgressContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in));
- mContentContainer.startAnimation(AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out));
- } else {
- mProgressContainer.clearAnimation();
- mContentContainer.clearAnimation();
- }
- mProgressContainer.setVisibility(View.VISIBLE);
- mContentContainer.setVisibility(View.GONE);
- }
- }
-
- /**
- * Returns true if content is empty. The default content is not empty.
- *
- * @return true if content is null or empty
- * @see #setContentEmpty(boolean)
- */
- public boolean isContentEmpty() {
- return mIsContentEmpty;
- }
-
- /**
- * If the content is empty, then set true otherwise false. The default content is not empty.
- * You can't call this method if the content view has not been initialized before
- * {@link #setContentView(android.view.View)} and content view not null.
- *
- * @param isEmpty true if content is empty else false
- * @see #isContentEmpty()
- */
- public void setContentEmpty(boolean isEmpty) {
- ensureContent();
- if (mContentView == null) {
- throw new IllegalStateException("Content view must be initialized before");
- }
- if (isEmpty) {
- mEmptyView.setVisibility(View.VISIBLE);
- mContentView.setVisibility(View.GONE);
- } else {
- mEmptyView.setVisibility(View.GONE);
- mContentView.setVisibility(View.VISIBLE);
- }
- mIsContentEmpty = isEmpty;
- }
-
- /**
- * Initialization views.
- */
- private void ensureContent() {
- if (mContentContainer != null && mProgressContainer != null) {
- return;
- }
- View root = getView();
- if (root == null) {
- throw new IllegalStateException("Content view not yet created");
- }
- mProgressContainer = root.findViewById(R.id.progress_container);
- if (mProgressContainer == null) {
- throw new RuntimeException("Your content must have a ViewGroup whose id attribute is 'R.id.progress_container'");
- }
- mContentContainer = root.findViewById(R.id.content_container);
- if (mContentContainer == null) {
- throw new RuntimeException("Your content must have a ViewGroup whose id attribute is 'R.id.content_container'");
- }
- mEmptyView = root.findViewById(android.R.id.empty);
- if (mEmptyView != null) {
- mEmptyView.setVisibility(View.GONE);
- }
- mContentShown = true;
- // We are starting without a content, so assume we won't
- // have our data right away and start with the progress indicator.
- if (mContentView == null) {
- setContentShown(false, false);
- }
- }
-
-}
diff --git a/library/src/ru/vang/progressswitcher/ProgressFragment.java b/library/src/ru/vang/progressswitcher/ProgressFragment.java
new file mode 100644
index 0000000..e24deb0
--- /dev/null
+++ b/library/src/ru/vang/progressswitcher/ProgressFragment.java
@@ -0,0 +1,256 @@
+/*
+ * Copyright (C) 2013 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 ru.vang.progressswitcher;
+
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+
+/**
+ * The implementation of the fragment to display content. Based on
+ * {@link android.support.v4.app.ListFragment}. If you are waiting for the
+ * initial data, you'll can displaying during this time an indeterminate
+ * progress indicator.
+ */
+public class ProgressFragment extends Fragment implements Switcher {
+
+ private static final String PACKAGE = ProgressFragment.class.getPackage().getName();
+
+ private static final String EXTRA_SHOWN_TYPE = PACKAGE + ".EXTRA_SHOWN_TYPE";
+
+ private ProgressSwitcher mProgressSwitcher;
+
+ @Override
+ public void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ mProgressSwitcher = new ProgressSwitcher(getActivity());
+ }
+
+ /**
+ * Provide default implementation to return a simple view. Subclasses can
+ * override to replace with their own layout. If doing so, the returned view
+ * hierarchy must have a progress container whose id is
+ * {@link ru.vang.progressswitcher.R.id#progress_view
+ * R.id.progress_container}, content container whose id is
+ * {@link ru.vang.progressswitcher.R.id#content_container
+ * R.id.content_container} and can optionally have a sibling view id
+ * {@link android.R.id#empty android.R.id.empty} that is to be shown when
+ * the content is empty.
+ *
+ *
+ * If you are overriding this method with your own custom content, consider
+ * including the standard layout
+ * {@link ru.vang.progressswitcher.R.layout#switcher_layout} in your
+ * layout file, so that you continue to retain all of the standard behavior
+ * of ProgressFragment. In particular, this is currently the only way to
+ * have the built-in indeterminant progress state be shown.
+ */
+ @Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ return inflater.inflate(R.layout.switcher_layout, container, false);
+ }
+
+ /**
+ * Attach to view once the view hierarchy has been created.
+ */
+ @Override
+ public void onViewCreated(final View view, final Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+ mProgressSwitcher.setRootView(view);
+ }
+
+ @Override
+ public void onViewStateRestored(final Bundle savedInstanceState) {
+ super.onViewStateRestored(savedInstanceState);
+ if (savedInstanceState != null) {
+ mProgressSwitcher.setContentShown(
+ savedInstanceState.getInt(EXTRA_SHOWN_TYPE, ProgressSwitcher.TYPE_PROGRESS),
+ false);
+ }
+ }
+
+ /**
+ * Detach from view.
+ */
+ @Override
+ public void onDestroyView() {
+ mProgressSwitcher.reset();
+ super.onDestroyView();
+ }
+
+ @Override
+ public void onSaveInstanceState(final Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt(EXTRA_SHOWN_TYPE, mProgressSwitcher.getShownContentType());
+ }
+
+ @Override
+ public View getContentView() {
+ return mProgressSwitcher.getContentView();
+ }
+
+ @Override
+ public void addContentView(final int layoutResId) {
+ mProgressSwitcher.addContentView(layoutResId);
+ }
+
+ @Override
+ public void addContentView(final View view) {
+ mProgressSwitcher.addContentView(view);
+ }
+
+ @Override
+ public void setContentView(final int contentViewId) {
+ mProgressSwitcher.setContentView(contentViewId);
+ }
+
+ @Override
+ public void setContentView(final View contentView) {
+ mProgressSwitcher.setContentView(contentView);
+ }
+
+ @Override
+ public void showContent() {
+ mProgressSwitcher.showContent();
+ }
+
+ @Override
+ public void showContent(final boolean animate) {
+ mProgressSwitcher.showContent(animate);
+ }
+
+ @Override
+ public void showProgress() {
+ mProgressSwitcher.showProgress();
+ }
+
+ @Override
+ public void showProgress(final boolean animate) {
+ mProgressSwitcher.showProgress(animate);
+ }
+
+ @Override
+ public void showEmpty() {
+ mProgressSwitcher.showEmpty();
+ }
+
+ @Override
+ public void showEmpty(final boolean animate) {
+ mProgressSwitcher.showEmpty();
+ }
+
+ @Override
+ public void showError() {
+ mProgressSwitcher.showError();
+ }
+
+ @Override
+ public void showError(final boolean animate) {
+ mProgressSwitcher.showEmpty(animate);
+ }
+
+ @Override
+ public void setEmptyText(final int resId) {
+ mProgressSwitcher.setEmptyText(resId);
+ }
+
+ @Override
+ public void setEmptyText(final CharSequence text) {
+ mProgressSwitcher.setEmptyText(text);
+ }
+
+ @Override
+ public void setEmptyText(final int resId, final int viewId) {
+ mProgressSwitcher.setEmptyText(resId, viewId);
+ }
+
+ @Override
+ public void setEmptyText(final CharSequence text, final int viewId) {
+ mProgressSwitcher.setEmptyText(text, viewId);
+ }
+
+ @Override
+ public void setErrorText(final int resId) {
+ mProgressSwitcher.setErrorText(resId);
+ }
+
+ @Override
+ public void setErrorText(final CharSequence text) {
+ mProgressSwitcher.setErrorText(text);
+ }
+
+ @Override
+ public void setErrorText(final int resId, final int viewId) {
+ mProgressSwitcher.setErrorText(resId, viewId);
+ }
+
+ @Override
+ public void setErrorText(final CharSequence text, final int viewId) {
+ mProgressSwitcher.setErrorText(text, viewId);
+ }
+
+ @Override
+ public void setOnEmptyViewClickListener(final OnClickListener onClickListener) {
+ mProgressSwitcher.setOnEmptyViewClickListener(onClickListener);
+ }
+
+ @Override
+ public void setOnEmptyViewClickListener(final OnClickListener onClickListener,
+ final int viewId) {
+ mProgressSwitcher.setOnEmptyViewClickListener(onClickListener, viewId);
+ }
+
+ @Override
+ public void setOnErrorViewClickListener(final OnClickListener onClickListener) {
+ mProgressSwitcher.setOnErrorViewClickListener(onClickListener);
+ }
+
+ @Override
+ public void setOnErrorViewClickListener(final OnClickListener onClickListener,
+ final int viewId) {
+ mProgressSwitcher.setOnErrorViewClickListener(onClickListener, viewId);
+ }
+
+ @Override
+ public boolean isProgressDisplayed() {
+ return mProgressSwitcher.isProgressDisplayed();
+ }
+
+ @Override
+ public boolean isContentDisplayed() {
+ return mProgressSwitcher.isContentDisplayed();
+ }
+
+ @Override
+ public boolean isEmptyViewDisplayed() {
+ return mProgressSwitcher.isEmptyViewDisplayed();
+ }
+
+ @Override
+ public boolean isErrorViewDisplayed() {
+ return mProgressSwitcher.isErrorViewDisplayed();
+ }
+
+ @Override
+ public void setCustomAnimation(final int animationIn, final int animationOut) {
+ mProgressSwitcher.setCustomAnimation(animationIn, animationOut);
+ }
+}
diff --git a/library/src/ru/vang/progressswitcher/ProgressSwitcher.java b/library/src/ru/vang/progressswitcher/ProgressSwitcher.java
new file mode 100644
index 0000000..d620f65
--- /dev/null
+++ b/library/src/ru/vang/progressswitcher/ProgressSwitcher.java
@@ -0,0 +1,726 @@
+/*
+ * Copyright (C) 2013 Zaitsev Dmitry
+ *
+ * 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 ru.vang.progressswitcher;
+
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.view.ViewGroup;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.TextView;
+
+
+public class ProgressSwitcher implements Switcher {
+
+ public static final int TYPE_PROGRESS = 0;
+
+ public static final int TYPE_CONTENT = 1;
+
+ public static final int TYPE_EMPTY = 2;
+
+ public static final int TYPE_ERROR = 3;
+
+ private static int sDefaultProgressView = R.layout.ps_progress_view;
+
+ private static int sDefaultEmptyView = R.layout.ps_empty_view;
+
+ private static int sDefaultErrorView = R.layout.ps_error_view;
+
+ static final int DEFAULT_ANIMATION_IN = android.R.anim.fade_in;
+
+ static final int DEFAULT_ANIMATION_OUT = android.R.anim.fade_out;
+
+ private Context mContext;
+
+ private ViewGroup mContentContainer;
+
+ private View mProgressView;
+
+ private View mContentView;
+
+ private View mEmptyView;
+
+ private View mErrorView;
+
+ private View mShownView;
+
+ private int mContentTypeShown = TYPE_PROGRESS;
+
+ private int mAnimationIn = DEFAULT_ANIMATION_IN;
+
+ private int mAnimationOut = DEFAULT_ANIMATION_OUT;
+
+ ProgressSwitcher(final Context context) {
+ mContext = context;
+ }
+
+ private ProgressSwitcher(final Context context, final View rootView) {
+ mContext = context;
+ initViewsFromRoot(rootView);
+ }
+
+ /**
+ * Create instance of {@link ru.vang.progressswitcher.ProgressSwitcher ProgressSwitcher}
+ * from provided views hierarchy. views hierarchy should have the following structure:
+ * ...
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ *
+ * ...
+ * Content view can be included directly in layout with id {@link ru.vang.progressswitcher.R.id#content_view
+ * R.id.content_view} or added by {@link #addContentView(android.view.View)} method.
+ *
+ * @param context app context
+ * @param rootView view from which {@link ru.vang.progressswitcher.ProgressSwitcher
+ * ProgressSwitcher} will be created
+ * @return instance of {@link ru.vang.progressswitcher.ProgressSwitcher
+ * ProgressSwitcher}
+ */
+ public static ProgressSwitcher fromRootView(final Context context, final View rootView) {
+ return new ProgressSwitcher(context, rootView);
+ }
+
+ /**
+ * Wrap content view with defaults views and create instance of {@link
+ * ru.vang.progressswitcher.ProgressSwitcher
+ * ProgressSwitcher}. Default view can be set by {@link #setDefaultProgressView(int)},
+ * {@link #setDefaultEmptyView(int)}, {@link #setDefaultErrorView(int)}
+ *
+ * @param context app context
+ * @param contentView the desired content to display, can't be null and must be attached to
+ * parent
+ * @return instance of {@link ru.vang.progressswitcher.ProgressSwitcher
+ * ProgressSwitcher}
+ */
+ public static ProgressSwitcher fromContentView(final Context context, final View contentView) {
+ if (contentView == null) {
+ throw new NullPointerException("Content view can't be null");
+ }
+
+ contentView.setId(R.id.content_view);
+ final ViewGroup parent = (ViewGroup) contentView.getParent();
+ if (parent == null) {
+ throw new IllegalStateException("Content view wasn't added to layout");
+ }
+ parent.removeView(contentView);
+
+ final FrameLayout rootView = new FrameLayout(context);
+ rootView.setId(R.id.content_container);
+ rootView.setLayoutParams(contentView.getLayoutParams());
+
+ final LayoutInflater inflater = LayoutInflater.from(context);
+ inflater.inflate(sDefaultProgressView, rootView);
+ if (sDefaultEmptyView > 0) {
+ inflater.inflate(sDefaultEmptyView, rootView);
+ }
+ if (sDefaultErrorView > 0) {
+ inflater.inflate(sDefaultErrorView, rootView);
+ }
+ rootView.addView(contentView);
+ parent.addView(rootView);
+
+ return new ProgressSwitcher(context, parent);
+ }
+
+ /**
+ * Set default layout for progress view
+ *
+ * @param layoutId default layout
+ * @see #fromContentView(android.content.Context, android.view.View)
+ */
+ public static void setDefaultProgressView(final int layoutId) {
+ sDefaultProgressView = layoutId;
+ }
+
+ /**
+ * Set default layout for empty view
+ *
+ * @param layoutId default layout
+ * @see #fromContentView(android.content.Context, android.view.View)
+ */
+ public static void setDefaultEmptyView(final int layoutId) {
+ sDefaultEmptyView = layoutId;
+ }
+
+ /**
+ * Set default layout for error view
+ *
+ * @param layoutId default layout
+ * @see #fromContentView(android.content.Context, android.view.View)
+ */
+ public static void setDefaultErrorView(final int layoutId) {
+ sDefaultErrorView = layoutId;
+ }
+
+ @Override
+ public View getContentView() {
+ return mContentView;
+ }
+
+ @Override
+ public void addContentView(final int layoutResId) {
+ final LayoutInflater layoutInflater = LayoutInflater.from(mContext);
+ final View contentView = layoutInflater.inflate(layoutResId, mContentContainer,
+ false);
+ addContentView(contentView);
+ }
+
+ @Override
+ public void addContentView(final View view) {
+ ensureContent();
+ if (view == null) {
+ throw new IllegalArgumentException("Content view can't be null");
+ }
+ if (mContentView == null) {
+ mContentContainer.addView(view);
+ } else {
+ final int index = mContentContainer.indexOfChild(mContentView);
+ // replace content view
+ mContentContainer.removeView(mContentView);
+ mContentContainer.addView(view, index);
+ }
+ view.setVisibility(View.GONE);
+ mContentView = view;
+ }
+
+ @Override
+ public void setContentView(final int contentViewId) {
+ ensureContent();
+ mContentView = mContentContainer.findViewById(contentViewId);
+ if (mContentView == null) {
+ throw new IllegalStateException("View with id "
+ + Integer.toHexString(contentViewId) + " wasn't found");
+ }
+ mContentView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void setContentView(final View contentView) {
+ if (contentView == null) {
+ throw new IllegalArgumentException("Content view can't be null");
+ }
+ ensureContent();
+ final int index = mContentContainer.indexOfChild(contentView);
+ if (index < 0) {
+ throw new IllegalStateException("View " + contentView
+ + " wasn't found in content container");
+ }
+ mContentView = contentView;
+ mContentView.setVisibility(View.GONE);
+ }
+
+ @Override
+ public void showProgress() {
+ showProgress(true);
+ }
+
+ @Override
+ public void showProgress(boolean animate) {
+ if (mProgressView == null) {
+ throw new IllegalStateException(
+ "Progress view should be specified in layout");
+ }
+ setContentShown(TYPE_PROGRESS, animate);
+ }
+
+ @Override
+ public void showContent() {
+ showContent(true);
+ }
+
+ @Override
+ public void showContent(boolean animate) {
+ if (mContentView == null) {
+ throw new IllegalStateException("Content view should be initialized");
+ }
+ setContentShown(TYPE_CONTENT, animate);
+ }
+
+ @Override
+ public void showEmpty() {
+ showEmpty(true);
+ }
+
+ @Override
+ public void showEmpty(boolean animate) {
+ if (mEmptyView == null) {
+ throw new IllegalStateException("Empty view should be specified in layout");
+ }
+ if (mContentView == null) {
+ throw new IllegalStateException("Content view must be initialized");
+ }
+
+ setContentShown(TYPE_EMPTY, animate);
+ }
+
+ @Override
+ public void showError() {
+ showError(true);
+ }
+
+ @Override
+ public void showError(boolean animate) {
+ if (mErrorView == null) {
+ throw new IllegalStateException("Error view should be specified in layout");
+ }
+ if (mContentView == null) {
+ throw new IllegalStateException("Content view must be initialized");
+ }
+
+ setContentShown(TYPE_ERROR, animate);
+ }
+
+ @Override
+ public void setEmptyText(final int resId) {
+ setEmptyText(mContext.getString(resId));
+ }
+
+ @Override
+ public void setEmptyText(final CharSequence text) {
+ ensureContent();
+ if (mEmptyView == null) {
+ throw new IllegalStateException("Empty view should be specified in layout");
+ }
+ setTextInternal(text, mEmptyView);
+ }
+
+ @Override
+ public void setEmptyText(final int resId, final int viewId) {
+ setEmptyText(mContext.getString(resId), viewId);
+ }
+
+ @Override
+ public void setEmptyText(final CharSequence text, final int viewId) {
+ ensureContent();
+ if (mEmptyView == null) {
+ throw new IllegalStateException("Empty view should be specified in layout");
+ }
+ final View emptyTextView = mEmptyView.findViewById(viewId);
+ setTextInternal(text, emptyTextView);
+ }
+
+ @Override
+ public void setErrorText(final int resId) {
+ setErrorText(mContext.getString(resId));
+ }
+
+ @Override
+ public void setErrorText(final CharSequence text) {
+ ensureContent();
+ if (mErrorView == null) {
+ throw new IllegalStateException("Error view should be specified in layout");
+ }
+ final View errorTextView = mErrorView.findViewById(R.id.error_text);
+ setTextInternal(text, errorTextView);
+ }
+
+ @Override
+ public void setErrorText(final int resId, final int viewId) {
+ setErrorText(mContext.getString(resId), viewId);
+ }
+
+ @Override
+ public void setErrorText(final CharSequence text, final int viewId) {
+ ensureContent();
+ if (mErrorView == null) {
+ throw new IllegalStateException("Error view should be specified in layout");
+ }
+ final View errorTextView = mErrorView.findViewById(viewId);
+ setTextInternal(text, errorTextView);
+ }
+
+ @Override
+ public void setOnEmptyViewClickListener(final OnClickListener onClickListener) {
+ if (mEmptyView == null) {
+ throw new IllegalStateException("Empty view should be provided in layout");
+ }
+
+ mEmptyView.setOnClickListener(onClickListener);
+ }
+
+ @Override
+ public void setOnEmptyViewClickListener(OnClickListener onClickListener, int viewId) {
+ if (mEmptyView == null) {
+ throw new IllegalStateException("Empty view should be provided in layout");
+ }
+ setOnClickListenerToView(mEmptyView, onClickListener, viewId);
+ }
+
+ @Override
+ public void setOnErrorViewClickListener(final OnClickListener onClickListener) {
+ if (mErrorView == null) {
+ throw new IllegalStateException("Error view should be provided in layout");
+ }
+
+ mErrorView.setOnClickListener(onClickListener);
+ }
+
+ @Override
+ public void setOnErrorViewClickListener(final OnClickListener onClickListener,
+ final int viewId) {
+ if (mErrorView == null) {
+ throw new IllegalStateException("Error view should be provided in layout");
+ }
+ addDefaultErrorButtonIfNecessary(viewId);
+ setOnClickListenerToView(mErrorView, onClickListener, viewId);
+ }
+
+ @Override
+ public boolean isProgressDisplayed() {
+ return mContentTypeShown == TYPE_PROGRESS;
+ }
+
+ @Override
+ public boolean isContentDisplayed() {
+ return mContentTypeShown == TYPE_CONTENT;
+ }
+
+ @Override
+ public boolean isEmptyViewDisplayed() {
+ return mContentTypeShown == TYPE_EMPTY;
+ }
+
+ @Override
+ public boolean isErrorViewDisplayed() {
+ return mContentTypeShown == TYPE_ERROR;
+ }
+
+ @Override
+ public void setCustomAnimation(final int animationIn, final int animationOut) {
+ mAnimationIn = animationIn;
+ mAnimationOut = animationOut;
+ }
+
+ void setRootView(final View rootView) {
+ initViewsFromRoot(rootView);
+ }
+
+ void setContentContainer(final View content) {
+ initViewFromContentContainer(content);
+ }
+
+ void addProgressView(final View progressView) {
+ if (progressView == null) {
+ throw new NullPointerException("Progress view can't be null");
+ }
+ mProgressView = progressView;
+ mContentContainer.addView(progressView);
+ }
+
+ void addEmptyView(final View emptyView) {
+ if (emptyView == null) {
+ throw new NullPointerException("Empty view can't be null");
+ }
+ mEmptyView = emptyView;
+ mContentContainer.addView(emptyView);
+ emptyView.setVisibility(View.GONE);
+ }
+
+ void addErrorView(final View errorView) {
+ if (errorView == null) {
+ throw new NullPointerException("Error view can't be null");
+ }
+ mErrorView = errorView;
+ mContentContainer.addView(errorView);
+ errorView.setVisibility(View.GONE);
+ }
+
+ void reset() {
+ mContentTypeShown = TYPE_PROGRESS;
+ mErrorView = mProgressView = mContentView = mEmptyView = null;
+ mContentContainer = null;
+ }
+
+
+ void setContentShown(final int type, final boolean animate) {
+ ensureContent();
+ if (mContentTypeShown == type) {
+ return;
+ }
+ switch (type) {
+ case TYPE_PROGRESS:
+ showView(mProgressView, animate);
+ break;
+ case TYPE_CONTENT:
+ showView(mContentView, animate);
+ break;
+ case TYPE_EMPTY:
+ showView(mEmptyView, animate);
+ break;
+ case TYPE_ERROR:
+ showView(mErrorView, animate);
+ break;
+ default:
+ throw new IllegalArgumentException("Unknown view type: " + type);
+ }
+ mContentTypeShown = type;
+ }
+
+ int getShownContentType() {
+ return mContentTypeShown;
+ }
+
+ private void initViewsFromRoot(final View rootView) {
+ if (rootView == null) {
+ throw new NullPointerException("Root view can't be null");
+ }
+
+ final View container = rootView.findViewById(R.id.content_container);
+ initViewFromContentContainer(container);
+ }
+
+ private void initViewFromContentContainer(final View container) {
+ if (container == null) {
+ throw new NullPointerException(
+ "Container with id content_container should be provided in layout");
+ }
+ if (!(container instanceof ViewGroup)) {
+ throw new IllegalStateException(
+ "Content container should be derived from ViewGroup");
+ }
+ mContentContainer = (ViewGroup) container;
+ ensureContent();
+ }
+
+ private void ensureContent() {
+ if (mContentView != null) {
+ return;
+ }
+ if (mContentContainer == null) {
+ throw new IllegalStateException("Content container not yet set");
+ }
+ if (mProgressView == null || mContentContainer.indexOfChild(mProgressView) < 0) {
+ mProgressView = mContentContainer.findViewById(R.id.progress_view);
+ if (mProgressView != null) {
+ mShownView = mProgressView;
+ }
+ }
+ if (mContentView == null || mContentContainer.indexOfChild(mContentView) < 0) {
+ mContentView = mContentContainer.findViewById(R.id.content_view);
+ if (mContentView != null) {
+ mContentView.setVisibility(View.GONE);
+ }
+ }
+ if (mEmptyView == null || mContentContainer.indexOfChild(mEmptyView) < 0) {
+ mEmptyView = mContentContainer.findViewById(R.id.empty_view);
+ if (mEmptyView != null) {
+ mEmptyView.setVisibility(View.GONE);
+ }
+ }
+ if (mErrorView == null || mContentContainer.indexOfChild(mErrorView) < 0) {
+ mErrorView = mContentContainer.findViewById(R.id.error_view);
+ if (mErrorView != null) {
+ mErrorView.setVisibility(View.GONE);
+ }
+ }
+ // We are starting without a content, so assume we won't
+ // have our data right away and start with the progress indicator.
+ if (mContentView == null && mProgressView != null) {
+ showView(mProgressView, false);
+ }
+ }
+
+ private void showView(final View view, final boolean animate) {
+ final View shownView = mShownView;
+
+ if (animate) {
+ if (shownView != null) {
+ shownView.startAnimation(AnimationUtils.loadAnimation(mContext,
+ mAnimationOut));
+ }
+ view.startAnimation(AnimationUtils.loadAnimation(mContext,
+ mAnimationIn));
+ } else {
+ if (shownView != null) {
+ shownView.clearAnimation();
+ }
+
+ view.clearAnimation();
+ }
+
+ if (shownView != null) {
+ shownView.setVisibility(View.GONE);
+ }
+ view.setVisibility(View.VISIBLE);
+ mShownView = view;
+ }
+
+ private void setTextInternal(final CharSequence text, final View textView) {
+ if (textView != null && textView instanceof TextView) {
+ ((TextView) textView).setText(text);
+ } else {
+ throw new IllegalStateException(
+ "Can't be used with a custom view. TextView should be provided.");
+ }
+ }
+
+ private void setOnClickListenerToView(final View view,
+ final OnClickListener onClickListener, final int viewId) {
+ final View targetView = view.findViewById(viewId);
+ if (targetView == null) {
+ throw new IllegalArgumentException("View with id "
+ + Integer.toHexString(viewId) + "wasn't found");
+ }
+
+ targetView.setOnClickListener(onClickListener);
+ }
+
+ private void addDefaultErrorButtonIfNecessary(final int viewId) {
+ if (mErrorView.getId() != R.id.error_view) {
+ return;
+ }
+
+ if (viewId != R.id.retry) {
+ return;
+ }
+
+ final View localView = mErrorView.findViewById(R.id.retry);
+ if (localView != null) {
+ return;
+ }
+
+ LayoutInflater.from(mContext).inflate(R.layout.retry_button, (ViewGroup) mErrorView);
+ }
+
+ public static class Builder {
+
+ private Context mContext;
+
+ private final FrameLayout mRootView;
+
+ private View mContentView;
+
+ private View mProgressView;
+
+ private View mEmptyView;
+
+ private View mErrorView;
+
+ public Builder(final Context context) {
+ mContext = context;
+
+ mRootView = new FrameLayout(context);
+ mRootView.setId(R.id.content_container);
+ }
+
+ public Builder setContentView(final int contentViewResId) {
+ final View contentView = inflateViewFromResource(contentViewResId);
+
+ return setContentView(contentView);
+ }
+
+ public Builder setContentView(final View contentView) {
+ if (contentView == null) {
+ throw new NullPointerException("Content view couldn't be null");
+ }
+
+ mContentView = contentView;
+
+ return this;
+ }
+
+ public Builder setProgressView(final int progressViewResId) {
+ final View progressView = inflateViewFromResource(progressViewResId);
+
+ return setProgressView(progressView);
+ }
+
+ public Builder setProgressView(final View progressView) {
+ if (progressView == null) {
+ throw new NullPointerException("Progress view couldn't be null");
+ }
+
+ mProgressView = progressView;
+
+ return this;
+ }
+
+ public Builder setEmptyView(final int emptyViewResId) {
+ final View emptyView = inflateViewFromResource(emptyViewResId);
+
+ return setEmptyView(emptyView);
+ }
+
+ public Builder setEmptyView(final View emptyView) {
+ if (emptyView == null) {
+ throw new NullPointerException("Empty view couldn't be null");
+ }
+
+ mEmptyView = emptyView;
+
+ return this;
+ }
+
+ public Builder setErrorView(final int errorViewResId) {
+ final View errorView = inflateViewFromResource(errorViewResId);
+
+ return setErrorView(errorView);
+ }
+
+ public Builder setErrorView(final View errorView) {
+ if (errorView == null) {
+ throw new NullPointerException("Error view couldn't be null");
+ }
+
+ mErrorView = errorView;
+
+ return this;
+ }
+
+ public ProgressSwitcher build() {
+ if (mContentView == null) {
+ throw new IllegalArgumentException("Content view wasn't set");
+ }
+
+ mRootView.addView(mContentView);
+ if (mProgressView != null) {
+ mRootView.addView(mProgressView);
+ }
+ if (mEmptyView != null) {
+ mRootView.addView(mEmptyView);
+ }
+ if (mErrorView != null) {
+ mRootView.addView(mErrorView);
+ }
+
+ return new ProgressSwitcher(mContext, mRootView);
+ }
+
+ private View inflateViewFromResource(final int resId) {
+ final LayoutInflater inflater = LayoutInflater.from(mContext);
+ return inflater.inflate(resId, mRootView, false);
+ }
+
+ }
+
+}
diff --git a/library/src/ru/vang/progressswitcher/ProgressWidget.java b/library/src/ru/vang/progressswitcher/ProgressWidget.java
new file mode 100644
index 0000000..ec4b9e4
--- /dev/null
+++ b/library/src/ru/vang/progressswitcher/ProgressWidget.java
@@ -0,0 +1,294 @@
+package ru.vang.progressswitcher;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.FrameLayout;
+
+public class ProgressWidget extends FrameLayout implements Switcher {
+
+ private ProgressSwitcher mProgressSwitcher;
+
+ private int mProgressViewResId;
+
+ private int mEmptyViewResId;
+
+ private int mErrorViewResId;
+
+ private ProgressWidget(final Context context) {
+ super(context);
+ }
+
+ public ProgressWidget(final Context context, final AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public ProgressWidget(final Context context, final AttributeSet attrs,
+ final int defStyle) {
+ super(context, attrs, defStyle);
+
+ mProgressSwitcher = new ProgressSwitcher(context);
+
+ final TypedArray typedArray = context.obtainStyledAttributes(attrs,
+ R.styleable.ProgressWidget, 0, 0);
+ if (typedArray == null) {
+ return;
+ }
+ try {
+ mProgressViewResId = typedArray.getResourceId(
+ R.styleable.ProgressWidget_progressViewLayout,
+ R.layout.ps_progress_view);
+ mEmptyViewResId = typedArray.getResourceId(
+ R.styleable.ProgressWidget_emptyViewLayout,
+ R.layout.ps_empty_view);
+ mErrorViewResId = typedArray.getResourceId(
+ R.styleable.ProgressWidget_errorViewLayout,
+ R.layout.ps_error_view);
+
+ final int animationIn = typedArray.getResourceId(R.styleable.ProgressWidget_animationIn,
+ ProgressSwitcher.DEFAULT_ANIMATION_IN);
+ final int animationOut = typedArray
+ .getResourceId(R.styleable.ProgressWidget_animationOut,
+ ProgressSwitcher.DEFAULT_ANIMATION_OUT);
+ mProgressSwitcher.setCustomAnimation(animationIn, animationOut);
+ } finally {
+ typedArray.recycle();
+ }
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+
+ if (getChildCount() == 0) {
+ throw new IllegalStateException("Content child must be provided");
+ }
+ if (getChildCount() > 2) {
+ throw new IllegalStateException(ProgressWidget.class.getSimpleName()
+ + " supports only one content child");
+ }
+
+ final View content = getChildAt(0);
+ final LayoutInflater inflater = LayoutInflater.from(getContext());
+ final View progressView = inflater.inflate(mProgressViewResId, this, false);
+ final View emptyView = inflater.inflate(mEmptyViewResId, this, false);
+ final View errorView = inflater.inflate(mErrorViewResId, this, false);
+
+ mProgressSwitcher.setContentContainer(this);
+ mProgressSwitcher.addProgressView(progressView);
+ mProgressSwitcher.addEmptyView(emptyView);
+ mProgressSwitcher.addErrorView(errorView);
+ mProgressSwitcher.setContentView(content);
+ }
+
+ @Override
+ protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ final SavedState ss = new SavedState(superState);
+ ss.shownType = mProgressSwitcher.getShownContentType();
+
+ return ss;
+ }
+
+ @Override
+ public void onRestoreInstanceState(final Parcelable state) {
+ final SavedState ss = (SavedState) state;
+ super.onRestoreInstanceState(ss.getSuperState());
+
+ mProgressSwitcher.setContentShown(ss.shownType, false);
+ }
+
+ @Override
+ public View getContentView() {
+ return mProgressSwitcher.getContentView();
+ }
+
+ @Override
+ public void addContentView(final int layoutResId) {
+ mProgressSwitcher.addContentView(layoutResId);
+ }
+
+ @Override
+ public void addContentView(final View view) {
+ mProgressSwitcher.addContentView(view);
+ }
+
+ @Override
+ public void setContentView(final int contentViewId) {
+ throw new UnsupportedOperationException("Content view must be set through xml");
+ }
+
+ @Override
+ public void setContentView(final View contentView) {
+ throw new UnsupportedOperationException("Content view must be set through xml");
+ }
+
+ @Override
+ public void setEmptyText(final int resId) {
+ mProgressSwitcher.setEmptyText(resId);
+ }
+
+ @Override
+ public void setEmptyText(final CharSequence text) {
+ mProgressSwitcher.setEmptyText(text);
+ }
+
+ @Override
+ public void setEmptyText(final int resId, final int viewId) {
+ mProgressSwitcher.setEmptyText(resId, viewId);
+ }
+
+ @Override
+ public void setEmptyText(final CharSequence text, final int viewId) {
+ mProgressSwitcher.setEmptyText(text, viewId);
+ }
+
+ @Override
+ public void setErrorText(final int resId) {
+ mProgressSwitcher.setErrorText(resId);
+ }
+
+ @Override
+ public void setErrorText(final CharSequence text) {
+ mProgressSwitcher.setErrorText(text);
+ }
+
+ @Override
+ public void setErrorText(int resId, int layoutResId) {
+ mProgressSwitcher.setErrorText(resId, layoutResId);
+ }
+
+ @Override
+ public void setErrorText(CharSequence text, int layoutResId) {
+ mProgressSwitcher.setErrorText(text, layoutResId);
+ }
+
+ @Override
+ public void setCustomAnimation(final int animationIn, final int animationOut) {
+ mProgressSwitcher.setCustomAnimation(animationIn, animationOut);
+ }
+
+ @Override
+ public void setOnEmptyViewClickListener(final OnClickListener onClickListener) {
+ mProgressSwitcher.setOnEmptyViewClickListener(onClickListener);
+ }
+
+ @Override
+ public void setOnEmptyViewClickListener(final OnClickListener onClickListener,
+ final int viewId) {
+ mProgressSwitcher.setOnEmptyViewClickListener(onClickListener, viewId);
+ }
+
+ @Override
+ public void setOnErrorViewClickListener(final OnClickListener onClickListener) {
+ mProgressSwitcher.setOnErrorViewClickListener(onClickListener);
+ }
+
+ @Override
+ public void setOnErrorViewClickListener(final OnClickListener onClickListener,
+ final int resId) {
+ mProgressSwitcher.setOnErrorViewClickListener(onClickListener, resId);
+ }
+
+ @Override
+ public void showContent() {
+ mProgressSwitcher.showContent();
+ }
+
+ @Override
+ public void showContent(final boolean animate) {
+ mProgressSwitcher.showContent(animate);
+ }
+
+ @Override
+ public void showProgress() {
+ mProgressSwitcher.showProgress();
+ }
+
+ @Override
+ public void showProgress(final boolean animate) {
+ mProgressSwitcher.showProgress(animate);
+ }
+
+ @Override
+ public void showEmpty() {
+ mProgressSwitcher.showEmpty();
+ }
+
+ @Override
+ public void showEmpty(boolean animate) {
+ mProgressSwitcher.showEmpty(animate);
+ }
+
+ @Override
+ public void showError() {
+ mProgressSwitcher.showError();
+ }
+
+ @Override
+ public void showError(final boolean animate) {
+ mProgressSwitcher.showError(animate);
+ }
+
+ @Override
+ public boolean isProgressDisplayed() {
+ return mProgressSwitcher.isProgressDisplayed();
+ }
+
+ @Override
+ public boolean isContentDisplayed() {
+ return mProgressSwitcher.isContentDisplayed();
+ }
+
+ @Override
+ public boolean isEmptyViewDisplayed() {
+ return mProgressSwitcher.isEmptyViewDisplayed();
+ }
+
+ @Override
+ public boolean isErrorViewDisplayed() {
+ return mProgressSwitcher.isErrorViewDisplayed();
+ }
+
+ private static class SavedState extends BaseSavedState {
+
+ int shownType;
+
+ SavedState(final Parcelable superState) {
+ super(superState);
+ }
+
+ /**
+ * Constructor called from {@link #CREATOR}
+ */
+ private SavedState(final Parcel in) {
+ super(in);
+ shownType = in.readInt();
+ }
+
+ @Override
+ public void writeToParcel(final Parcel out, final int flags) {
+ super.writeToParcel(out, flags);
+ out.writeInt(shownType);
+ }
+
+ public static final Parcelable.Creator CREATOR
+ = new Parcelable.Creator() {
+
+ @Override
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ @Override
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+
+ }
+}
diff --git a/library/src/ru/vang/progressswitcher/Switcher.java b/library/src/ru/vang/progressswitcher/Switcher.java
new file mode 100644
index 0000000..764dfee
--- /dev/null
+++ b/library/src/ru/vang/progressswitcher/Switcher.java
@@ -0,0 +1,339 @@
+package ru.vang.progressswitcher;
+
+import android.view.View;
+import android.view.View.OnClickListener;
+
+public interface Switcher {
+
+ /**
+ * Return content view or null if the content view has not been initialized.
+ *
+ * @return content view or null
+ * @see #addContentView(android.view.View)
+ * @see #addContentView(int)
+ * @see #setContentView(android.view.View)
+ * @see #setContentView(int)
+ */
+ public View getContentView();
+
+ /**
+ * Add the content content from a layout resource.
+ *
+ * @param layoutResId resource Id to be inflated.
+ * @see #addContentView(android.view.View)
+ * @see #setContentView(android.view.View)
+ * @see #setContentView(int)
+ * @see #getContentView()
+ */
+ public void addContentView(int layoutResId);
+
+ /**
+ * Add the content view to an explicit view. If the content view was
+ * installed earlier, the content will be replaced with a new view.
+ *
+ * @param view the desired content to display, can't be null.
+ * @see #addContentView(int)
+ * @see #setContentView(int)
+ * @see #setContentView(android.view.View)
+ * @see #getContentView()
+ */
+ public void addContentView(View view);
+
+ /**
+ * If content view was included in layout it can be set explicitly by Id.
+ *
+ * @param contentViewId Resource Id to be set.
+ * @see #addContentView(android.view.View)
+ * @see #addContentView(int)
+ * @see #setContentView(int)
+ * @see #getContentView()
+ */
+ public void setContentView(int contentViewId);
+
+ /**
+ * If content view was included in layout it can be set explicitly.
+ *
+ * @param contentView The desired view to set. Value can't be null.
+ * @see #addContentView(android.view.View)
+ * @see #addContentView(int)
+ * @see #setContentView(int)
+ * @see #getContentView()
+ */
+ public void setContentView(View contentView);
+
+ /**
+ * Display content view if it's not already shown.
+ *
+ * @see #showContent(boolean)
+ * @see #showProgress()
+ * @see #showEmpty()
+ * @see #showError()
+ */
+ public void showContent();
+
+ /**
+ * Display content view if it's not already shown.
+ *
+ * @param animate If true, the view will be shown with animation, false
+ * otherwise.
+ * @see #showContent()
+ * @see #showProgress()
+ * @see #showEmpty()
+ * @see #showError()
+ */
+ public void showContent(boolean animate);
+
+ /**
+ * Display progress view if it's not already shown.
+ *
+ * @see #showProgress(boolean)
+ * @see #showContent()
+ * @see #showEmpty()
+ * @see #showError()
+ */
+ public void showProgress();
+
+ /**
+ * Display progress view if it's not already shown.
+ *
+ * @param animate If true, the view will be shown with animation, false
+ * otherwise.
+ * @see #showContent()
+ * @see #showProgress()
+ * @see #showEmpty()
+ * @see #showError()
+ */
+ public void showProgress(boolean animate);
+
+ /**
+ * Display empty view if it's not already shown and corresponding view is
+ * provided.
+ *
+ * @see #showEmpty(boolean)
+ * @see #showContent()
+ * @see #showProgress()
+ * @see #showError()
+ */
+ public void showEmpty();
+
+ /**
+ * Display empty view if it's not already shown and corresponding view is
+ * provided.
+ *
+ * @param animate If true, the view will be shown with animation, false
+ * otherwise.
+ * @see #showEmpty()
+ * @see #showContent()
+ * @see #showProgress()
+ * @see #showError()
+ */
+ public void showEmpty(boolean animate);
+
+ /**
+ * Display error view if it's not already shown and corresponding view is
+ * provided.
+ *
+ * @see #showError(boolean)
+ * @see #showContent()
+ * @see #showProgress()
+ * @see #showEmpty()
+ */
+ public void showError();
+
+ /**
+ * Display error view if it's not already shown and corresponding view is
+ * provided.
+ *
+ * @param animate If true, the view will be shown with animation, false
+ * otherwise.
+ * @see #showError()
+ * @see #showContent()
+ * @see #showProgress()
+ * @see #showEmpty()
+ */
+ public void showError(boolean animate);
+
+ /**
+ * The default content for a ProgressSwitcher has a TextView that can be
+ * shown when the content is empty({@link #showEmpty()}). If you would like
+ * to have it shown, call this method to supply the text it should use.
+ *
+ * @param resId Identification of string from a resources
+ * @see #setEmptyText(CharSequence)
+ * @see #setEmptyText(CharSequence, int)
+ * @see #setEmptyText(int, int)
+ */
+ public void setEmptyText(int resId);
+
+ /**
+ * The default content for a ProgressSwitcher has a TextView that can be
+ * shown when the content is empty({@link #showEmpty()}). If you would like
+ * to have it shown, call this method to supply the text it should use.
+ *
+ * @param text Text for empty view
+ * @see #setEmptyText(int)
+ * @see #setEmptyText(CharSequence, int)
+ * @see #setEmptyText(int, int)
+ */
+ public void setEmptyText(CharSequence text);
+
+ /**
+ * If custom layout is provided for empty view, you can set empty text to
+ * specific view in provided layout.
+ *
+ * @param resId Identification of string from a resources
+ * @param viewId View id to which text shall be assigned
+ * @see #setEmptyText(int)
+ * @see #setEmptyText(CharSequence)
+ * @see #setEmptyText(CharSequence, int)
+ */
+ public void setEmptyText(int resId, int viewId);
+
+ /**
+ * If custom layout is provided for empty view, you can set empty text to
+ * specific view in provided layout.
+ *
+ * @param text Text for empty view
+ * @param viewId View id to which text shall be assigned
+ * @see #setEmptyText(int)
+ * @see #setEmptyText(CharSequence)
+ * @see #setEmptyText(int, int)
+ */
+ public void setEmptyText(CharSequence text, int viewId);
+
+ /**
+ * The default content for a ProgressSwitcher has a TextView that can be
+ * shown when the error occurred ({@link #showError()}). If you would like
+ * to change text, call this method to supply the text it should use.
+ *
+ * @param resId Identification of string from a resources
+ * @see #setErrorText(CharSequence)
+ * @see #setErrorText(CharSequence, int)
+ * @see #setErrorText(int, int)
+ */
+ public void setErrorText(int resId);
+
+ /**
+ * The default content for a ProgressSwitcher has a TextView that can be
+ * shown when the error occurred ({@link #showError()}). If you would like
+ * to change text, call this method to supply the text it should use.
+ *
+ * @param text Text for empty view
+ * @see #setErrorText(int)
+ * @see #setErrorText(CharSequence, int)
+ * @see #setErrorText(int, int)
+ */
+ public void setErrorText(CharSequence text);
+
+ /**
+ * If custom layout is provided for error view, you can set empty text to
+ * specific view in provided layout.
+ *
+ * @param resId Identification of string from a resources
+ * @param viewId View id to which text shall be assigned
+ * @see #setErrorText(int)
+ * @see #setErrorText(CharSequence)
+ * @see #setErrorText(CharSequence, int)
+ */
+ public void setErrorText(int resId, int viewId);
+
+ /**
+ * If custom layout is provided for error view, you can set empty text to
+ * specific view in provided layout.
+ *
+ * @param text Text for empty view
+ * @param viewId View id to which text shall be assigned
+ * @see #setErrorText(int)
+ * @see #setErrorText(CharSequence)
+ * @see #setErrorText(int, int)
+ */
+ public void setErrorText(CharSequence text, int viewId);
+
+ /**
+ * If you want provide some action by clicking on empty view, you can set
+ * listener here.
+ *
+ * @param onClickListener On error view click listener
+ * @see #setOnErrorViewClickListener(android.view.View.OnClickListener, int)
+ */
+ public void setOnEmptyViewClickListener(OnClickListener onClickListener);
+
+ /**
+ * If you want provide some action by clicking on specific view in empty
+ * layout, you can set listener here.
+ *
+ * @param onClickListener On error view click listener
+ * @param viewId View id to which listener shall be assigned
+ * @see #setOnErrorViewClickListener(android.view.View.OnClickListener)
+ */
+ public void setOnEmptyViewClickListener(OnClickListener onClickListener, int viewId);
+
+ /**
+ * If you want provide some action by clicking on error view, you can set
+ * listener here.
+ *
+ * @param onClickListener On error view click listener
+ * @see #setOnErrorViewClickListener(android.view.View.OnClickListener, int)
+ */
+ public void setOnErrorViewClickListener(OnClickListener onClickListener);
+
+ /**
+ * If you want provide some action by clicking on specific view in error
+ * layout, you can set listener here. You can use {@link ru.vang.progressswitcher.R.id#retry
+ * R.id.retry} to set listener to "Retry" button in default layout.
+ *
+ * @param onClickListener On error view click listener
+ * @param viewId View id to which listener shall be assigned
+ * @see #setOnErrorViewClickListener(android.view.View.OnClickListener)
+ */
+ public void setOnErrorViewClickListener(OnClickListener onClickListener, int viewId);
+
+ /**
+ * Returns true if the progress view is displayed.
+ *
+ * @return a boolean indicating if the progress view is displayed.
+ * @see #isContentDisplayed()
+ * @see #isEmptyViewDisplayed()
+ * @see #isErrorViewDisplayed()
+ */
+ public boolean isProgressDisplayed();
+
+ /**
+ * Returns true if the content view is displayed.
+ *
+ * @return a boolean indicating if the content view is displayed.
+ * @see #isProgressDisplayed()
+ * @see #isEmptyViewDisplayed()
+ * @see #isErrorViewDisplayed()
+ */
+ public boolean isContentDisplayed();
+
+ /**
+ * Returns true if the empty view is displayed.
+ *
+ * @return a boolean indicating if the empty view is displayed.
+ * @see #isProgressDisplayed()
+ * @see #isContentDisplayed()
+ * @see #isErrorViewDisplayed()
+ */
+ public boolean isEmptyViewDisplayed();
+
+ /**
+ * Returns true if the error view is displayed.
+ *
+ * @return a boolean indicating if the error view is displayed.
+ * @see #isProgressDisplayed()
+ * @see #isContentDisplayed()
+ * @see #isEmptyViewDisplayed()
+ */
+ public boolean isErrorViewDisplayed();
+
+ /**
+ * Set custom animation for both appearing view and disappearing view.
+ *
+ * @param animationIn Animation for appearing view
+ * @param animationOut Animation for disappearing view
+ */
+ public void setCustomAnimation(final int animationIn, final int animationOut);
+
+}
diff --git a/maven_push.gradle b/maven_push.gradle
new file mode 100644
index 0000000..4fa99b7
--- /dev/null
+++ b/maven_push.gradle
@@ -0,0 +1,77 @@
+apply plugin: 'maven'
+apply plugin: 'signing'
+
+def sonatypeRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2"
+
+configurations {
+ archives {
+ extendsFrom configurations.default
+ }
+}
+
+
+uploadArchives {
+ configuration = configurations.archives
+ repositories.mavenDeployer {
+ beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }
+
+ pom.artifactId = POM_ARTIFACT_ID
+
+ repository(url: sonatypeRepositoryUrl) {
+ authentication(userName: sonatypeUsername,
+ password: sonatypePassword)
+ }
+
+ pom.project {
+ name POM_NAME
+ packaging POM_PACKAGING
+ description POM_DESCRIPTION
+ url POM_URL
+
+ scm {
+ url POM_SCM_URL
+ connection POM_SCM_CONNECTION
+ developerConnection POM_SCM_DEV_CONNECTION
+ }
+
+ licenses {
+ license {
+ name POM_LICENCE_NAME
+ url POM_LICENCE_URL
+ distribution POM_LICENCE_DIST
+ }
+ }
+
+ developers {
+ developer {
+ name POM_DEVELOPER_NAME
+ email 'prehistoric2003@gmail.com'
+ }
+ }
+ }
+ }
+}
+
+signing {
+ required { isReleaseBuild() && gradle.taskGraph.hasTask("uploadArchives") }
+ sign configurations.archives
+}
+
+task androidJavadocs(type: Javadoc) {
+ source = android.sourceSets.main.java.sourceFiles
+}
+
+task androidJavadocsJar(type: Jar) {
+ classifier = 'javadoc'
+ from androidJavadocs.destinationDir
+}
+
+task androidSourcesJar(type: Jar) {
+ classifier = 'sources'
+ from android.sourceSets.main.java.sourceFiles
+}
+
+artifacts {
+ archives androidSourcesJar
+ archives androidJavadocsJar
+}
diff --git a/sample/AndroidManifest.xml b/sample/AndroidManifest.xml
index 23ec021..fc64d39 100644
--- a/sample/AndroidManifest.xml
+++ b/sample/AndroidManifest.xml
@@ -1,12 +1,12 @@
+ android:targetSdkVersion="19"/>
+ android:name=".ProgressSamplesActivity"
+ android:label="@string/app_name">
-
+
\ No newline at end of file
diff --git a/sample/build.gradle b/sample/build.gradle
new file mode 100644
index 0000000..0bda214
--- /dev/null
+++ b/sample/build.gradle
@@ -0,0 +1,58 @@
+apply plugin: 'com.android.application'
+
+dependencies {
+ compile project(':library')
+}
+
+android {
+ compileSdkVersion 19
+ buildToolsVersion '19.1.0'
+ defaultConfig {
+ minSdkVersion 4
+ targetSdkVersion 19
+ versionName project.VERSION_NAME
+ versionCode Integer.parseInt(project.VERSION_CODE)
+ }
+ sourceSets {
+ main {
+ manifest.srcFile 'AndroidManifest.xml'
+ java.srcDirs = ['src']
+ resources.srcDirs = ['src']
+ aidl.srcDirs = ['src']
+ renderscript.srcDirs = ['src']
+ res.srcDirs = ['res']
+ assets.srcDirs = ['assets']
+ }
+
+ // Move the tests to tests/java, tests/res, etc...
+ instrumentTest.setRoot('tests')
+
+ // Move the build types to build-types/
+ // For instance, build-types/debug/java, build-types/debug/AndroidManifest.xml, ...
+ // This moves them out of them default location under src//... which would
+ // conflict with src/ being used by the main source set.
+ // Adding new build types or product flavors should be accompanied
+ // by a similar customization.
+ debug.setRoot('build-types/debug')
+ release.setRoot('build-types/release')
+ }
+ Properties props = new Properties()
+ props.load(new FileInputStream(file(project.property("ProgressSwitcherSamples.properties"))))
+ signingConfigs {
+ release {
+ storeFile file(props['keystore'])
+ storePassword props['keystore.password']
+ keyAlias props['keyAlias']
+ keyPassword props['keyPassword']
+ }
+ }
+ buildTypes {
+ release {
+ runProguard true
+ proguardFile getDefaultProguardFile('proguard-android.txt')
+ signingConfig signingConfigs.release
+ }
+ }
+ productFlavors {
+ }
+}
diff --git a/sample/gradle.properties b/sample/gradle.properties
new file mode 100644
index 0000000..a1349e4
--- /dev/null
+++ b/sample/gradle.properties
@@ -0,0 +1 @@
+ProgressSwitcherSamples.properties=signing/signing.properties
\ No newline at end of file
diff --git a/sample/ic_launcher-web.png b/sample/ic_launcher-web.png
new file mode 100644
index 0000000..2e96b8e
Binary files /dev/null and b/sample/ic_launcher-web.png differ
diff --git a/sample/project.properties b/sample/project.properties
index 1a02f56..8230a7f 100644
--- a/sample/project.properties
+++ b/sample/project.properties
@@ -11,6 +11,6 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt
# Project target.
-target=android-17
+target=android-19
android.library.reference.1=../library
diff --git a/sample/res/anim/zoom_in.xml b/sample/res/anim/zoom_in.xml
new file mode 100644
index 0000000..d7099d0
--- /dev/null
+++ b/sample/res/anim/zoom_in.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/anim/zoom_out.xml b/sample/res/anim/zoom_out.xml
new file mode 100644
index 0000000..3694381
--- /dev/null
+++ b/sample/res/anim/zoom_out.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/drawable-hdpi/ic_action_refresh.png b/sample/res/drawable-hdpi/ic_action_refresh.png
deleted file mode 100755
index 553e90b..0000000
Binary files a/sample/res/drawable-hdpi/ic_action_refresh.png and /dev/null differ
diff --git a/sample/res/drawable-hdpi/ic_launcher.png b/sample/res/drawable-hdpi/ic_launcher.png
old mode 100755
new mode 100644
index 9eb64d2..b6ec54a
Binary files a/sample/res/drawable-hdpi/ic_launcher.png and b/sample/res/drawable-hdpi/ic_launcher.png differ
diff --git a/sample/res/drawable-mdpi/emo_im_crying.png b/sample/res/drawable-mdpi/emo_im_crying.png
deleted file mode 100644
index 3151125..0000000
Binary files a/sample/res/drawable-mdpi/emo_im_crying.png and /dev/null differ
diff --git a/sample/res/drawable-mdpi/ic_action_refresh.png b/sample/res/drawable-mdpi/ic_action_refresh.png
deleted file mode 100755
index a370457..0000000
Binary files a/sample/res/drawable-mdpi/ic_action_refresh.png and /dev/null differ
diff --git a/sample/res/drawable-mdpi/ic_launcher.png b/sample/res/drawable-mdpi/ic_launcher.png
old mode 100755
new mode 100644
index d9184b3..e281bb6
Binary files a/sample/res/drawable-mdpi/ic_launcher.png and b/sample/res/drawable-mdpi/ic_launcher.png differ
diff --git a/sample/res/drawable-xhdpi/ic_action_refresh.png b/sample/res/drawable-xhdpi/ic_action_refresh.png
deleted file mode 100755
index e34cc7b..0000000
Binary files a/sample/res/drawable-xhdpi/ic_action_refresh.png and /dev/null differ
diff --git a/sample/res/drawable-xhdpi/ic_launcher.png b/sample/res/drawable-xhdpi/ic_launcher.png
old mode 100755
new mode 100644
index c244526..27363ee
Binary files a/sample/res/drawable-xhdpi/ic_launcher.png and b/sample/res/drawable-xhdpi/ic_launcher.png differ
diff --git a/sample/res/drawable-xhdpi/ic_sad.png b/sample/res/drawable-xhdpi/ic_sad.png
new file mode 100644
index 0000000..efbae88
Binary files /dev/null and b/sample/res/drawable-xhdpi/ic_sad.png differ
diff --git a/sample/res/drawable-xhdpi/ic_toad.png b/sample/res/drawable-xhdpi/ic_toad.png
new file mode 100644
index 0000000..9e1224f
Binary files /dev/null and b/sample/res/drawable-xhdpi/ic_toad.png differ
diff --git a/sample/res/drawable-xhdpi/moose.jpeg b/sample/res/drawable-xhdpi/moose.jpeg
new file mode 100644
index 0000000..3677607
Binary files /dev/null and b/sample/res/drawable-xhdpi/moose.jpeg differ
diff --git a/sample/res/drawable-xhdpi/new_york.jpg b/sample/res/drawable-xhdpi/new_york.jpg
deleted file mode 100644
index a279974..0000000
Binary files a/sample/res/drawable-xhdpi/new_york.jpg and /dev/null differ
diff --git a/sample/res/drawable-xxhdpi/ic_launcher.png b/sample/res/drawable-xxhdpi/ic_launcher.png
old mode 100755
new mode 100644
index b53cab9..e95cc0e
Binary files a/sample/res/drawable-xxhdpi/ic_launcher.png and b/sample/res/drawable-xxhdpi/ic_launcher.png differ
diff --git a/sample/res/drawable/shadow.xml b/sample/res/drawable/shadow.xml
deleted file mode 100644
index eeb7c63..0000000
--- a/sample/res/drawable/shadow.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/res/layout-land/view_content.xml b/sample/res/layout-land/view_content.xml
new file mode 100644
index 0000000..e38e3cd
--- /dev/null
+++ b/sample/res/layout-land/view_content.xml
@@ -0,0 +1,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/layout-v11/panel.xml b/sample/res/layout-v11/panel.xml
new file mode 100644
index 0000000..8767c67
--- /dev/null
+++ b/sample/res/layout-v11/panel.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/res/layout/actvitiy_progress.xml b/sample/res/layout/actvitiy_progress.xml
new file mode 100644
index 0000000..4a6e783
--- /dev/null
+++ b/sample/res/layout/actvitiy_progress.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/res/layout/custom_empty_view.xml b/sample/res/layout/custom_empty_view.xml
new file mode 100644
index 0000000..692c259
--- /dev/null
+++ b/sample/res/layout/custom_empty_view.xml
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/layout/custom_error_view.xml b/sample/res/layout/custom_error_view.xml
new file mode 100644
index 0000000..1fc50ed
--- /dev/null
+++ b/sample/res/layout/custom_error_view.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/layout/custom_progress_view.xml b/sample/res/layout/custom_progress_view.xml
new file mode 100644
index 0000000..8cd0a58
--- /dev/null
+++ b/sample/res/layout/custom_progress_view.xml
@@ -0,0 +1,22 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/layout/fragment_custom_layouts.xml b/sample/res/layout/fragment_custom_layouts.xml
new file mode 100644
index 0000000..d06362e
--- /dev/null
+++ b/sample/res/layout/fragment_custom_layouts.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/layout/fragment_custom_progress.xml b/sample/res/layout/fragment_custom_progress.xml
deleted file mode 100644
index db0e4cc..0000000
--- a/sample/res/layout/fragment_custom_progress.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/sample/res/layout/fragment_progress_widget.xml b/sample/res/layout/fragment_progress_widget.xml
new file mode 100644
index 0000000..5cd6c47
--- /dev/null
+++ b/sample/res/layout/fragment_progress_widget.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/layout/panel.xml b/sample/res/layout/panel.xml
new file mode 100644
index 0000000..181d7d5
--- /dev/null
+++ b/sample/res/layout/panel.xml
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/sample/res/layout/view_content.xml b/sample/res/layout/view_content.xml
index 2d7a351..e38e3cd 100644
--- a/sample/res/layout/view_content.xml
+++ b/sample/res/layout/view_content.xml
@@ -17,13 +17,15 @@
-->
+ android:padding="16dp">
+ android:src="@drawable/moose"/>
-
-
\ No newline at end of file
diff --git a/sample/res/values/ids.xml b/sample/res/values/ids.xml
new file mode 100644
index 0000000..1286aab
--- /dev/null
+++ b/sample/res/values/ids.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/sample/res/values/strings.xml b/sample/res/values/strings.xml
index 8516cd9..a9dabee 100644
--- a/sample/res/values/strings.xml
+++ b/sample/res/values/strings.xml
@@ -17,18 +17,20 @@
-->
- Android-ProgressFragment
- Refresh
- New York City
- New York is the most populous city in the United States and the center of the New York
- Metropolitan Area, one of the most populous urban agglomerations in the world. The city is referred to as New
- York City or the City of New York to distinguish it from the State of New York, of which it is a part. A global
- power city, New York exerts a significant impact upon commerce, finance, media, art, fashion, research,
- technology, education, and entertainment. The home of the United Nations Headquarters, New York is an important
- center for international diplomacy and has been described as the cultural capital of the world.
-
- No Data
- Loading…
-
+ ProgressSwitcher
+ Moose
+ The moose (North America) or Eurasian elk (Europe) (Alces alces)
+ is the largest extant species in the deer family. Moose are distinguished by the palmate
+ antlers of the males; other members of the family have antlers with a dendritic ("twig-like")
+ configuration. Moose typically inhabit boreal and mixed deciduous forests of the Northern
+ Hemisphere in temperate to subarctic climates. Moose used to have a much wider range but
+ hunting and other human activities greatly reduced it over the years. Moose have been
+ reintroduced to some of their former habitats. Currently, most moose are found in Canada,
+ Alaska, Scandinavia and Russia. Their diet consists of both terrestrial and aquatic
+ vegetation. The most common moose predators are wolves, bears, and humans. Unlike most
+ other deer species, moose are solitary animals and do not form herds. Although generally
+ slow-moving and sedentary, moose can become aggressive and move surprisingly quickly if
+ angered or startled. Their mating season in the autumn can lead to spectacular fights
+ between males competing for a female.
\ No newline at end of file
diff --git a/sample/src/com/devspark/progressfragment/sample/CustomLayoutProgressFragment.java b/sample/src/com/devspark/progressfragment/sample/CustomLayoutProgressFragment.java
deleted file mode 100644
index 145c30b..0000000
--- a/sample/src/com/devspark/progressfragment/sample/CustomLayoutProgressFragment.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2013 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.progressfragment.sample;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.*;
-import com.devspark.progressfragment.ProgressFragment;
-
-/**
- * Sample implementation of {@link com.devspark.progressfragment.ProgressFragment}.
- *
- * @author Evgeny Shishkin
- */
-public class CustomLayoutProgressFragment extends ProgressFragment {
- private View mContentView;
- private Handler mHandler;
- private Runnable mShowContentRunnable = new Runnable() {
-
- @Override
- public void run() {
- setContentEmpty(true);
- setContentShown(true);
- }
-
- };
-
- public static CustomLayoutProgressFragment newInstance() {
- CustomLayoutProgressFragment fragment = new CustomLayoutProgressFragment();
- return fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mContentView = inflater.inflate(R.layout.view_content, null);
- return inflater.inflate(R.layout.fragment_custom_progress, container, false);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- // Setup content view
- setContentView(mContentView);
- // Setup text for empty content
- setEmptyText(R.string.empty);
- obtainData();
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mHandler.removeCallbacks(mShowContentRunnable);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.refresh, menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_refresh:
- obtainData();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void obtainData() {
- // Show indeterminate progress
- setContentShown(false);
-
- mHandler = new Handler();
- mHandler.postDelayed(mShowContentRunnable, 3000);
- }
-}
diff --git a/sample/src/com/devspark/progressfragment/sample/DefaultProgressFragment.java b/sample/src/com/devspark/progressfragment/sample/DefaultProgressFragment.java
deleted file mode 100644
index eeace88..0000000
--- a/sample/src/com/devspark/progressfragment/sample/DefaultProgressFragment.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2013 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.progressfragment.sample;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.*;
-import com.devspark.progressfragment.ProgressFragment;
-
-/**
- * Sample implementation of {@link com.devspark.progressfragment.ProgressFragment}.
- *
- * @author Evgeny Shishkin
- */
-public class DefaultProgressFragment extends ProgressFragment {
- private View mContentView;
- private Handler mHandler;
- private Runnable mShowContentRunnable = new Runnable() {
-
- @Override
- public void run() {
- setContentShown(true);
- }
-
- };
-
- public static DefaultProgressFragment newInstance() {
- DefaultProgressFragment fragment = new DefaultProgressFragment();
- return fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mContentView = inflater.inflate(R.layout.view_content, null);
- return super.onCreateView(inflater, container, savedInstanceState);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- // Setup content view
- setContentView(mContentView);
- // Setup text for empty content
- setEmptyText(R.string.empty);
- obtainData();
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mHandler.removeCallbacks(mShowContentRunnable);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.refresh, menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_refresh:
- obtainData();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void obtainData() {
- // Show indeterminate progress
- setContentShown(false);
-
- mHandler = new Handler();
- mHandler.postDelayed(mShowContentRunnable, 3000);
- }
-}
diff --git a/sample/src/com/devspark/progressfragment/sample/EmptyContentProgressFragment.java b/sample/src/com/devspark/progressfragment/sample/EmptyContentProgressFragment.java
deleted file mode 100644
index 6579292..0000000
--- a/sample/src/com/devspark/progressfragment/sample/EmptyContentProgressFragment.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Copyright (C) 2013 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.progressfragment.sample;
-
-import android.os.Bundle;
-import android.os.Handler;
-import android.view.*;
-import com.devspark.progressfragment.ProgressFragment;
-
-/**
- * Sample implementation of {@link com.devspark.progressfragment.ProgressFragment}.
- *
- * @author Evgeny Shishkin
- */
-public class EmptyContentProgressFragment extends ProgressFragment {
- private View mContentView;
- private Handler mHandler;
- private Runnable mShowContentRunnable = new Runnable() {
-
- @Override
- public void run() {
- setContentEmpty(true);
- setContentShown(true);
- }
-
- };
-
- public static EmptyContentProgressFragment newInstance() {
- EmptyContentProgressFragment fragment = new EmptyContentProgressFragment();
- return fragment;
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setHasOptionsMenu(true);
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- mContentView = inflater.inflate(R.layout.view_content, null);
- return super.onCreateView(inflater, container, savedInstanceState);
- }
-
- @Override
- public void onActivityCreated(Bundle savedInstanceState) {
- super.onActivityCreated(savedInstanceState);
- // Setup content view
- setContentView(mContentView);
- // Setup text for empty content
- setEmptyText(R.string.empty);
- obtainData();
- }
-
- @Override
- public void onDestroyView() {
- super.onDestroyView();
- mHandler.removeCallbacks(mShowContentRunnable);
- }
-
- @Override
- public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
- inflater.inflate(R.menu.refresh, menu);
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case R.id.menu_refresh:
- obtainData();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-
- private void obtainData() {
- // Show indeterminate progress
- setContentShown(false);
-
- mHandler = new Handler();
- mHandler.postDelayed(mShowContentRunnable, 3000);
- }
-}
diff --git a/sample/src/com/devspark/progressfragment/sample/ProgressActivity.java b/sample/src/com/devspark/progressfragment/sample/ProgressActivity.java
deleted file mode 100644
index 70890e4..0000000
--- a/sample/src/com/devspark/progressfragment/sample/ProgressActivity.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) 2013 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.progressfragment.sample;
-
-import android.annotation.TargetApi;
-import android.os.Build;
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.support.v4.app.FragmentActivity;
-import android.view.MenuItem;
-
-/**
- * @author Evgeny Shishkin
- */
-public class ProgressActivity extends FragmentActivity {
- public static final String EXTRA_TITLE = "com.devspark.progressfragment.sample.extras.EXTRA_TITLE";
- public static final String EXTRA_FRAGMENT = "com.devspark.progressfragment.sample.extras.EXTRA_FRAGMENT";
- public static final int FRAGMENT_DEFAULT = 0;
- public static final int FRAGMENT_EMPTY_CONTENT = 1;
- public static final int FRAGMENT_CUSTOM_LAYOUT = 2;
-
- @TargetApi(Build.VERSION_CODES.HONEYCOMB)
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setTitle(getIntent().getStringExtra(EXTRA_TITLE));
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
- getActionBar().setDisplayHomeAsUpEnabled(true);
- }
- // Check what fragment is shown, replace if needed.
- Fragment fragment = getSupportFragmentManager().findFragmentById(android.R.id.content);
- if (fragment == null) {
- // Make new fragment to show.
- int fragmentId = getIntent().getIntExtra(EXTRA_FRAGMENT, FRAGMENT_DEFAULT);
- switch (fragmentId) {
- case FRAGMENT_DEFAULT:
- fragment = DefaultProgressFragment.newInstance();
- break;
- case FRAGMENT_EMPTY_CONTENT:
- fragment = EmptyContentProgressFragment.newInstance();
- break;
- case FRAGMENT_CUSTOM_LAYOUT:
- fragment = CustomLayoutProgressFragment.newInstance();
- break;
- default:
- fragment = DefaultProgressFragment.newInstance();
- break;
-
- }
- getSupportFragmentManager().beginTransaction().add(android.R.id.content, fragment).commit();
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- switch (item.getItemId()) {
- case android.R.id.home:
- finish();
- return true;
- default:
- return super.onOptionsItemSelected(item);
- }
- }
-}
diff --git a/sample/src/ru/vang/progressswitcher/sample/BaseProgressSwitcherFragment.java b/sample/src/ru/vang/progressswitcher/sample/BaseProgressSwitcherFragment.java
new file mode 100644
index 0000000..6c59e4c
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/BaseProgressSwitcherFragment.java
@@ -0,0 +1,26 @@
+package ru.vang.progressswitcher.sample;
+
+import ru.vang.progressswitcher.ProgressFragment;
+
+public abstract class BaseProgressSwitcherFragment extends ProgressFragment implements ProgressActivity.OnSwitchListener {
+
+ @Override
+ public void showProgress() {
+ super.showProgress();
+ }
+
+ @Override
+ public void showContent() {
+ super.showContent();
+ }
+
+ @Override
+ public void showEmpty() {
+ super.showEmpty();
+ }
+
+ @Override
+ public void showError() {
+ super.showError();
+ }
+}
diff --git a/sample/src/ru/vang/progressswitcher/sample/BaseSwitcherFragment.java b/sample/src/ru/vang/progressswitcher/sample/BaseSwitcherFragment.java
new file mode 100644
index 0000000..3b1dc06
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/BaseSwitcherFragment.java
@@ -0,0 +1,34 @@
+package ru.vang.progressswitcher.sample;
+
+import android.support.v4.app.Fragment;
+
+import ru.vang.progressswitcher.Switcher;
+
+public abstract class BaseSwitcherFragment extends Fragment implements ProgressActivity.OnSwitchListener {
+
+ protected Switcher mProgressSwitcher;
+
+ public void setProgressSwitcher(final Switcher switcher) {
+ mProgressSwitcher = switcher;
+ }
+
+ @Override
+ public void showProgress() {
+ mProgressSwitcher.showProgress();
+ }
+
+ @Override
+ public void showContent() {
+ mProgressSwitcher.showContent();
+ }
+
+ @Override
+ public void showEmpty() {
+ mProgressSwitcher.showEmpty();
+ }
+
+ @Override
+ public void showError() {
+ mProgressSwitcher.showError();
+ }
+}
diff --git a/sample/src/ru/vang/progressswitcher/sample/CustomLayoutsFragment.java b/sample/src/ru/vang/progressswitcher/sample/CustomLayoutsFragment.java
new file mode 100644
index 0000000..78314a2
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/CustomLayoutsFragment.java
@@ -0,0 +1,28 @@
+package ru.vang.progressswitcher.sample;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import ru.vang.progressswitcher.ProgressWidget;
+
+public class CustomLayoutsFragment extends BaseSwitcherFragment {
+
+ public static CustomLayoutsFragment newInstance() {
+ final CustomLayoutsFragment fragment = new CustomLayoutsFragment();
+
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.fragment_custom_layouts, container, false);
+ final ProgressWidget progressWidget = (ProgressWidget) view.findViewById(R.id.progress_widget);
+ setProgressSwitcher(progressWidget);
+
+ return view;
+ }
+
+}
diff --git a/sample/src/ru/vang/progressswitcher/sample/ProgressActivity.java b/sample/src/ru/vang/progressswitcher/sample/ProgressActivity.java
new file mode 100644
index 0000000..56d1969
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/ProgressActivity.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2013 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 ru.vang.progressswitcher.sample;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v4.app.Fragment;
+import android.support.v4.app.FragmentActivity;
+import android.view.MenuItem;
+import android.view.View;
+
+/**
+ * @author Evgeny Shishkin
+ */
+public class ProgressActivity extends FragmentActivity implements View.OnClickListener {
+
+ public static final String EXTRA_TITLE = "ru.vang.progressfragment.sample.extras.EXTRA_TITLE";
+
+ public static final String EXTRA_FRAGMENT
+ = "ru.vang.progressfragment.sample.extras.EXTRA_FRAGMENT";
+
+ public static final int FRAGMENT_PROGRESS_FRAGMENT = 0;
+
+ public static final int FRAGMENT_SWITCHER = 1;
+
+ public static final int FRAGMENT_WIDGET = 2;
+
+ public static final int FRAGMENT_CUSTOM_LAYOUTS = 3;
+
+ private static final String TAG_FRAGMENT = "fragment_progress";
+
+ public interface OnSwitchListener {
+
+ public void showProgress();
+
+ public void showContent();
+
+ public void showEmpty();
+
+ public void showError();
+
+ }
+
+ private Fragment mFragment;
+
+ @Override
+ protected void onCreate(final Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setTitle(getIntent().getStringExtra(EXTRA_TITLE));
+ setContentView(R.layout.actvitiy_progress);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ new ActionBarHelper().setDisplayHomeAsUpEnabled(true);
+ }
+
+ findViewById(R.id.action_progress).setOnClickListener(this);
+ findViewById(R.id.action_content).setOnClickListener(this);
+ findViewById(R.id.action_empty).setOnClickListener(this);
+ findViewById(R.id.action_error).setOnClickListener(this);
+
+ if (savedInstanceState == null) {
+ int fragmentId = getIntent().getIntExtra(EXTRA_FRAGMENT, FRAGMENT_PROGRESS_FRAGMENT);
+ switch (fragmentId) {
+ case FRAGMENT_PROGRESS_FRAGMENT:
+ mFragment = ProgressFragmentSampleFragment.newInstance();
+ break;
+ case FRAGMENT_SWITCHER:
+ mFragment = ProgressSwitcherFragment.newInstance();
+ break;
+ case FRAGMENT_WIDGET:
+ mFragment = ProgressWidgetFragment.newInstance();
+ break;
+ case FRAGMENT_CUSTOM_LAYOUTS:
+ mFragment = CustomLayoutsFragment.newInstance();
+ break;
+ default:
+ throw new IllegalArgumentException("Incorrect index: " + fragmentId);
+
+ }
+ getSupportFragmentManager().beginTransaction()
+ .add(R.id.container, mFragment, TAG_FRAGMENT).commit();
+ } else {
+ mFragment = getSupportFragmentManager().findFragmentByTag(TAG_FRAGMENT);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ finish();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ public void onClick(final View view) {
+ final int id = view.getId();
+ final OnSwitchListener localFragment = (OnSwitchListener) mFragment;
+ switch (id) {
+ case R.id.action_progress:
+ localFragment.showProgress();
+ break;
+ case R.id.action_content:
+ localFragment.showContent();
+ break;
+ case R.id.action_empty:
+ localFragment.showEmpty();
+ break;
+ case R.id.action_error:
+ localFragment.showError();
+ break;
+ }
+ }
+
+ class ActionBarHelper {
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ void setDisplayHomeAsUpEnabled(boolean showHomeAsUp) {
+ getActionBar().setDisplayHomeAsUpEnabled(showHomeAsUp);
+ }
+ }
+}
diff --git a/sample/src/ru/vang/progressswitcher/sample/ProgressFragmentSampleFragment.java b/sample/src/ru/vang/progressswitcher/sample/ProgressFragmentSampleFragment.java
new file mode 100644
index 0000000..169a032
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/ProgressFragmentSampleFragment.java
@@ -0,0 +1,40 @@
+package ru.vang.progressswitcher.sample;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+public class ProgressFragmentSampleFragment extends BaseProgressSwitcherFragment {
+
+ private View mContentView;
+
+ public static ProgressFragmentSampleFragment newInstance() {
+ final ProgressFragmentSampleFragment fragment = new ProgressFragmentSampleFragment();
+
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ mContentView = inflater.inflate(R.layout.view_content, null);
+
+ return super.onCreateView(inflater, container, savedInstanceState);
+ }
+
+
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ addContentView(mContentView);
+ setOnErrorViewClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+
+ }
+ }, R.id.retry);
+ }
+
+}
diff --git a/sample/src/com/devspark/progressfragment/sample/MainActivity.java b/sample/src/ru/vang/progressswitcher/sample/ProgressSamplesActivity.java
similarity index 71%
rename from sample/src/com/devspark/progressfragment/sample/MainActivity.java
rename to sample/src/ru/vang/progressswitcher/sample/ProgressSamplesActivity.java
index ab24b25..97109d0 100644
--- a/sample/src/com/devspark/progressfragment/sample/MainActivity.java
+++ b/sample/src/ru/vang/progressswitcher/sample/ProgressSamplesActivity.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.devspark.progressfragment.sample;
+package ru.vang.progressswitcher.sample;
import android.app.ListActivity;
import android.content.Intent;
@@ -23,17 +23,15 @@
import android.widget.ArrayAdapter;
import android.widget.ListView;
-/**
- * @author Evgeny Shishkin
- */
-public class MainActivity extends ListActivity {
+public class ProgressSamplesActivity extends ListActivity {
- private String[] examples = new String[]{"Default", "Empty content", "Custom layout"};
+ private String[] examples = new String[]{"ProgressFragment", "ProgressSwitcher", "ProgressWidget", "Custom layouts"};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- ArrayAdapter arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, examples);
+ ArrayAdapter arrayAdapter = new ArrayAdapter(this,
+ android.R.layout.simple_list_item_1, examples);
setListAdapter(arrayAdapter);
}
@@ -43,13 +41,20 @@ protected void onListItemClick(ListView l, View v, int position, long id) {
intent.putExtra(ProgressActivity.EXTRA_TITLE, examples[position]);
switch (position) {
case 0:
- intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_DEFAULT);
+ intent.putExtra(ProgressActivity.EXTRA_FRAGMENT,
+ ProgressActivity.FRAGMENT_PROGRESS_FRAGMENT);
break;
case 1:
- intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_EMPTY_CONTENT);
+ intent.putExtra(ProgressActivity.EXTRA_FRAGMENT,
+ ProgressActivity.FRAGMENT_SWITCHER);
break;
case 2:
- intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_CUSTOM_LAYOUT);
+ intent.putExtra(ProgressActivity.EXTRA_FRAGMENT,
+ ProgressActivity.FRAGMENT_WIDGET);
+ break;
+ case 3:
+ intent.putExtra(ProgressActivity.EXTRA_FRAGMENT,
+ ProgressActivity.FRAGMENT_CUSTOM_LAYOUTS);
break;
default:
break;
diff --git a/sample/src/ru/vang/progressswitcher/sample/ProgressSwitcherFragment.java b/sample/src/ru/vang/progressswitcher/sample/ProgressSwitcherFragment.java
new file mode 100644
index 0000000..3894666
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/ProgressSwitcherFragment.java
@@ -0,0 +1,37 @@
+package ru.vang.progressswitcher.sample;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import ru.vang.progressswitcher.ProgressSwitcher;
+
+public class ProgressSwitcherFragment extends BaseSwitcherFragment {
+
+ private View mContentView;
+
+ public static ProgressSwitcherFragment newInstance() {
+ final ProgressSwitcherFragment fragment = new ProgressSwitcherFragment();
+
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ mContentView = inflater.inflate(R.layout.view_content, container, false);
+
+ return mContentView;
+ }
+
+ @Override
+ public void onActivityCreated(final Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+
+ final ProgressSwitcher progressSwitcher = ProgressSwitcher
+ .fromContentView(getActivity(), mContentView);
+ setProgressSwitcher(progressSwitcher);
+ }
+
+}
diff --git a/sample/src/ru/vang/progressswitcher/sample/ProgressWidgetFragment.java b/sample/src/ru/vang/progressswitcher/sample/ProgressWidgetFragment.java
new file mode 100644
index 0000000..ef96022
--- /dev/null
+++ b/sample/src/ru/vang/progressswitcher/sample/ProgressWidgetFragment.java
@@ -0,0 +1,29 @@
+package ru.vang.progressswitcher.sample;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import ru.vang.progressswitcher.ProgressWidget;
+import ru.vang.progressswitcher.Switcher;
+
+public class ProgressWidgetFragment extends BaseSwitcherFragment {
+
+ public static ProgressWidgetFragment newInstance() {
+ final ProgressWidgetFragment fragment = new ProgressWidgetFragment();
+
+ return fragment;
+ }
+
+ @Override
+ public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
+ final Bundle savedInstanceState) {
+ final View view = inflater.inflate(R.layout.fragment_progress_widget, container, false);
+ final Switcher switcher = (ProgressWidget) view.findViewById(R.id.progress_widget);
+ setProgressSwitcher(switcher);
+
+ return view;
+ }
+}
+
diff --git a/sample/web_hi_res_512.png b/sample/web_hi_res_512.png
deleted file mode 100755
index 610ff92..0000000
Binary files a/sample/web_hi_res_512.png and /dev/null differ
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..612d9e4
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,2 @@
+include ':library'
+include ':sample'