com.mstoyanov.music_lessons.StudentsFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.mstoyanov.music_lessons.StudentsFragment.java

Source

/*   Copyright (C) 2013, Martin Stoyanov
 *   This program is free software: you can redistribute it and/or modify it under 
 *   the terms of the GNU Affero General Public License as published by the Free
 *   Software Foundation, either version 3 of the License, or (at your option) any
 *   later version.
 *
 *   This program is distributed in the hope that it will be useful, but WITHOUT 
 *   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 
 *   FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more 
 *   details.
 *
 *   You should have received a copy of the GNU Affero General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.   */

package com.mstoyanov.music_lessons;

import java.util.ArrayList;
import java.util.List;
import com.mstoyanov.music_lessons.data.SchoolContract;
import com.mstoyanov.music_lessons.model.Actions;
import com.mstoyanov.music_lessons.model.ActionsAdapter;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TextView;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;

/*    A fragment of the MainActivity, under tab 2 of total 3 tabs,
 *    which Displays a list of all students.
 * 
 *    In single pane mode it calls StudentDetailsActivity, with student
 *    Id passed in. The StudentDetailsActivity contains the clicked student's
 *  contact data, so call, SMS or email action can be performed. 
 * 
 *    In dual pane mode the layout of the StudentDetailsActivity appears
 *    on the right side of the screen of the StudentsFragment.   */

