Java tutorial
// Copyright (c) 2014-2015 Akop Karapetyan // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in all // copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. package org.akop.crosswords.fragment; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.AsyncTask; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v4.app.LoaderManager; import android.support.v4.content.Loader; import android.support.v4.content.LocalBroadcastManager; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.CursorAdapter; import android.widget.ListView; import android.widget.TextView; import org.akop.crosswords.R; import org.akop.crosswords.Storage; import org.akop.crosswords.activity.CrosswordActivity; import org.akop.crosswords.utility.SimpleCursorLoader; import org.akop.xross.object.Crossword; public class FoldersFragment extends BaseFragment { public static Bundle createArgs(long folderId) { Bundle bundle = new Bundle(); bundle.putLong(ARG_FOLDER_ID, folderId); return bundle; } public interface OnFolderSelectedListener { void onFolderSelected(long id, String title); } private static final int INDEX_FOLDER_ID = 0; private static final int INDEX_FOLDER_TITLE = 1; private static final int INDEX_FOLDER_COUNT = 2; private static final String ARG_FOLDER_ID = "folderId"; private static final String sQuery = "SELECT " + "f." + Storage.Folder._ID + "," + "f." + Storage.Folder.TITLE + "," + "COUNT(p." + Storage.Puzzle._ID + ") " + "FROM " + Storage.Folder.TABLE + " f " + "LEFT JOIN " + Storage.Puzzle.TABLE + " p " + "ON p." + Storage.Puzzle.FOLDER_ID + "= f." + Storage.Folder._ID + " " + "GROUP BY f." + Storage.Folder._ID + "," + "f." + Storage.Folder.TITLE + " " + "ORDER BY f." + Storage.Folder._ID; private FolderAdapter mAdapter; private ListView mListView; private int mSelectedPos; private LoaderManager.LoaderCallbacks<Cursor> mLoaderCallbacks = new LoaderManager.LoaderCallbacks<Cursor>() { @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { return new FolderLoader(getActivity()); } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { mAdapter.swapCursor(data); if (mListView != null) { mListView.setItemChecked(mSelectedPos, true); notifySelectionChange(); } } @Override public void onLoaderReset(Loader<Cursor> loader) { mAdapter.swapCursor(null); } }; private BroadcastReceiver mPuzzleChangeReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { getLoaderManager().restartLoader(0, null, mLoaderCallbacks); } }; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mSelectedPos = 0; if (savedInstanceState != null) { mSelectedPos = savedInstanceState.getInt("selectedPos"); } mAdapter = new FolderAdapter(getActivity(), null); getLoaderManager().initLoader(0, null, mLoaderCallbacks); IntentFilter filter = new IntentFilter(Storage.ACTION_PUZZLE_CHANGE); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getActivity()); lbm.registerReceiver(mPuzzleChangeReceiver, filter); } @Nullable @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View layout = inflater.inflate(R.layout.fragment_folders, container, false); mListView = (ListView) layout.findViewById(R.id.list_view); mListView.setChoiceMode(ListView.CHOICE_MODE_SINGLE); mListView.setAdapter(mAdapter); mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { mSelectedPos = position; notifySelectionChange(); } }); return layout; } @Override public void onSaveInstanceState(Bundle outState) { super.onSaveInstanceState(outState); if (mListView != null) { outState.putInt("selectedPos", mListView.getCheckedItemPosition()); } } @Override public void onDestroy() { super.onDestroy(); LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(getActivity()); lbm.unregisterReceiver(mPuzzleChangeReceiver); } private void notifySelectionChange() { Activity activity = getActivity(); if (mSelectedPos != -1 && activity instanceof OnFolderSelectedListener) { Cursor cursor = (Cursor) mAdapter.getItem(mSelectedPos); if (cursor != null) { OnFolderSelectedListener listener = (OnFolderSelectedListener) activity; listener.onFolderSelected(cursor.getLong(INDEX_FOLDER_ID), cursor.getString(INDEX_FOLDER_TITLE)); } } } private static class FolderAdapter extends CursorAdapter { private static class ViewHolder { TextView mTitle; TextView mCount; } public FolderAdapter(Context context, Cursor cursor) { super(context, cursor, false); } @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { LayoutInflater inflater = LayoutInflater.from(context); View layout = inflater.inflate(R.layout.template_folder_item, parent, false); ViewHolder vh = new ViewHolder(); vh.mTitle = (TextView) layout.findViewById(R.id.title); vh.mCount = (TextView) layout.findViewById(R.id.count); layout.setTag(vh); return layout; } @Override public void bindView(View view, Context context, Cursor cursor) { ViewHolder vh = (ViewHolder) view.getTag(); int icon = 0; long id = cursor.getLong(INDEX_FOLDER_ID); if (id == Storage.FOLDER_INBOX) { icon = R.drawable.ic_folder_inbox; } else if (id == Storage.FOLDER_ARCHIVES) { icon = R.drawable.ic_folder_archived; } else if (id == Storage.FOLDER_TRASH) { icon = R.drawable.ic_folder_trash; } if (icon != 0) { vh.mTitle.setCompoundDrawablesWithIntrinsicBounds(icon, 0, 0, 0); } int count = cursor.getInt(INDEX_FOLDER_COUNT); String countStr = ""; if (count > 0) { countStr = String.valueOf(count); } vh.mTitle.setText(cursor.getString(INDEX_FOLDER_TITLE)); vh.mCount.setText(countStr); } } private static class FolderLoader extends SimpleCursorLoader { private FolderLoader(Context context) { super(context); } @Override public Cursor loadInBackground() { SQLiteDatabase db = Storage.getInstance().getDatabase(false); Cursor cursor = db.rawQuery(sQuery, null); if (cursor != null) { cursor.getCount(); } return cursor; } } }