Back to project page GuildViewerApp2.
The source code is released under:
Apache License
If you think the Android project GuildViewerApp2 listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.
package com.skywomantechnology.app.guildviewer; /* www . j a va 2s . c om*/ /* * Guild Viewer is an Android app that allows users to view news feeds and news feed details * on a mobile device and while not logged into the game servers. * * Copyright 2014 Sky Woman Technology LLC * * 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. */ import android.app.Activity; import android.app.ListFragment; import android.app.LoaderManager; import android.content.CursorLoader; import android.content.Loader; import android.database.Cursor; import android.os.Bundle; //import android.util.Log; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.widget.ListView; import com.skywomantechnology.app.guildviewer.data.GuildViewerContract.NewsEntry; import com.skywomantechnology.app.guildviewer.sync.GuildViewerSyncAdapter; /** * A list fragment representing a list of News. 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 NewsDetailFragment}. * <p/> * Activities containing this fragment MUST implement the {@link Callbacks} interface. */ public class NewsListFragment extends ListFragment implements LoaderManager.LoaderCallbacks<Cursor> { // logging identifier is the class name //public final String LOG_TAG = NewsListFragment.class.getSimpleName(); private NewsAdapter mNewsAdapter; // key for storing the currently selected news item to be used in detail fragment public static final String NEWS_ID_KEY = "news_id"; // key for storing the currently selected position in the list to retain list state private static final String STATE_ACTIVATED_POSITION = "activated_position"; // actual list item selected in the list private int mActivatedPosition = ListView.INVALID_POSITION; // cursor loader identifier private static final int NEWS_LIST_LOADER = 0; // For the news list view we're showing only a small subset of the stored data. // Specify the columns we need. private static final String[] NEWS_LIST_COLUMNS = { NewsEntry.TABLE_NAME + "." + NewsEntry._ID, NewsEntry.COLUMN_TYPE, NewsEntry.COLUMN_TIMESTAMP, NewsEntry.COLUMN_CHARACTER, NewsEntry.COLUMN_ITEM_NAME, NewsEntry.COLUMN_ACHIEVEMENT_TITLE }; // These indices are tied to NEWS_LIST_COLUMNS. public static final int COL_NEWS_ID = 0; public static final int COL_TYPE = 1; public static final int COL_TIMESTAMP = 2; public static final int COL_CHARACTER = 3; public static final int COL_ITEM_NAME = 4; public static final int COL_ACHIEVEMENT_TITLE = 5; private Callbacks mCallbacks = sNewsListCallbacks; // dummy callbacks /** * Callback for any activity using this fragment to implement so that the when a list item is * selected it is correctly processed on UI */ public interface Callbacks { public void onNewsListItemSelected(long id); public void onNoDataForGuild(); public void onDataRefresh(); } /** * dummy callback */ private static Callbacks sNewsListCallbacks = new Callbacks() { @Override public void onNewsListItemSelected(long id) { } public void onNoDataForGuild() { } public void onDataRefresh() { } }; /** * constructor */ public NewsListFragment() { } /** * When this fragment is created lets it know that there is an options menu * create the news list adapter * * @param savedInstanceState * Bundle with saved information to be used on creating a new fragment */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); //create & set cursor adapter for the news list items mNewsAdapter = new NewsAdapter(getActivity(), null, 0); setListAdapter(mNewsAdapter); } /** * Setup the options menu for this fragment * * @param menu Options Menu to be inflated * @param inflater Inflater to generate menu from xml */ @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { inflater.inflate(R.menu.newslistfragment, menu); } /** * Process the options item selection Refresh - sends out a refresh message and syncs the data * * @param item MenuItem selected * @return true if processed OK */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // if you get tired of waiting for a refresh // or just need to refresh for testing purposes case R.id.action_refresh: // sync immediately ((Callbacks) getActivity()).onDataRefresh(); GuildViewerSyncAdapter.syncImmediately(getActivity()); return true; default: return super.onOptionsItemSelected(item); } } /** * Starts the set up for the cursor loader * * @param savedInstanceState Bundle with saved information to be used on creating a new fragment */ @Override public void onActivityCreated(Bundle savedInstanceState) { getLoaderManager().initLoader(NEWS_LIST_LOADER, null, this); super.onActivityCreated(savedInstanceState); setEmptyText(getString(R.string.type_loading_data)); } /** * Creates a cursor loader to obtain data from the content provider This cursor loader will get * ALL of the news list items from the content provider in descending order. Since it only * stores data for one guild at a time right now it doesn't matter but in the future this could * be modified to get only the data for the prefered guild, realm and region. * * @param id loader identifier * @param args Bundle of data * @return Cursor Loader */ @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { String sortOrder = NewsEntry.COLUMN_TIMESTAMP + " DESC"; return new CursorLoader( getActivity(), NewsEntry.buildNewsListUri(), NEWS_LIST_COLUMNS, null, null, sortOrder ); } /** * We loaded all the data from the content provider. * * @param loader cursor loader * @param data data loaded */ @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { // if it didn't find any guild news let the activity know so they can warn the user setEmptyText(getString(R.string.type_loading_data)); if (data.getCount() == 0) { setActivatedPosition(ListView.INVALID_POSITION); setEmptyText(getString(R.string.type_no_data)); ((Callbacks) getActivity()).onNoDataForGuild(); } // some guilds will have zero data so only try to sync if the notification timestamp // is defaulted to zero otherwise we can get in a big loop here until data shows up if (data.getCount() == 0 && Utility.getPreferenceForLastNotificationDate(getActivity()) == 0L) { GuildViewerSyncAdapter.syncImmediately(getActivity()); } // put the newly loaded data into the adapter mNewsAdapter.swapCursor(data); // scroll to the current position in the list if (mActivatedPosition != ListView.INVALID_POSITION) { getListView().smoothScrollToPosition(mActivatedPosition); } } /** * Clear out the data cursor if the loader is reset * * @param loader Cursor loader being reset */ @Override public void onLoaderReset(Loader<Cursor> loader) { mNewsAdapter.swapCursor(null); } /** * Resets the activated position when the fragment view is created * and sets up the text to display if there is no data in the list * * @param view View being processed * @param savedInstanceState Bundle with saved information to be used on creating a new View */ @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // Tell the listview what to say if there is no guild news data setEmptyText(getString(R.string.type_loading_data)); // handle the activated position in the list // use the one in the bundle unless this is a brand new instance // and then use the one that was saved in the preferences if (savedInstanceState != null && savedInstanceState.containsKey(STATE_ACTIVATED_POSITION)) { setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); } } /** * Ensure that the activity calling this fragment implements the required callbacks to handle * the item list processing * * @param activity Activity that is attaching this fragment */ @Override public void onAttach(Activity activity) { super.onAttach(activity); if (!(activity instanceof Callbacks)) { throw new IllegalStateException("Activity must implement fragment's callbacks."); } mCallbacks = (Callbacks) activity; } /** * setup the dummy callbacks on detach */ @Override public void onDetach() { super.onDetach(); mCallbacks = sNewsListCallbacks; } /** * Match the data cursor to the selected item in the listview, then process the news item * selected in the calling activity. * * @param listView ListView being processed * @param view View being processed * @param position new position for the list item selected * @param id id of the item selected */ @Override public void onListItemClick(ListView listView, View view, int position, long id) { Cursor cursor = mNewsAdapter.getCursor(); if (cursor != null && cursor.moveToPosition(position)) { ((Callbacks) getActivity()).onNewsListItemSelected(cursor.getLong(COL_NEWS_ID)); } setActivatedPosition(position); } /** * Save the currently store list position so it can be reactivated later * * @param outState Bundle to hold the save data */ @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mActivatedPosition != ListView.INVALID_POSITION) { outState.putInt(STATE_ACTIVATED_POSITION, mActivatedPosition); } } /** * Setup so that we can change the background of the listview when selected * * @param activateOnItemClick true for CHOICE_MODE_SINGLE else CHOICE_MODE_NONE */ public void setActivateOnItemClick(boolean activateOnItemClick) { getListView().setChoiceMode(activateOnItemClick ? ListView.CHOICE_MODE_SINGLE : ListView.CHOICE_MODE_NONE); } /** * Update the selected item background activation * * @param position new position for the list viewer to activate */ private void setActivatedPosition(int position) { // only process if the listview has been created if (getListView() == null) return; mActivatedPosition = position; if (position == ListView.INVALID_POSITION) { getListView().setItemChecked(mActivatedPosition, false); } else { getListView().setItemChecked(position, true); } } }