public class StudentsFragment extends Fragment
        implements LoaderManager.LoaderCallbacks<Cursor>, OnItemClickListener {

    private boolean dualPane; // flag
    private int selectedStudent; // index
    // there are students entered into the database:
    private boolean studentsEntered;
    private int studentId;
    private List<Actions> actions; // call, SMS, email

    private SimpleCursorAdapter studentsAdapter;
    private ActionsAdapter studentDetailsAdapter;

    private ListView studentsList;
    private ListView studentDetailsList;

    private TextView firstNameTextView;
    private TextView lastNameTextView;
    private TextView firstNameLabel;
    private TextView lastNameLabel;

    private static final int STUDENTS_LOADER = 0;
    private static final int STUDENT_DETAILS_LOADER = 1;
    private static final int LESSONS_LOADER = 2;

    private static final String selection = "studentID = ?";
    private String[] selectionArgs = new String[1];
    private static final String[] projection = { SchoolContract.Students.COLUMN_NAME_STUDENT_ID + " as _id",
            SchoolContract.Students.COLUMN_NAME_FIRST_NAME, SchoolContract.Students.COLUMN_NAME_LAST_NAME };
    private static final String sortOrder = SchoolContract.Students.COLUMN_NAME_FIRST_NAME + ", "
            + SchoolContract.Students.COLUMN_NAME_LAST_NAME;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        super.onCreateView(inflater, container, savedInstanceState);
        View view = inflater.inflate(R.layout.students_fragment, container, false);
        return view;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        setHasOptionsMenu(true);

        String[] fromColumns = new String[] { "firstName", "lastName" };
        int[] toViews = new int[] { R.id.firstName, R.id.lastName };
        studentsAdapter = new SimpleCursorAdapter(getActivity(), R.layout.student_list_item, // layout
                null, // no cursor is created yet
                fromColumns, // columns
                toViews, // UI controls
                0 // flags
        );
        studentsList = (ListView) getActivity().findViewById(R.id.students_list);
        studentsList.setOnItemClickListener(this);
        studentsList.setAdapter(studentsAdapter);

        // determine the current layout:
        View studentDetailsView = getActivity().findViewById(R.id.student_details_pane);
        dualPane = studentDetailsView != null && studentDetailsView.getVisibility() == View.VISIBLE;

        if (dualPane) {
            if (savedInstanceState != null) {
                selectedStudent = savedInstanceState.getInt("SELECTED_STUDENT", 0);
            } else if (getActivity().getIntent() != null) {
                selectedStudent = getActivity().getIntent().getIntExtra("SELECTED_STUDENT", selectedStudent);
            }

            firstNameLabel = ((TextView) getActivity().findViewById(R.id.label_fname_students));
            firstNameTextView = ((TextView) getActivity().findViewById(R.id.fname_students));
            lastNameLabel = ((TextView) getActivity().findViewById(R.id.label_lname_students));
            lastNameTextView = ((TextView) getActivity().findViewById(R.id.lname_students));

            studentDetailsList = (ListView) getActivity().findViewById(R.id.student_details_list);
            studentDetailsList.setOnItemClickListener(this);
            actions = new ArrayList<Actions>();
            studentDetailsAdapter = new ActionsAdapter(getActivity(), actions);
            studentDetailsList.setAdapter(studentDetailsAdapter);
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        getLoaderManager().restartLoader(STUDENTS_LOADER, null, this);
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        if (dualPane) {
            getActivity().getMenuInflater().inflate(R.menu.student_details_menu, menu);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.menu_edit_student:
            if (studentsEntered) {
                Intent intent = new Intent(getActivity(), EditStudentActivity.class);
                intent.putExtra("STUDENT_ID", studentId);
                intent.putExtra("DUAL_PANE", dualPane);
                intent.putExtra("SELECTED_STUDENT", selectedStudent);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                return true;
            }
            return true;
        case R.id.menu_delete_student:
            if (studentsEntered) {
                // Create AlertDialog:
                AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getActivity());
                alertDialogBuilder.setMessage("Delete student?")
                        .setPositiveButton("Delete", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                // delete the selected student:
                                getActivity().getContentResolver().delete(SchoolContract.STUDENTS_TABLE_CONTENTURI, // uri
                                        selection, // selection
                                        selectionArgs // selectionArgs
                                );
                                // check if this student has associated
                                // lessons, and delete them, if so:
                                getLoaderManager().initLoader(LESSONS_LOADER, null, StudentsFragment.this);
                                // Navigate back to the main screen:
                                Intent intent = new Intent(getActivity(), MainActivity.class);
                                // select the "Students" tab:
                                intent.putExtra("SELECTED_TAB", 1);
                                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                                startActivity(intent);
                            }
                        }).setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int id) {
                                dialog.cancel();
                            }
                        });
                AlertDialog alertDialog = alertDialogBuilder.create();
                alertDialog.show();
                return true;
            }
            return true;
        default:
            throw new IllegalArgumentException("Invalid ItemId: " + item.getItemId());
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        if (dualPane) {
            outState.putInt("SELECTED_STUDENT", selectedStudent);
        }
    }

    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        switch (parent.getId()) {
        case R.id.students_list:
            Cursor cursor = (Cursor) parent.getItemAtPosition(position);
            studentId = cursor.getInt(cursor.getColumnIndex("_id"));
            String firstName = cursor.getString(cursor.getColumnIndex("firstName"));
            String lastName = cursor.getString(cursor.getColumnIndex("lastName"));
            if (dualPane) {
                studentsList.setItemChecked(position, true);
                selectedStudent = position;

                selectionArgs[0] = String.valueOf(studentId);

                firstNameLabel.setText("First Name");
                firstNameTextView.setText(firstName);
                lastNameLabel.setText("Last Name");
                lastNameTextView.setText(lastName);

                getLoaderManager().restartLoader(STUDENT_DETAILS_LOADER, null, this);
            } else {
                Intent intent = new Intent(getActivity(), StudentDetailsActivity.class);
                intent.putExtra("STUDENT_ID", studentId);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            }
            break;
        case R.id.student_details_list:
            Actions action = actions.get(position);
            switch (action.getType()) {
            case Actions.ACTION_CALL:
                Uri callUri = Uri.parse("tel:" + action.getData());
                Intent intent = new Intent(Intent.ACTION_CALL, callUri);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                break;
            case Actions.ACTION_EMAIL:
                intent = new Intent(Intent.ACTION_SEND);
                intent.setType("plain/text");
                intent.putExtra(Intent.EXTRA_EMAIL, new String[] { action.getData() });
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
                break;
            case Actions.ACTION_SMS:
                Uri smsUri = Uri.parse("sms:" + action.getData());
                intent = new Intent(Intent.ACTION_VIEW, smsUri);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                startActivity(intent);
            default:
                throw new IllegalArgumentException("Invalid action type: " + action.getType());
            }
        default:
            throw new IllegalArgumentException("Invalid parentId: " + parent.getId());
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int loaderID, Bundle bundle) {
        switch (loaderID) {
        case STUDENTS_LOADER:
            return new CursorLoader(getActivity(), // context
                    SchoolContract.STUDENTS_TABLE_CONTENTURI, // uri
                    projection, // projection
                    null, // selection
                    null, // selectionArgs
                    sortOrder // firstName, lastName
            );
        case STUDENT_DETAILS_LOADER:
            return new CursorLoader(getActivity(), // context
                    SchoolContract.STUDENTS_TABLE_CONTENTURI, // uri
                    null, // projection
                    selection, // selection
                    selectionArgs, // selectionArgs
                    null // sortOrder
            );
        case LESSONS_LOADER:
            return new CursorLoader(getActivity(), // context
                    SchoolContract.SCHEDULE_TABLE_CONTENTURI, // uri
                    null, // projection
                    selection, // selection
                    selectionArgs, // selectionArgs
                    null // sortOrder
            );
        default:
            throw new IllegalArgumentException("Invalid loaderID: " + loaderID);
        }
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
        switch (loader.getId()) {
        case STUDENTS_LOADER:
            studentsAdapter.swapCursor(cursor);
            // select the first student, or recover previous state, if the
            // list is not empty:
            if (dualPane && cursor.getCount() > 0) {
                studentsEntered = true;
                onItemClick(studentsList, studentsList.getChildAt(selectedStudent), selectedStudent, -1);
            }
            break;
        case STUDENT_DETAILS_LOADER:
            if (cursor != null) {
                cursor.moveToFirst();
                actions.clear();
                String homePhone = cursor.getString(cursor.getColumnIndex("homePhone"));
                if (homePhone.length() > 0) {
                    actions.add(new Actions("Home", homePhone, Actions.ACTION_CALL));
                }
                String cellPhone = cursor.getString(cursor.getColumnIndex("cellPhone"));
                if (cellPhone.length() > 0) {
                    actions.add(new Actions("Mobile", cellPhone, Actions.ACTION_CALL));
                    actions.add(new Actions("SMS", cellPhone, Actions.ACTION_SMS));
                }
                String workPhone = cursor.getString(cursor.getColumnIndex("workPhone"));
                if (workPhone.length() > 0) {
                    actions.add(new Actions("Office", workPhone, Actions.ACTION_CALL));
                }
                String email = cursor.getString(cursor.getColumnIndex("email"));
                if (email.length() > 0) {
                    actions.add(new Actions("Email", email, Actions.ACTION_EMAIL));
                }
            }
            studentDetailsAdapter.notifyDataSetChanged();
            break;
        case LESSONS_LOADER:
            if (cursor.getCount() > 0) {
                getActivity().getContentResolver().delete(SchoolContract.SCHEDULE_TABLE_CONTENTURI, // uri
                        selection, // selection
                        selectionArgs // selectionArgs
                );
            }
            break;
        default:
            throw new IllegalArgumentException("Unknown loaderId " + loader.getId());
        }
    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        switch (loader.getId()) {
        case STUDENTS_LOADER:
            studentsAdapter.swapCursor(null);
            break;
        case STUDENT_DETAILS_LOADER:
            studentDetailsAdapter.clear();
            break;
        case LESSONS_LOADER:
            // at this point the cursor is out of scope and respectively null;
            // no adapters have been created to clear;
            break;
        }
    }
}