diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f893a0..888a944 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,11 @@ Change Log ========== -Version 1.3.2 *(In development)* +Version 1.4.0 *(2013-12-04)* -------------------------------- -* ... +* Implemented `ProgressListFragment` & `SherlockProgressListFragment`. +* Rename `GridFragment` to `ProgressGridFragment`. +* Rename `SherlockGridFragment` to `SherlockProgressGridFragment`. Version 1.3.1 *(2013-10-28)* diff --git a/README.md b/README.md index 3e8a361..91d5b11 100644 --- a/README.md +++ b/README.md @@ -81,15 +81,15 @@ Android-ProgressFragment library is now pushed to Maven Central as a AAR, so you ProgressFragment: ``` xml dependencies { - compile 'com.github.johnkil.android-progressfragment:progressfragment:1.3.1' + compile 'com.github.johnkil.android-progressfragment:progressfragment:1.4.0' } ``` SherlockProgressFragment: ``` xml dependencies { - compile 'com.android.support:support-v4:18.0.0' - compile('com.github.johnkil.android-progressfragment:sherlockprogressfragment:1.3.1') { + compile 'com.android.support:support-v4:19.0.0' + compile('com.github.johnkil.android-progressfragment:sherlockprogressfragment:1.4.0') { exclude module: 'support-v4' } } diff --git a/build.gradle b/build.gradle index 1074676..d17d75f 100644 --- a/build.gradle +++ b/build.gradle @@ -21,4 +21,4 @@ allprojects { } } -// apply plugin: 'android-reporting' \ No newline at end of file +apply plugin: 'android-reporting' \ No newline at end of file diff --git a/gradle.properties b/gradle.properties index dec3a20..b763c7a 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,5 +1,5 @@ -VERSION_NAME=1.3.1-SNAPSHOT -VERSION_CODE=5 +VERSION_NAME=1.4.0-SNAPSHOT +VERSION_CODE=6 GROUP=com.github.johnkil.android-progressfragment POM_DESCRIPTION=Implementation of the fragment with the ability to display indeterminate progress indicator when you are waiting for the initial data diff --git a/progressfragment-sample/AndroidManifest.xml b/progressfragment-sample/AndroidManifest.xml index 5d4b568..6e72a8e 100644 --- a/progressfragment-sample/AndroidManifest.xml +++ b/progressfragment-sample/AndroidManifest.xml @@ -1,12 +1,12 @@ + android:versionCode="6" + android:versionName="1.4.0"> + android:targetSdkVersion="19"/> No Data Loading… + + + Apple Pie + Banana Bread + Cupcake + Donut + Eclair + Froyo + Gingerbread + Honeycomb + Ice Cream Sandwich + Jelly Bean + KitKat + \ No newline at end of file diff --git a/progressfragment-sample/src/com/devspark/progressfragment/sample/DefaultProgressGridFragment.java b/progressfragment-sample/src/com/devspark/progressfragment/sample/DefaultProgressGridFragment.java new file mode 100644 index 0000000..53000a2 --- /dev/null +++ b/progressfragment-sample/src/com/devspark/progressfragment/sample/DefaultProgressGridFragment.java @@ -0,0 +1,101 @@ +/* + * 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.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.ArrayAdapter; + +import com.devspark.progressfragment.ProgressGridFragment; + +/** + * Sample implementation of {@link com.devspark.progressfragment.ProgressGridFragment}. + * + * @author Evgeny Shishkin + */ +public class DefaultProgressGridFragment extends ProgressGridFragment { + private Handler mHandler; + private Runnable mShowContentRunnable = new Runnable() { + + @Override + public void run() { + setGridAdapter(new ArrayAdapter(getActivity(), + android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.sweets))); + setGridShown(true); + } + + }; + + public static DefaultProgressGridFragment newInstance() { + DefaultProgressGridFragment fragment = new DefaultProgressGridFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getGridView().setNumColumns(2); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + // 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 + setGridShown(false); + + mHandler = new Handler(); + mHandler.postDelayed(mShowContentRunnable, 3000); + } +} diff --git a/progressfragment-sample/src/com/devspark/progressfragment/sample/DefaultProgressListFragment.java b/progressfragment-sample/src/com/devspark/progressfragment/sample/DefaultProgressListFragment.java new file mode 100644 index 0000000..c44f698 --- /dev/null +++ b/progressfragment-sample/src/com/devspark/progressfragment/sample/DefaultProgressListFragment.java @@ -0,0 +1,94 @@ +/* + * 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.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.widget.ArrayAdapter; + +import com.devspark.progressfragment.ProgressListFragment; + +/** + * Sample implementation of {@link com.devspark.progressfragment.ProgressListFragment}. + * + * @author Evgeny Shishkin + */ +public class DefaultProgressListFragment extends ProgressListFragment { + private Handler mHandler; + private Runnable mShowContentRunnable = new Runnable() { + + @Override + public void run() { + setListAdapter(new ArrayAdapter(getActivity(), + android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.sweets))); + setListShown(true); + } + + }; + + public static DefaultProgressListFragment newInstance() { + DefaultProgressListFragment fragment = new DefaultProgressListFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + // 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 + setListShown(false); + + mHandler = new Handler(); + mHandler.postDelayed(mShowContentRunnable, 3000); + } +} diff --git a/progressfragment-sample/src/com/devspark/progressfragment/sample/MainActivity.java b/progressfragment-sample/src/com/devspark/progressfragment/sample/MainActivity.java index ab24b25..80fa7d1 100644 --- a/progressfragment-sample/src/com/devspark/progressfragment/sample/MainActivity.java +++ b/progressfragment-sample/src/com/devspark/progressfragment/sample/MainActivity.java @@ -28,7 +28,7 @@ */ public class MainActivity extends ListActivity { - private String[] examples = new String[]{"Default", "Empty content", "Custom layout"}; + private String[] examples = new String[]{"Default", "Empty content", "Custom layout", "List", "Grid"}; @Override protected void onCreate(Bundle savedInstanceState) { @@ -51,6 +51,12 @@ protected void onListItemClick(ListView l, View v, int position, long id) { case 2: intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_CUSTOM_LAYOUT); break; + case 3: + intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_LIST); + break; + case 4: + intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_GRID); + break; default: break; } diff --git a/progressfragment-sample/src/com/devspark/progressfragment/sample/ProgressActivity.java b/progressfragment-sample/src/com/devspark/progressfragment/sample/ProgressActivity.java index e7dcb67..05618d5 100644 --- a/progressfragment-sample/src/com/devspark/progressfragment/sample/ProgressActivity.java +++ b/progressfragment-sample/src/com/devspark/progressfragment/sample/ProgressActivity.java @@ -33,6 +33,8 @@ public class ProgressActivity extends FragmentActivity { public static final int FRAGMENT_DEFAULT = 0; public static final int FRAGMENT_EMPTY_CONTENT = 1; public static final int FRAGMENT_CUSTOM_LAYOUT = 2; + public static final int FRAGMENT_LIST = 3; + public static final int FRAGMENT_GRID = 4; @TargetApi(Build.VERSION_CODES.HONEYCOMB) @Override @@ -57,6 +59,12 @@ protected void onCreate(Bundle savedInstanceState) { case FRAGMENT_CUSTOM_LAYOUT: fragment = CustomLayoutProgressFragment.newInstance(); break; + case FRAGMENT_LIST: + fragment = DefaultProgressListFragment.newInstance(); + break; + case FRAGMENT_GRID: + fragment = DefaultProgressGridFragment.newInstance(); + break; default: fragment = DefaultProgressFragment.newInstance(); break; diff --git a/progressfragment/AndroidManifest.xml b/progressfragment/AndroidManifest.xml index 567ea53..417c5d1 100644 --- a/progressfragment/AndroidManifest.xml +++ b/progressfragment/AndroidManifest.xml @@ -1,12 +1,12 @@ + android:versionCode="6" + android:versionName="1.4.0"> + android:targetSdkVersion="19"/> diff --git a/progressfragment/build.gradle b/progressfragment/build.gradle index 6a39488..3a1b6c3 100644 --- a/progressfragment/build.gradle +++ b/progressfragment/build.gradle @@ -1,12 +1,17 @@ apply plugin: 'android-library' dependencies { - compile 'com.android.support:support-v4:18.0.0' + compile 'com.android.support:support-v4:19.0.0' } android { - compileSdkVersion 18 - buildToolsVersion '18.1.0' + compileSdkVersion 19 + buildToolsVersion '19.0.0' + + defaultConfig { + minSdkVersion 4 + targetSdkVersion 19 + } sourceSets { main { diff --git a/progressfragment/project.properties b/progressfragment/project.properties index 4a46b9d..61afc8f 100644 --- a/progressfragment/project.properties +++ b/progressfragment/project.properties @@ -12,4 +12,4 @@ android.library=true # Project target. -target=android-17 +target=android-19 diff --git a/progressfragment/res/layout/fragment_progress.xml b/progressfragment/res/layout/fragment_progress.xml index d6ab2d4..c647690 100644 --- a/progressfragment/res/layout/fragment_progress.xml +++ b/progressfragment/res/layout/fragment_progress.xml @@ -29,6 +29,7 @@ diff --git a/progressfragment/res/layout/fragment_grid.xml b/progressfragment/res/layout/fragment_progress_grid.xml similarity index 95% rename from progressfragment/res/layout/fragment_grid.xml rename to progressfragment/res/layout/fragment_progress_grid.xml index 150f989..f9e4615 100644 --- a/progressfragment/res/layout/fragment_grid.xml +++ b/progressfragment/res/layout/fragment_progress_grid.xml @@ -29,6 +29,7 @@ @@ -38,8 +39,8 @@ android:layout_height="wrap_content" android:paddingTop="4dip" android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceSmall" - android:visibility="gone"/> + android:visibility="gone" + android:textAppearance="?android:attr/textAppearanceSmall"/> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/progressfragment/src/com/devspark/progressfragment/ProgressFragment.java b/progressfragment/src/com/devspark/progressfragment/ProgressFragment.java index 5ab2f94..8c0ca9a 100644 --- a/progressfragment/src/com/devspark/progressfragment/ProgressFragment.java +++ b/progressfragment/src/com/devspark/progressfragment/ProgressFragment.java @@ -39,6 +39,9 @@ public class ProgressFragment extends Fragment { private boolean mContentShown; private boolean mIsContentEmpty; + public ProgressFragment() { + } + /** * Provide default implementation to return a simple view. Subclasses * can override to replace with their own layout. If doing so, the diff --git a/progressfragment/src/com/devspark/progressfragment/GridFragment.java b/progressfragment/src/com/devspark/progressfragment/ProgressGridFragment.java similarity index 92% rename from progressfragment/src/com/devspark/progressfragment/GridFragment.java rename to progressfragment/src/com/devspark/progressfragment/ProgressGridFragment.java index e0aeb22..0475bf4 100644 --- a/progressfragment/src/com/devspark/progressfragment/GridFragment.java +++ b/progressfragment/src/com/devspark/progressfragment/ProgressGridFragment.java @@ -32,9 +32,9 @@ * The implementation of the fragment to display grid view. 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 e.shishkin. + * @author Evgeny Shishkin */ -public class GridFragment extends Fragment { +public class ProgressGridFragment extends Fragment { final private Handler mHandler = new Handler(); final private Runnable mRequestFocus = new Runnable() { @@ -57,6 +57,9 @@ public void onItemClick(AdapterView parent, View v, int position, long id) { private CharSequence mEmptyText; private boolean mGridShown; + public ProgressGridFragment() { + } + /** * Provide default implementation to return a simple grid view. Subclasses * can override to replace with their own layout. If doing so, the @@ -66,14 +69,14 @@ public void onItemClick(AdapterView parent, View v, int position, long id) { * that is to be shown when the list is empty. *

*

If you are overriding this method with your own custom content, - * consider including the standard layout {@link com.devspark.progressfragment.R.layout#fragment_grid} + * consider including the standard layout {@link com.devspark.progressfragment.R.layout#fragment_progress_grid} * in your layout file, so that you continue to retain all of the standard - * behavior of SherlockGridFragment. In particular, this is currently the only + * behavior of ProgressGridFragment. 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_grid, container, false); + return inflater.inflate(R.layout.fragment_progress_grid, container, false); } /** @@ -148,9 +151,24 @@ public GridView getGridView() { } /** - * The default content for a SherlockGridFragment has a TextView that can + * The default content for a ProgressGridFragment has a TextView that can + * be shown when the grid is empty. 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 ProgressGridFragment has a TextView that can * be shown when the grid is empty. 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) { ensureList(); @@ -170,7 +188,7 @@ public void setEmptyText(CharSequence text) { * this time an indeterminant progress indicator will be shown instead. *

*

Applications do not normally need to use this themselves. The default - * behavior of SherlockGridFragment is to start with the grid not being shown, only + * behavior of ProgressGridFragment is to start with the grid not being shown, only * showing it once an adapter is given with {@link #setGridAdapter(android.widget.ListAdapter)}. * If the grid at that point had not been shown, when it does get shown * it will be do without the user ever seeing the hidden state. diff --git a/progressfragment/src/com/devspark/progressfragment/ProgressListFragment.java b/progressfragment/src/com/devspark/progressfragment/ProgressListFragment.java new file mode 100644 index 0000000..e4c2087 --- /dev/null +++ b/progressfragment/src/com/devspark/progressfragment/ProgressListFragment.java @@ -0,0 +1,338 @@ +/* + * 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.os.Handler; +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.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.TextView; + +/** + * The implementation of the fragment to display list view. 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 ProgressListFragment extends Fragment { + + final private Handler mHandler = new Handler(); + final private Runnable mRequestFocus = new Runnable() { + public void run() { + mListView.focusableViewAvailable(mListView); + } + }; + final private AdapterView.OnItemClickListener mOnClickListener + = new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + onListItemClick((ListView) parent, v, position, id); + } + }; + private ListAdapter mAdapter; + private ListView mListView; + private View mEmptyView; + private TextView mStandardEmptyView; + private View mProgressContainer; + private View mListContainer; + private CharSequence mEmptyText; + private boolean mListShown; + + public ProgressListFragment() { + } + + /** + * Provide default implementation to return a simple list view. Subclasses + * can override to replace with their own layout. If doing so, the + * returned view hierarchy must have a ListView whose id + * is {@link android.R.id#list android.R.id.list} and can optionally + * have a sibling view id {@link android.R.id#empty android.R.id.empty} + * that is to be shown when the list is empty. + *

+ *

If you are overriding this method with your own custom content, + * consider including the standard layout {@link com.devspark.progressfragment.R.layout#fragment_progress_list} + * in your layout file, so that you continue to retain all of the standard + * behavior of ListFragment. 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_list, container, false); + } + + /** + * Attach to list view once the view hierarchy has been created. + */ + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + ensureList(); + } + + /** + * Detach from list view. + */ + @Override + public void onDestroyView() { + mHandler.removeCallbacks(mRequestFocus); + mListView = null; + mListShown = false; + mEmptyView = mProgressContainer = mListContainer = null; + mStandardEmptyView = null; + super.onDestroyView(); + } + + /** + * This method will be called when an item in the list is selected. + * Subclasses should override. Subclasses can call + * getListView().getItemAtPosition(position) if they need to access the + * data associated with the selected item. + * + * @param l The ListView where the click happened + * @param v The view that was clicked within the ListView + * @param position The position of the view in the list + * @param id The row id of the item that was clicked + */ + public void onListItemClick(ListView l, View v, int position, long id) { + } + + /** + * Set the currently selected list item to the specified + * position with the adapter's data + * + * @param position + */ + public void setSelection(int position) { + ensureList(); + mListView.setSelection(position); + } + + /** + * Get the position of the currently selected list item. + */ + public int getSelectedItemPosition() { + ensureList(); + return mListView.getSelectedItemPosition(); + } + + /** + * Get the cursor row ID of the currently selected list item. + */ + public long getSelectedItemId() { + ensureList(); + return mListView.getSelectedItemId(); + } + + /** + * Get the activity's list view widget. + */ + public ListView getListView() { + ensureList(); + return mListView; + } + + /** + * The default content for a ProgressListFragment has a TextView that can + * be shown when the list is empty. 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 ProgressListFragment has a TextView that can + * be shown when the list is empty. 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) { + ensureList(); + if (mStandardEmptyView == null) { + throw new IllegalStateException("Can't be used with a custom content view"); + } + mStandardEmptyView.setText(text); + if (mEmptyText == null) { + mListView.setEmptyView(mStandardEmptyView); + } + mEmptyText = text; + } + + /** + * Control whether the list 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. + *

+ *

Applications do not normally need to use this themselves. The default + * behavior of ProgressListFragment is to start with the list not being shown, only + * showing it once an adapter is given with {@link #setListAdapter(ListAdapter)}. + * If the list at that point had not been shown, when it does get shown + * it will be do without the user ever seeing the hidden state. + * + * @param shown If true, the list view is shown; if false, the progress + * indicator. The initial value is true. + */ + public void setListShown(boolean shown) { + setListShown(shown, true); + } + + /** + * Like {@link #setListShown(boolean)}, but no animation is used when + * transitioning from the previous state. + */ + public void setListShownNoAnimation(boolean shown) { + setListShown(shown, false); + } + + /** + * Control whether the list 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 list 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 setListShown(boolean shown, boolean animate) { + ensureList(); + if (mProgressContainer == null) { + throw new IllegalStateException("Can't be used with a custom content view"); + } + if (mListShown == shown) { + return; + } + mListShown = shown; + if (shown) { + if (animate) { + mProgressContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_out)); + mListContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_in)); + } else { + mProgressContainer.clearAnimation(); + mListContainer.clearAnimation(); + } + mProgressContainer.setVisibility(View.GONE); + mListContainer.setVisibility(View.VISIBLE); + } else { + if (animate) { + mProgressContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_in)); + mListContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_out)); + } else { + mProgressContainer.clearAnimation(); + mListContainer.clearAnimation(); + } + mProgressContainer.setVisibility(View.VISIBLE); + mListContainer.setVisibility(View.GONE); + } + } + + /** + * Get the ListAdapter associated with this activity's ListView. + */ + public ListAdapter getListAdapter() { + return mAdapter; + } + + /** + * Provide the cursor for the list view. + */ + public void setListAdapter(ListAdapter adapter) { + boolean hadAdapter = mAdapter != null; + mAdapter = adapter; + if (mListView != null) { + mListView.setAdapter(adapter); + if (!mListShown && !hadAdapter) { + // The list was hidden, and previously didn't have an + // adapter. It is now time to show it. + setListShown(true, getView().getWindowToken() != null); + } + } + } + + private void ensureList() { + if (mListView != null) { + return; + } + View root = getView(); + if (root == null) { + throw new IllegalStateException("Content view not yet created"); + } + if (root instanceof ListView) { + mListView = (ListView)root; + } else { + View emptyView = root.findViewById(android.R.id.empty); + if (emptyView != null) { + if (emptyView instanceof TextView) { + mStandardEmptyView = (TextView) emptyView; + } else { + mEmptyView = emptyView; + } + } else { + mStandardEmptyView.setVisibility(View.GONE); + } + mProgressContainer = root.findViewById(R.id.progress_container); + mListContainer = root.findViewById(R.id.list_container); + View rawListView = root.findViewById(android.R.id.list); + if (!(rawListView instanceof ListView)) { + throw new RuntimeException( + "Content has view with id attribute 'android.R.id.list' " + + "that is not a ListView class"); + } + mListView = (ListView)rawListView; + if (mListView == null) { + throw new RuntimeException( + "Your content must have a ListView whose id attribute is " + + "'android.R.id.list'"); + } + if (mEmptyView != null) { + mListView.setEmptyView(mEmptyView); + } else if (mEmptyText != null) { + mStandardEmptyView.setText(mEmptyText); + mListView.setEmptyView(mStandardEmptyView); + } + } + mListShown = true; + mListView.setOnItemClickListener(mOnClickListener); + if (mAdapter != null) { + ListAdapter adapter = mAdapter; + mAdapter = null; + setListAdapter(adapter); + } else { + // We are starting without an adapter, so assume we won't + // have our data right away and start with the progress indicator. + if (mProgressContainer != null) { + setListShown(false, false); + } + } + mHandler.post(mRequestFocus); + } + +} diff --git a/sherlockprogressfragment-sample/AndroidManifest.xml b/sherlockprogressfragment-sample/AndroidManifest.xml index afd7962..89d1ee2 100644 --- a/sherlockprogressfragment-sample/AndroidManifest.xml +++ b/sherlockprogressfragment-sample/AndroidManifest.xml @@ -1,12 +1,12 @@ + android:versionCode="6" + android:versionName="1.4.0"> + android:targetSdkVersion="19"/> No Data Loading… + + Apple Pie + Banana Bread + Cupcake + Donut + Eclair + Froyo + Gingerbread + Honeycomb + Ice Cream Sandwich + Jelly Bean + KitKat + + \ No newline at end of file diff --git a/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/DefaultProgressGridFragment.java b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/DefaultProgressGridFragment.java new file mode 100644 index 0000000..33216d9 --- /dev/null +++ b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/DefaultProgressGridFragment.java @@ -0,0 +1,103 @@ +/* + * 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.sherlock; + +import android.os.Bundle; +import android.os.Handler; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.ArrayAdapter; + +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; +import com.devspark.progressfragment.SherlockProgressGridFragment; + +/** + * Sample implementation of {@link com.devspark.progressfragment.SherlockProgressGridFragment}. + * + * @author Evgeny Shishkin + */ +public class DefaultProgressGridFragment extends SherlockProgressGridFragment { + private Handler mHandler; + private Runnable mShowContentRunnable = new Runnable() { + + @Override + public void run() { + setGridAdapter(new ArrayAdapter(getActivity(), + android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.sweets))); + setGridShown(true); + } + + }; + + public static DefaultProgressGridFragment newInstance() { + DefaultProgressGridFragment fragment = new DefaultProgressGridFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + getGridView().setNumColumns(2); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + // 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 + setGridShown(false); + + mHandler = new Handler(); + mHandler.postDelayed(mShowContentRunnable, 3000); + } +} diff --git a/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/DefaultProgressListFragment.java b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/DefaultProgressListFragment.java new file mode 100644 index 0000000..b31a122 --- /dev/null +++ b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/DefaultProgressListFragment.java @@ -0,0 +1,95 @@ +/* + * 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.sherlock; + +import android.os.Bundle; +import android.os.Handler; +import android.view.View; +import android.widget.ArrayAdapter; + +import com.actionbarsherlock.view.Menu; +import com.actionbarsherlock.view.MenuInflater; +import com.actionbarsherlock.view.MenuItem; +import com.devspark.progressfragment.SherlockProgressListFragment; + +/** + * Sample implementation of {@link com.devspark.progressfragment.SherlockProgressListFragment}. + * + * @author Evgeny Shishkin + */ +public class DefaultProgressListFragment extends SherlockProgressListFragment { + private Handler mHandler; + private Runnable mShowContentRunnable = new Runnable() { + + @Override + public void run() { + setListAdapter(new ArrayAdapter(getActivity(), + android.R.layout.simple_list_item_1, getResources().getStringArray(R.array.sweets))); + setListShown(true); + } + + }; + + public static DefaultProgressListFragment newInstance() { + DefaultProgressListFragment fragment = new DefaultProgressListFragment(); + return fragment; + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setHasOptionsMenu(true); + } + + @Override + public void onActivityCreated(Bundle savedInstanceState) { + super.onActivityCreated(savedInstanceState); + // 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 + setListShown(false); + + mHandler = new Handler(); + mHandler.postDelayed(mShowContentRunnable, 3000); + } +} diff --git a/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/MainActivity.java b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/MainActivity.java index 215dec8..ff048a0 100644 --- a/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/MainActivity.java +++ b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/MainActivity.java @@ -29,7 +29,7 @@ */ public class MainActivity extends SherlockListActivity { - private String[] examples = new String[]{"Default", "Empty content", "Custom layout"}; + private String[] examples = new String[]{"Default", "Empty content", "Custom layout", "List", "Grid"}; @Override protected void onCreate(Bundle savedInstanceState) { @@ -52,6 +52,12 @@ protected void onListItemClick(ListView l, View v, int position, long id) { case 2: intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_CUSTOM_LAYOUT); break; + case 3: + intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_LIST); + break; + case 4: + intent.putExtra(ProgressActivity.EXTRA_FRAGMENT, ProgressActivity.FRAGMENT_GRID); + break; default: break; } diff --git a/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/ProgressActivity.java b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/ProgressActivity.java index 1e097e1..2c0541c 100644 --- a/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/ProgressActivity.java +++ b/sherlockprogressfragment-sample/src/com/devspark/progressfragment/sample/sherlock/ProgressActivity.java @@ -31,6 +31,8 @@ public class ProgressActivity extends SherlockFragmentActivity { public static final int FRAGMENT_DEFAULT = 0; public static final int FRAGMENT_EMPTY_CONTENT = 1; public static final int FRAGMENT_CUSTOM_LAYOUT = 2; + public static final int FRAGMENT_LIST = 3; + public static final int FRAGMENT_GRID = 4; @Override protected void onCreate(Bundle savedInstanceState) { @@ -52,6 +54,12 @@ protected void onCreate(Bundle savedInstanceState) { case FRAGMENT_CUSTOM_LAYOUT: fragment = CustomLayoutProgressFragment.newInstance(); break; + case FRAGMENT_LIST: + fragment = DefaultProgressListFragment.newInstance(); + break; + case FRAGMENT_GRID: + fragment = DefaultProgressGridFragment.newInstance(); + break; default: fragment = DefaultProgressFragment.newInstance(); break; diff --git a/sherlockprogressfragment/AndroidManifest.xml b/sherlockprogressfragment/AndroidManifest.xml index b62ebdc..3c947f2 100644 --- a/sherlockprogressfragment/AndroidManifest.xml +++ b/sherlockprogressfragment/AndroidManifest.xml @@ -1,12 +1,12 @@ + android:versionCode="6" + android:versionName="1.4.0"> + android:targetSdkVersion="19"/> diff --git a/sherlockprogressfragment/build.gradle b/sherlockprogressfragment/build.gradle index 2c6bae3..b5409b6 100644 --- a/sherlockprogressfragment/build.gradle +++ b/sherlockprogressfragment/build.gradle @@ -1,13 +1,18 @@ apply plugin: 'android-library' dependencies { - compile 'com.android.support:support-v4:18.0.0' + compile 'com.android.support:support-v4:19.0.0' compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar' } android { - compileSdkVersion 18 - buildToolsVersion '18.1.0' + compileSdkVersion 19 + buildToolsVersion '19.0.0' + + defaultConfig { + minSdkVersion 7 + targetSdkVersion 19 + } sourceSets { main { diff --git a/sherlockprogressfragment/project.properties b/sherlockprogressfragment/project.properties index 4a46b9d..61afc8f 100644 --- a/sherlockprogressfragment/project.properties +++ b/sherlockprogressfragment/project.properties @@ -12,4 +12,4 @@ android.library=true # Project target. -target=android-17 +target=android-19 diff --git a/sherlockprogressfragment/res/layout/fragment_progress.xml b/sherlockprogressfragment/res/layout/fragment_progress.xml index d6ab2d4..c647690 100644 --- a/sherlockprogressfragment/res/layout/fragment_progress.xml +++ b/sherlockprogressfragment/res/layout/fragment_progress.xml @@ -29,6 +29,7 @@ diff --git a/sherlockprogressfragment/res/layout/fragment_grid.xml b/sherlockprogressfragment/res/layout/fragment_progress_grid.xml similarity index 95% rename from sherlockprogressfragment/res/layout/fragment_grid.xml rename to sherlockprogressfragment/res/layout/fragment_progress_grid.xml index 150f989..f9e4615 100644 --- a/sherlockprogressfragment/res/layout/fragment_grid.xml +++ b/sherlockprogressfragment/res/layout/fragment_progress_grid.xml @@ -29,6 +29,7 @@ @@ -38,8 +39,8 @@ android:layout_height="wrap_content" android:paddingTop="4dip" android:singleLine="true" - android:textAppearance="?android:attr/textAppearanceSmall" - android:visibility="gone"/> + android:visibility="gone" + android:textAppearance="?android:attr/textAppearanceSmall"/> + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressFragment.java b/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressFragment.java index d19dbc8..10a9fb1 100644 --- a/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressFragment.java +++ b/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressFragment.java @@ -40,6 +40,9 @@ public class SherlockProgressFragment extends SherlockFragment { private boolean mContentShown; private boolean mIsContentEmpty; + public SherlockProgressFragment() { + } + /** * Provide default implementation to return a simple view. Subclasses * can override to replace with their own layout. If doing so, the @@ -52,7 +55,7 @@ public class SherlockProgressFragment extends SherlockFragment { *

If you are overriding this method with your own custom content, * consider including the standard layout {@link com.devspark.progressfragment.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 + * behavior of SherlockProgressFragment. In particular, this is currently the only * way to have the built-in indeterminant progress state be shown. */ @Override @@ -134,7 +137,7 @@ public void setContentView(View view) { } /** - * The default content for a ProgressFragment has a TextView that can be shown when + * The default content for a SherlockProgressFragment 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. * @@ -146,7 +149,7 @@ public void setEmptyText(int resId) { } /** - * The default content for a ProgressFragment has a TextView that can be shown when + * The default content for a SherlockProgressFragment 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. * diff --git a/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockGridFragment.java b/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressGridFragment.java similarity index 91% rename from sherlockprogressfragment/src/com/devspark/progressfragment/SherlockGridFragment.java rename to sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressGridFragment.java index fdba4c7..9529191 100644 --- a/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockGridFragment.java +++ b/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressGridFragment.java @@ -33,9 +33,9 @@ * The implementation of the fragment to display grid view. 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 e.shishkin. + * @author Evgeny Shishkin */ -public class SherlockGridFragment extends SherlockFragment { +public class SherlockProgressGridFragment extends SherlockFragment { final private Handler mHandler = new Handler(); final private Runnable mRequestFocus = new Runnable() { @@ -58,6 +58,9 @@ public void onItemClick(AdapterView parent, View v, int position, long id) { private CharSequence mEmptyText; private boolean mGridShown; + public SherlockProgressGridFragment() { + } + /** * Provide default implementation to return a simple grid view. Subclasses * can override to replace with their own layout. If doing so, the @@ -67,14 +70,14 @@ public void onItemClick(AdapterView parent, View v, int position, long id) { * that is to be shown when the list is empty. *

*

If you are overriding this method with your own custom content, - * consider including the standard layout {@link com.devspark.progressfragment.R.layout#fragment_grid} + * consider including the standard layout {@link com.devspark.progressfragment.R.layout#fragment_progress_grid} * in your layout file, so that you continue to retain all of the standard - * behavior of SherlockGridFragment. In particular, this is currently the only + * behavior of SherlockProgressGridFragment. 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_grid, container, false); + return inflater.inflate(R.layout.fragment_progress_grid, container, false); } /** @@ -149,9 +152,24 @@ public GridView getGridView() { } /** - * The default content for a SherlockGridFragment has a TextView that can + * The default content for a SherlockProgressGridFragment has a TextView that can + * be shown when the grid is empty. 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 SherlockProgressGridFragment has a TextView that can * be shown when the grid is empty. 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) { ensureList(); @@ -171,7 +189,7 @@ public void setEmptyText(CharSequence text) { * this time an indeterminant progress indicator will be shown instead. *

*

Applications do not normally need to use this themselves. The default - * behavior of SherlockGridFragment is to start with the grid not being shown, only + * behavior of SherlockProgressGridFragment is to start with the grid not being shown, only * showing it once an adapter is given with {@link #setGridAdapter(android.widget.ListAdapter)}. * If the grid at that point had not been shown, when it does get shown * it will be do without the user ever seeing the hidden state. diff --git a/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressListFragment.java b/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressListFragment.java new file mode 100644 index 0000000..d4cc95a --- /dev/null +++ b/sherlockprogressfragment/src/com/devspark/progressfragment/SherlockProgressListFragment.java @@ -0,0 +1,340 @@ +/* + * 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.os.Handler; +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.AdapterView; +import android.widget.ListAdapter; +import android.widget.ListView; +import android.widget.TextView; + +import com.actionbarsherlock.app.SherlockFragment; + +/** + * The implementation of the fragment to display list view. 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 SherlockProgressListFragment extends SherlockFragment { + + final private Handler mHandler = new Handler(); + final private Runnable mRequestFocus = new Runnable() { + public void run() { + mListView.focusableViewAvailable(mListView); + } + }; + final private AdapterView.OnItemClickListener mOnClickListener + = new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + onListItemClick((ListView) parent, v, position, id); + } + }; + private ListAdapter mAdapter; + private ListView mListView; + private View mEmptyView; + private TextView mStandardEmptyView; + private View mProgressContainer; + private View mListContainer; + private CharSequence mEmptyText; + private boolean mListShown; + + public SherlockProgressListFragment() { + } + + /** + * Provide default implementation to return a simple list view. Subclasses + * can override to replace with their own layout. If doing so, the + * returned view hierarchy must have a ListView whose id + * is {@link android.R.id#list android.R.id.list} and can optionally + * have a sibling view id {@link android.R.id#empty android.R.id.empty} + * that is to be shown when the list is empty. + *

+ *

If you are overriding this method with your own custom content, + * consider including the standard layout {@link com.devspark.progressfragment.R.layout#fragment_progress_list} + * in your layout file, so that you continue to retain all of the standard + * behavior of ListFragment. 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_list, container, false); + } + + /** + * Attach to list view once the view hierarchy has been created. + */ + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + ensureList(); + } + + /** + * Detach from list view. + */ + @Override + public void onDestroyView() { + mHandler.removeCallbacks(mRequestFocus); + mListView = null; + mListShown = false; + mEmptyView = mProgressContainer = mListContainer = null; + mStandardEmptyView = null; + super.onDestroyView(); + } + + /** + * This method will be called when an item in the list is selected. + * Subclasses should override. Subclasses can call + * getListView().getItemAtPosition(position) if they need to access the + * data associated with the selected item. + * + * @param l The ListView where the click happened + * @param v The view that was clicked within the ListView + * @param position The position of the view in the list + * @param id The row id of the item that was clicked + */ + public void onListItemClick(ListView l, View v, int position, long id) { + } + + /** + * Set the currently selected list item to the specified + * position with the adapter's data + * + * @param position + */ + public void setSelection(int position) { + ensureList(); + mListView.setSelection(position); + } + + /** + * Get the position of the currently selected list item. + */ + public int getSelectedItemPosition() { + ensureList(); + return mListView.getSelectedItemPosition(); + } + + /** + * Get the cursor row ID of the currently selected list item. + */ + public long getSelectedItemId() { + ensureList(); + return mListView.getSelectedItemId(); + } + + /** + * Get the activity's list view widget. + */ + public ListView getListView() { + ensureList(); + return mListView; + } + + /** + * The default content for a SherlockProgressListFragment has a TextView that can + * be shown when the list is empty. 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 SherlockProgressListFragment has a TextView that can + * be shown when the list is empty. 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) { + ensureList(); + if (mStandardEmptyView == null) { + throw new IllegalStateException("Can't be used with a custom content view"); + } + mStandardEmptyView.setText(text); + if (mEmptyText == null) { + mListView.setEmptyView(mStandardEmptyView); + } + mEmptyText = text; + } + + /** + * Control whether the list 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. + *

+ *

Applications do not normally need to use this themselves. The default + * behavior of SherlockProgressListFragment is to start with the list not being shown, only + * showing it once an adapter is given with {@link #setListAdapter(android.widget.ListAdapter)}. + * If the list at that point had not been shown, when it does get shown + * it will be do without the user ever seeing the hidden state. + * + * @param shown If true, the list view is shown; if false, the progress + * indicator. The initial value is true. + */ + public void setListShown(boolean shown) { + setListShown(shown, true); + } + + /** + * Like {@link #setListShown(boolean)}, but no animation is used when + * transitioning from the previous state. + */ + public void setListShownNoAnimation(boolean shown) { + setListShown(shown, false); + } + + /** + * Control whether the list 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 list 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 setListShown(boolean shown, boolean animate) { + ensureList(); + if (mProgressContainer == null) { + throw new IllegalStateException("Can't be used with a custom content view"); + } + if (mListShown == shown) { + return; + } + mListShown = shown; + if (shown) { + if (animate) { + mProgressContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_out)); + mListContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_in)); + } else { + mProgressContainer.clearAnimation(); + mListContainer.clearAnimation(); + } + mProgressContainer.setVisibility(View.GONE); + mListContainer.setVisibility(View.VISIBLE); + } else { + if (animate) { + mProgressContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_in)); + mListContainer.startAnimation(AnimationUtils.loadAnimation( + getActivity(), android.R.anim.fade_out)); + } else { + mProgressContainer.clearAnimation(); + mListContainer.clearAnimation(); + } + mProgressContainer.setVisibility(View.VISIBLE); + mListContainer.setVisibility(View.GONE); + } + } + + /** + * Get the ListAdapter associated with this activity's ListView. + */ + public ListAdapter getListAdapter() { + return mAdapter; + } + + /** + * Provide the cursor for the list view. + */ + public void setListAdapter(ListAdapter adapter) { + boolean hadAdapter = mAdapter != null; + mAdapter = adapter; + if (mListView != null) { + mListView.setAdapter(adapter); + if (!mListShown && !hadAdapter) { + // The list was hidden, and previously didn't have an + // adapter. It is now time to show it. + setListShown(true, getView().getWindowToken() != null); + } + } + } + + private void ensureList() { + if (mListView != null) { + return; + } + View root = getView(); + if (root == null) { + throw new IllegalStateException("Content view not yet created"); + } + if (root instanceof ListView) { + mListView = (ListView)root; + } else { + View emptyView = root.findViewById(android.R.id.empty); + if (emptyView != null) { + if (emptyView instanceof TextView) { + mStandardEmptyView = (TextView) emptyView; + } else { + mEmptyView = emptyView; + } + } else { + mStandardEmptyView.setVisibility(View.GONE); + } + mProgressContainer = root.findViewById(R.id.progress_container); + mListContainer = root.findViewById(R.id.list_container); + View rawListView = root.findViewById(android.R.id.list); + if (!(rawListView instanceof ListView)) { + throw new RuntimeException( + "Content has view with id attribute 'android.R.id.list' " + + "that is not a ListView class"); + } + mListView = (ListView)rawListView; + if (mListView == null) { + throw new RuntimeException( + "Your content must have a ListView whose id attribute is " + + "'android.R.id.list'"); + } + if (mEmptyView != null) { + mListView.setEmptyView(mEmptyView); + } else if (mEmptyText != null) { + mStandardEmptyView.setText(mEmptyText); + mListView.setEmptyView(mStandardEmptyView); + } + } + mListShown = true; + mListView.setOnItemClickListener(mOnClickListener); + if (mAdapter != null) { + ListAdapter adapter = mAdapter; + mAdapter = null; + setListAdapter(adapter); + } else { + // We are starting without an adapter, so assume we won't + // have our data right away and start with the progress indicator. + if (mProgressContainer != null) { + setListShown(false, false); + } + } + mHandler.post(mRequestFocus); + } + +}