diff --git a/docs-android/app/app.iml b/docs-android/app/app.iml
index 42f9493f..8e392ec5 100644
--- a/docs-android/app/app.iml
+++ b/docs-android/app/app.iml
@@ -70,7 +70,10 @@
+
+
+
diff --git a/docs-android/app/build.gradle b/docs-android/app/build.gradle
index d1e5d434..29fd4179 100644
--- a/docs-android/app/build.gradle
+++ b/docs-android/app/build.gradle
@@ -36,5 +36,8 @@ android {
}
dependencies {
+ compile fileTree(dir: 'libs', include: '*.jar')
compile 'com.android.support:support-v4:19.1.0'
+ compile 'ch.acra:acra:4.5.0'
+ compile 'com.loopj.android:android-async-http:1.4.4'
}
diff --git a/docs-android/app/libs/android-query.0.26.8.jar b/docs-android/app/libs/android-query.0.26.8.jar
new file mode 100644
index 00000000..7fc26f17
Binary files /dev/null and b/docs-android/app/libs/android-query.0.26.8.jar differ
diff --git a/docs-android/app/src/main/AndroidManifest.xml b/docs-android/app/src/main/AndroidManifest.xml
index 86960760..62370917 100644
--- a/docs-android/app/src/main/AndroidManifest.xml
+++ b/docs-android/app/src/main/AndroidManifest.xml
@@ -2,27 +2,31 @@
+
+
+
+
+
-
+
-
+ android:name=".activity.MainActivity"
+ android:label="@string/app_name"
+ android:logo="@drawable/ic_launcher"
+ android:launchMode="singleTop">
diff --git a/docs-android/app/src/main/java/com/sismics/docs/DocDetailActivity.java b/docs-android/app/src/main/java/com/sismics/docs/DocDetailActivity.java
deleted file mode 100644
index 0ba834eb..00000000
--- a/docs-android/app/src/main/java/com/sismics/docs/DocDetailActivity.java
+++ /dev/null
@@ -1,67 +0,0 @@
-package com.sismics.docs;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.FragmentActivity;
-import android.support.v4.app.NavUtils;
-import android.view.MenuItem;
-
-/**
- * An activity representing a single Doc detail screen. This
- * activity is only used on handset devices. On tablet-size devices,
- * item details are presented side-by-side with a list of items
- * in a {@link DocListActivity}.
- *
- * This activity is mostly just a 'shell' activity containing nothing
- * more than a {@link DocDetailFragment}.
- */
-public class DocDetailActivity extends FragmentActivity {
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_doc_detail);
-
- // Show the Up button in the action bar.
- getActionBar().setDisplayHomeAsUpEnabled(true);
-
- // savedInstanceState is non-null when there is fragment state
- // saved from previous configurations of this activity
- // (e.g. when rotating the screen from portrait to landscape).
- // In this case, the fragment will automatically be re-added
- // to its container so we don't need to manually add it.
- // For more information, see the Fragments API guide at:
- //
- // http://developer.android.com/guide/components/fragments.html
- //
- if (savedInstanceState == null) {
- // Create the detail fragment and add it to the activity
- // using a fragment transaction.
- Bundle arguments = new Bundle();
- arguments.putString(DocDetailFragment.ARG_ITEM_ID,
- getIntent().getStringExtra(DocDetailFragment.ARG_ITEM_ID));
- DocDetailFragment fragment = new DocDetailFragment();
- fragment.setArguments(arguments);
- getSupportFragmentManager().beginTransaction()
- .add(R.id.doc_detail_container, fragment)
- .commit();
- }
- }
-
- @Override
- public boolean onOptionsItemSelected(MenuItem item) {
- int id = item.getItemId();
- if (id == android.R.id.home) {
- // This ID represents the Home or Up button. In the case of this
- // activity, the Up button is shown. Use NavUtils to allow users
- // to navigate up one level in the application structure. For
- // more details, see the Navigation pattern on Android Design:
- //
- // http://developer.android.com/design/patterns/navigation.html#up-vs-back
- //
- NavUtils.navigateUpTo(this, new Intent(this, DocListActivity.class));
- return true;
- }
- return super.onOptionsItemSelected(item);
- }
-}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/DocDetailFragment.java b/docs-android/app/src/main/java/com/sismics/docs/DocDetailFragment.java
deleted file mode 100644
index eae4abb4..00000000
--- a/docs-android/app/src/main/java/com/sismics/docs/DocDetailFragment.java
+++ /dev/null
@@ -1,61 +0,0 @@
-package com.sismics.docs;
-
-import android.os.Bundle;
-import android.support.v4.app.Fragment;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.TextView;
-
-import com.sismics.docs.dummy.DummyContent;
-
-/**
- * A fragment representing a single Doc detail screen.
- * This fragment is either contained in a {@link DocListActivity}
- * in two-pane mode (on tablets) or a {@link DocDetailActivity}
- * on handsets.
- */
-public class DocDetailFragment extends Fragment {
- /**
- * The fragment argument representing the item ID that this fragment
- * represents.
- */
- public static final String ARG_ITEM_ID = "item_id";
-
- /**
- * The dummy content this fragment is presenting.
- */
- private DummyContent.DummyItem mItem;
-
- /**
- * Mandatory empty constructor for the fragment manager to instantiate the
- * fragment (e.g. upon screen orientation changes).
- */
- public DocDetailFragment() {
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- if (getArguments().containsKey(ARG_ITEM_ID)) {
- // Load the dummy content specified by the fragment
- // arguments. In a real-world scenario, use a Loader
- // to load content from a content provider.
- mItem = DummyContent.ITEM_MAP.get(getArguments().getString(ARG_ITEM_ID));
- }
- }
-
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container,
- Bundle savedInstanceState) {
- View rootView = inflater.inflate(R.layout.fragment_doc_detail, container, false);
-
- // Show the dummy content as text in a TextView.
- if (mItem != null) {
- ((TextView) rootView.findViewById(R.id.doc_detail)).setText(mItem.content);
- }
-
- return rootView;
- }
-}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/DocListActivity.java b/docs-android/app/src/main/java/com/sismics/docs/DocListActivity.java
deleted file mode 100644
index 6e0a15a8..00000000
--- a/docs-android/app/src/main/java/com/sismics/docs/DocListActivity.java
+++ /dev/null
@@ -1,81 +0,0 @@
-package com.sismics.docs;
-
-import android.content.Intent;
-import android.os.Bundle;
-import android.support.v4.app.FragmentActivity;
-
-
-/**
- * An activity representing a list of Docs. This activity
- * has different presentations for handset and tablet-size devices. On
- * handsets, the activity presents a list of items, which when touched,
- * lead to a {@link DocDetailActivity} representing
- * item details. On tablets, the activity presents the list of items and
- * item details side-by-side using two vertical panes.
- *
- * The activity makes heavy use of fragments. The list of items is a
- * {@link DocListFragment} and the item details
- * (if present) is a {@link DocDetailFragment}.
- *
- * This activity also implements the required
- * {@link DocListFragment.Callbacks} interface
- * to listen for item selections.
- */
-public class DocListActivity extends FragmentActivity
- implements DocListFragment.Callbacks {
-
- /**
- * Whether or not the activity is in two-pane mode, i.e. running on a tablet
- * device.
- */
- private boolean mTwoPane;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_doc_list);
-
- if (findViewById(R.id.doc_detail_container) != null) {
- // The detail container view will be present only in the
- // large-screen layouts (res/values-large and
- // res/values-sw600dp). If this view is present, then the
- // activity should be in two-pane mode.
- mTwoPane = true;
-
- // In two-pane mode, list items should be given the
- // 'activated' state when touched.
- ((DocListFragment) getSupportFragmentManager()
- .findFragmentById(R.id.doc_list))
- .setActivateOnItemClick(true);
- }
-
- // TODO: If exposing deep links into your app, handle intents here.
- }
-
- /**
- * Callback method from {@link DocListFragment.Callbacks}
- * indicating that the item with the given ID was selected.
- */
- @Override
- public void onItemSelected(String id) {
- if (mTwoPane) {
- // In two-pane mode, show the detail view in this activity by
- // adding or replacing the detail fragment using a
- // fragment transaction.
- Bundle arguments = new Bundle();
- arguments.putString(DocDetailFragment.ARG_ITEM_ID, id);
- DocDetailFragment fragment = new DocDetailFragment();
- fragment.setArguments(arguments);
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.doc_detail_container, fragment)
- .commit();
-
- } else {
- // In single-pane mode, simply start the detail activity
- // for the selected item ID.
- Intent detailIntent = new Intent(this, DocDetailActivity.class);
- detailIntent.putExtra(DocDetailFragment.ARG_ITEM_ID, id);
- startActivity(detailIntent);
- }
- }
-}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/DocListFragment.java b/docs-android/app/src/main/java/com/sismics/docs/DocListFragment.java
deleted file mode 100644
index eac1ab18..00000000
--- a/docs-android/app/src/main/java/com/sismics/docs/DocListFragment.java
+++ /dev/null
@@ -1,151 +0,0 @@
-package com.sismics.docs;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.support.v4.app.ListFragment;
-import android.view.View;
-import android.widget.ArrayAdapter;
-import android.widget.ListView;
-
-import com.sismics.docs.dummy.DummyContent;
-
-/**
- * A list fragment representing a list of Docs. This fragment
- * also supports tablet devices by allowing list items to be given an
- * 'activated' state upon selection. This helps indicate which item is
- * currently being viewed in a {@link DocDetailFragment}.
- *
- * Activities containing this fragment MUST implement the {@link Callbacks}
- * interface.
- */
-public class DocListFragment extends ListFragment {
-
- /**
- * The serialization (saved instance state) Bundle key representing the
- * activated item position. Only used on tablets.
- */
- private static final String STATE_ACTIVATED_POSITION = "activated_position";
-
- /**
- * The fragment's current callback object, which is notified of list item
- * clicks.
- */
- private Callbacks mCallbacks = sDummyCallbacks;
-
- /**
- * The current activated item position. Only used on tablets.
- */
- private int mActivatedPosition = ListView.INVALID_POSITION;
-
- /**
- * A callback interface that all activities containing this fragment must
- * implement. This mechanism allows activities to be notified of item
- * selections.
- */
- public interface Callbacks {
- /**
- * Callback for when an item has been selected.
- */
- public void onItemSelected(String id);
- }
-
- /**
- * A dummy implementation of the {@link Callbacks} interface that does
- * nothing. Used only when this fragment is not attached to an activity.
- */
- private static Callbacks sDummyCallbacks = new Callbacks() {
- @Override
- public void onItemSelected(String id) {
- }
- };
-
- /**
- * Mandatory empty constructor for the fragment manager to instantiate the
- * fragment (e.g. upon screen orientation changes).
- */
- public DocListFragment() {
- }
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
-
- // TODO: replace with a real list adapter.
- setListAdapter(new ArrayAdapter(
- getActivity(),
- android.R.layout.simple_list_item_activated_1,
- android.R.id.text1,
- DummyContent.ITEMS));
- }
-
- @Override
- public void onViewCreated(View view, Bundle savedInstanceState) {
- super.onViewCreated(view, savedInstanceState);
-
- // Restore the previously serialized activated item position.
- if (savedInstanceState != null
- && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) {
- setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION));
- }
- }
-
- @Override
- public void onAttach(Activity activity) {
- super.onAttach(activity);
-
- // Activities containing this fragment must implement its callbacks.
- if (!(activity instanceof Callbacks)) {
- throw new IllegalStateException("Activity must implement fragment's callbacks.");
- }
-
- mCallbacks = (Callbacks) activity;
- }
-
- @Override
- public void onDetach() {
- super.onDetach();
-
- // Reset the active callbacks interface to the dummy implementation.
- mCallbacks = sDummyCallbacks;
- }
-
- @Override
- public void onListItemClick(ListView listView, View view, int position, long id) {
- super.onListItemClick(listView, view, position, id);
-
- // Notify the active callbacks interface (the activity, if the
- // fragment is attached to one) that an item has been selected.
- mCallbacks.onItemSelected(DummyContent.ITEMS.get(position).id);
- }
-
- @Override
- public void onSaveInstanceState(Bundle outState) {
- super.onSaveInstanceState(outState);
- if (mActivatedPosition != ListView.INVALID_POSITION) {
- // Serialize and persist the activated item position.
- outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition);
- }
- }
-
- /**
- * Turns on activate-on-click mode. When this mode is on, list items will be
- * given the 'activated' state when touched.
- */
- public void setActivateOnItemClick(boolean activateOnItemClick) {
- // When setting CHOICE_MODE_SINGLE, ListView will automatically
- // give items the 'activated' state when touched.
- getListView().setChoiceMode(activateOnItemClick
- ? ListView.CHOICE_MODE_SINGLE
- : ListView.CHOICE_MODE_NONE);
- }
-
- private void setActivatedPosition(int position) {
- if (position == ListView.INVALID_POSITION) {
- getListView().setItemChecked(mActivatedPosition, false);
- } else {
- getListView().setItemChecked(position, true);
- }
-
- mActivatedPosition = position;
- }
-}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/MainApplication.java b/docs-android/app/src/main/java/com/sismics/docs/MainApplication.java
new file mode 100644
index 00000000..805ae8a0
--- /dev/null
+++ b/docs-android/app/src/main/java/com/sismics/docs/MainApplication.java
@@ -0,0 +1,46 @@
+package com.sismics.docs;
+
+import android.app.Application;
+
+import com.androidquery.callback.BitmapAjaxCallback;
+import com.sismics.docs.model.application.ApplicationContext;
+import com.sismics.docs.util.PreferenceUtil;
+
+import org.acra.ACRA;
+import org.acra.ReportingInteractionMode;
+import org.acra.annotation.ReportsCrashes;
+import org.acra.sender.HttpSender.Method;
+import org.acra.sender.HttpSender.Type;
+import org.json.JSONObject;
+
+/**
+ * Main application.
+ *
+ * @author bgamard
+ */
+@ReportsCrashes(formKey = "",
+ httpMethod = Method.PUT,
+ reportType = Type.JSON,
+ formUri = "http://acralyzer.sismics.com/docs-report",
+ formUriBasicAuthLogin = "reporter",
+ formUriBasicAuthPassword = "jOS9ezJR",
+ mode = ReportingInteractionMode.TOAST,
+ forceCloseDialogAfterToast = true,
+ resToastText = R.string.crash_toast_text)
+public class MainApplication extends Application {
+ @Override
+ public void onCreate() {
+ ACRA.init(this);
+
+ // Fetching /user/info from cache
+ JSONObject json = PreferenceUtil.getCachedJson(getApplicationContext(), PreferenceUtil.PREF_CACHED_USER_INFO_JSON);
+ ApplicationContext.getInstance().setUserInfo(getApplicationContext(), json);
+
+ super.onCreate();
+ }
+
+ @Override
+ public void onLowMemory() {
+ BitmapAjaxCallback.clearCache();
+ }
+}
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java
new file mode 100644
index 00000000..cf5a92bf
--- /dev/null
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/LoginActivity.java
@@ -0,0 +1,184 @@
+package com.sismics.docs.activity;
+
+import android.content.Intent;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.support.v4.app.FragmentActivity;
+import android.text.Html;
+import android.text.method.LinkMovementMethod;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+
+import com.androidquery.AQuery;
+import com.loopj.android.http.JsonHttpResponseHandler;
+import com.sismics.docs.R;
+import com.sismics.docs.listener.CallbackListener;
+import com.sismics.docs.model.application.ApplicationContext;
+import com.sismics.docs.resource.UserResource;
+import com.sismics.docs.ui.form.Validator;
+import com.sismics.docs.ui.form.validator.Required;
+import com.sismics.docs.util.DialogUtil;
+import com.sismics.docs.util.PreferenceUtil;
+
+import org.apache.http.Header;
+import org.json.JSONObject;
+
+/**
+ * Login activity.
+ *
+ * @author bgamard
+ */
+public class LoginActivity extends FragmentActivity {
+
+ /**
+ * User interface.
+ */
+ private View loginForm;
+ private View progressBar;
+
+ @Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.login_activity);
+
+ AQuery aq = new AQuery(this);
+ aq.id(R.id.loginExplain)
+ .text(Html.fromHtml(getString(R.string.login_explain)))
+ .getTextView()
+ .setMovementMethod(LinkMovementMethod.getInstance());
+
+ final EditText txtServer = aq.id(R.id.txtServer).getEditText();
+ final EditText txtUsername = aq.id(R.id.txtUsername).getEditText();
+ final EditText txtPassword = aq.id(R.id.txtPassword).getEditText();
+ final Button btnConnect = aq.id(R.id.btnConnect).getButton();
+ loginForm = aq.id(R.id.loginForm).getView();
+ progressBar = aq.id(R.id.progressBar).getView();
+
+ PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
+
+ loginForm.setVisibility(View.GONE);
+ progressBar.setVisibility(View.VISIBLE);
+
+ // Form validation
+ final Validator validator = new Validator(false);
+ validator.addValidable(this, txtServer, new Required());
+ validator.addValidable(this, txtUsername, new Required());
+ validator.addValidable(this, txtPassword, new Required());
+ validator.setOnValidationChanged(new CallbackListener() {
+ @Override
+ public void onComplete() {
+ btnConnect.setEnabled(validator.isValidated());
+ }
+ });
+
+ // Preset saved server URL
+ String serverUrl = PreferenceUtil.getStringPreference(this, PreferenceUtil.PREF_SERVER_URL);
+ if (serverUrl != null) {
+ txtServer.setText(serverUrl);
+ }
+
+ tryConnect();
+
+ // Login button
+ btnConnect.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ loginForm.setVisibility(View.GONE);
+ progressBar.setVisibility(View.VISIBLE);
+
+ PreferenceUtil.setServerUrl(LoginActivity.this, txtServer.getText().toString());
+
+ try {
+ UserResource.login(getApplicationContext(), txtUsername.getText().toString(), txtPassword.getText().toString(), new JsonHttpResponseHandler() {
+ @Override
+ public void onSuccess(JSONObject json) {
+ // Empty previous user caches
+ PreferenceUtil.resetUserCache(getApplicationContext());
+
+ // Getting user info and redirecting to main activity
+ ApplicationContext.getInstance().fetchUserInfo(LoginActivity.this, new CallbackListener() {
+ @Override
+ public void onComplete() {
+ Intent intent = new Intent(LoginActivity.this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ }
+ });
+ }
+
+ @Override
+ public void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) {
+ loginForm.setVisibility(View.VISIBLE);
+ progressBar.setVisibility(View.GONE);
+
+ if (responseBytes != null && new String(responseBytes).contains("\"ForbiddenError\"")) {
+ DialogUtil.showOkDialog(LoginActivity.this, R.string.login_fail_title, R.string.login_fail);
+ } else {
+ DialogUtil.showOkDialog(LoginActivity.this, R.string.network_error_title, R.string.network_error);
+ }
+ }
+ });
+ } catch (IllegalArgumentException e) {
+ // Given URL is not valid
+ loginForm.setVisibility(View.VISIBLE);
+ progressBar.setVisibility(View.GONE);
+ PreferenceUtil.setServerUrl(LoginActivity.this, null);
+ DialogUtil.showOkDialog(LoginActivity.this, R.string.invalid_url_title, R.string.invalid_url);
+ }
+ }
+ });
+ }
+
+ /**
+ * Try to get a "session".
+ */
+ private void tryConnect() {
+ String serverUrl = PreferenceUtil.getStringPreference(this, PreferenceUtil.PREF_SERVER_URL);
+ if (serverUrl == null) {
+ // Server URL is empty
+ loginForm.setVisibility(View.VISIBLE);
+ progressBar.setVisibility(View.GONE);
+ return;
+ }
+
+ if (ApplicationContext.getInstance().isLoggedIn()) {
+ // If we are already connected (from cache data)
+ // redirecting to main activity
+ Intent intent = new Intent(LoginActivity.this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ } else {
+ // Trying to get user data
+ UserResource.info(getApplicationContext(), new JsonHttpResponseHandler() {
+ @Override
+ public void onSuccess(final JSONObject json) {
+ if (json.optBoolean("anonymous", true)) {
+ loginForm.setVisibility(View.VISIBLE);
+ return;
+ }
+
+ // Save user data in application context
+ ApplicationContext.getInstance().setUserInfo(getApplicationContext(), json);
+
+ // Redirecting to main activity
+ Intent intent = new Intent(LoginActivity.this, MainActivity.class);
+ startActivity(intent);
+ finish();
+ }
+
+ @Override
+ public void onFailure(final int statusCode, final Header[] headers, final byte[] responseBytes, final Throwable throwable) {
+ DialogUtil.showOkDialog(LoginActivity.this, R.string.network_error_title, R.string.network_error);
+ loginForm.setVisibility(View.VISIBLE);
+ }
+
+ @Override
+ public void onFinish() {
+ progressBar.setVisibility(View.GONE);
+ }
+ });
+ }
+ }
+}
\ No newline at end of file
diff --git a/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
new file mode 100644
index 00000000..fb61adb1
--- /dev/null
+++ b/docs-android/app/src/main/java/com/sismics/docs/activity/MainActivity.java
@@ -0,0 +1,123 @@
+package com.sismics.docs.activity;
+
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.support.v4.app.ActionBarDrawerToggle;
+import android.support.v4.app.FragmentActivity;
+import android.support.v4.view.GravityCompat;
+import android.support.v4.widget.DrawerLayout;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.Window;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+import com.sismics.docs.R;
+import com.sismics.docs.model.application.ApplicationContext;
+
+/**
+ * Main activity.
+ *
+ * @author bgamard
+ */
+public class MainActivity extends FragmentActivity {
+
+ private ListView drawerList;
+ private ActionBarDrawerToggle drawerToggle;
+
+ @Override
+ protected void onCreate(final Bundle args) {
+ super.onCreate(args);
+
+ // Check if logged in
+ if (!ApplicationContext.getInstance().isLoggedIn()) {
+ startActivity(new Intent(this, LoginActivity.class));
+ finish();
+ return;
+ }
+
+ // Setup the activity
+ requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+ setContentView(R.layout.main_activity);
+
+ // Cache view references
+ DrawerLayout drawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
+ drawerList = (ListView) findViewById(R.id.drawer_list);
+
+ // Drawer item click listener
+ drawerList.setOnItemClickListener(new ListView.OnItemClickListener() {
+ @Override
+ public void onItemClick(AdapterView> parent, View view, int position, long id) {
+ }
+ });
+
+ if (drawerLayout != null) {
+ // Set a custom shadow that overlays the main content when the drawer opens
+ drawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
+
+ // Enable ActionBar app icon to behave as action to toggle nav drawer
+ getActionBar().setDisplayHomeAsUpEnabled(true);
+ getActionBar().setHomeButtonEnabled(true);
+
+ // ActionBarDrawerToggle ties together the the proper interactions
+ // between the sliding drawer and the action bar app icon
+ drawerToggle = new ActionBarDrawerToggle(
+ this, /* host Activity */
+ drawerLayout, /* DrawerLayout object */
+ R.drawable.ic_drawer, R.string.drawer_open, R.string.drawer_close) {
+
+ @Override
+ public void onDrawerOpened(View drawerView) {
+ invalidateOptionsMenu();
+ }
+
+ @Override
+ public void onDrawerClosed(View drawerView) {
+ invalidateOptionsMenu();
+ }
+ };
+ drawerLayout.setDrawerListener(drawerToggle);
+ }
+ }
+
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case android.R.id.home:
+ // The action bar home/up action should open or close the drawer.
+ // ActionBarDrawerToggle will take care of this.
+ if (drawerToggle != null && drawerToggle.onOptionsItemSelected(item)) {
+ return true;
+ }
+ return true;
+
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+ }
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ super.onPostCreate(savedInstanceState);
+ if (drawerToggle != null) {
+ // Sync the toggle state after onRestoreInstanceState has occurred.
+ drawerToggle.syncState();
+ }
+ }
+
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ if (drawerToggle != null) {
+ // Pass any configuration change to the drawer toggle
+ drawerToggle.onConfigurationChanged(newConfig);
+ }
+ }
+
+ @Override
+ protected void onSaveInstanceState(Bundle outState) {
+ super.onSaveInstanceState(outState);
+ outState.putInt("drawerItemSelected", drawerList.getCheckedItemPosition());
+ }
+}
\ No newline at end of file
diff --git a/docs-android/app/src/main/java/com/sismics/docs/dummy/DummyContent.java b/docs-android/app/src/main/java/com/sismics/docs/dummy/DummyContent.java
deleted file mode 100644
index ee227fc5..00000000
--- a/docs-android/app/src/main/java/com/sismics/docs/dummy/DummyContent.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.sismics.docs.dummy;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * Helper class for providing sample content for user interfaces created by
- * Android template wizards.
- *