Skip to content

Instantly share code, notes, and snippets.

@alwx
Created July 31, 2013 20:05
Show Gist options
  • Save alwx/6125648 to your computer and use it in GitHub Desktop.
Save alwx/6125648 to your computer and use it in GitHub Desktop.
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.BaseColumns;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.text.TextUtils;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;
import com.bytelimit.dk.sqlite.SQLiteUtils;
import com.bytelimit.dk.sqlite.dao.CachedSQLiteDAOFactory;
import com.bytelimit.dk.sqlite.dao.SQLiteDAOFactory;
import com.lessonsproject.core.Consts;
import com.lessonsproject.core.R;
import com.lessonsproject.core.api.ApiConfig;
import com.lessonsproject.core.api.handler.SearchLessonsHandler;
import com.lessonsproject.core.api.loader.SearchLessonsLoader;
import com.lessonsproject.core.sqlite.*;
import java.net.URI;
import java.util.regex.Pattern;
import static com.elegion.interneturok.core.ui.LessonFragment.LessonListItem;
/**
* @author alwx
* @version 1.0
*/
public class SearchFragment extends BaseFragment implements LoaderManager.LoaderCallbacks<Cursor> {
private static final Pattern sInputFilter = Pattern.compile("[~'\"`$&#@?!%^\\(\\)\\[\\]]+");
private String mSearchString;
private ProgressBar mLoader;
private ExpandableListView mLessonList;
private SearchAdapter mSearchAdapter;
private EditText mSearchEdit;
private TextView mPlaceholderNoData;
private LinearLayout mPlaceholderNoConnection;
private final View.OnClickListener mItemClickListener = new View.OnClickListener() {
@Override
public void onClick(final View v) {
final LessonListItem lessonListItem = (LessonListItem) v;
final Intent intent = new Intent(getActivity(), LessonActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(Consts.Extra.TITLE_TAG, lessonListItem.getTitle());
intent.putExtra(Consts.Extra.LESSON_ID_TAG, lessonListItem.getUid());
intent.putExtra(Consts.Extra.SCHEDULE_ID_TAG, lessonListItem.getScheduleId());
intent.putExtra(Consts.Extra.CLASS_NAME_TAG, lessonListItem.getLesson().getClass().getName());
getActivity().startActivity(intent);
}
};
private final View.OnClickListener mPlaceholderClickListener = new View.OnClickListener() {
@Override
public void onClick(final View v) {
getLoaderManager().destroyLoader(R.id.schedules_loader);
getLoaderManager().initLoader(R.id.schedules_loader, null, SearchFragment.this);
}
};
private final MenuItem.OnActionExpandListener mExpandListener = new MenuItem.OnActionExpandListener() {
@Override
public boolean onMenuItemActionExpand(final MenuItem item) {
return true;
}
@Override
public boolean onMenuItemActionCollapse(final MenuItem item) {
getActivity().finish();
return true;
}
};
private final TextView.OnEditorActionListener mOnEditorActionListener = new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(final TextView v, final int actionId, final KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH) {
final String searchString = mSearchEdit.getText().toString();
if (searchString.trim().length() >= 3) {
if (!sInputFilter.matcher(searchString).matches() && !searchString.startsWith("/")) {
mSearchString = searchString.trim();
final InputMethodManager imm = (InputMethodManager) getActivity()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(mSearchEdit.getWindowToken(), 0);
getLoaderManager().destroyLoader(R.id.schedules_loader);
getLoaderManager().initLoader(R.id.schedules_loader, null, SearchFragment.this);
return true;
} else {
Toast.makeText(getActivity(), R.string.search_request_error, Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getActivity(), R.string.dialog_error_search, Toast.LENGTH_SHORT).show();
}
}
return false;
}
};
@Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container,
final Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fmt_search, container, false);
mLoader = (ProgressBar) view.findViewById(R.id.loader);
mLessonList = (ExpandableListView) view.findViewById(android.R.id.list);
mLessonList.setGroupIndicator(null);
mPlaceholderNoData = (TextView) view.findViewById(R.id.placeholder_no_data);
mPlaceholderNoConnection = (LinearLayout) view.findViewById(R.id.placeholder_no_connection);
mPlaceholderNoConnection.setVisibility(View.GONE);
return view;
}
@Override
public void onActivityCreated(final Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
mSearchAdapter = new SearchAdapter(getActivity(),
((BaseActivity) getActivity()).getGridColumnNumber(), mItemClickListener);
mLessonList.setAdapter(mSearchAdapter);
}
@Override
public void onCreateOptionsMenu(final Menu menu, final MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.search, menu);
final MenuItem mSearchItem = menu.findItem(R.id.search_edit);
mSearchEdit = (EditText) mSearchItem.getActionView();
mSearchItem.expandActionView();
mSearchItem.getActionView().requestFocus();
mSearchItem.setOnActionExpandListener(mExpandListener);
mSearchEdit.setOnEditorActionListener(mOnEditorActionListener);
setClearButton(mSearchEdit);
}
@Override
public void onResume() {
super.onResume();
mPlaceholderNoConnection.setOnClickListener(mPlaceholderClickListener);
mLessonList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(final ExpandableListView parent, final View v,
final int groupPosition, final long id) {
return true; // disable group collapsing
}
});
}
@Override
public void onPause() {
super.onPause();
mLessonList.setOnGroupClickListener(null);
mPlaceholderNoConnection.setOnClickListener(null);
}
private void setClearButton(final EditText edit) {
final Drawable x = getResources().getDrawable(R.drawable.ic_clear);
x.setBounds(0, 0, x.getIntrinsicWidth(), x.getIntrinsicHeight());
edit.setCompoundDrawables(null, null, x, null);
edit.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(final View v, final MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP && event.getX() > edit.getWidth()
- edit.getPaddingRight() - x.getIntrinsicWidth()) {
edit.setText("");
}
return false;
}
});
}
@Override
public Loader<Cursor> onCreateLoader(final int id, final Bundle bundle) {
if (id == R.id.schedules_loader) {
if (mSearchString != null && !TextUtils.isEmpty(mSearchString)) {
mLoader.setVisibility(View.VISIBLE);
mLessonList.setVisibility(View.GONE);
mPlaceholderNoConnection.setVisibility(View.GONE);
mPlaceholderNoData.setVisibility(View.GONE);
return new SearchLessonsLoader(
getActivity().getApplicationContext(),
mSearchString,
new SearchLessonsHandler(getActivity().getContentResolver()) {
@Override
public void onException(final URI uri, final Exception e) {
mLoader.setVisibility(View.GONE);
mPlaceholderNoConnection.setVisibility(View.VISIBLE);
}
}
);
}
} else if (id == R.id.new_lessons_loader) {
return new CursorLoader(getActivity(),
SQLiteUtils.getBaseUri(NewLesson.class), new String[]{BaseColumns._ID}, null, null, null);
} else if (id == R.id.saved_lessons_loader) {
return new CursorLoader(getActivity(),
SQLiteUtils.getBaseUri(SavedLessonInfo.class), new String[]{BaseColumns._ID}, null, null, null);
}
return null;
}
@Override
public void onLoadFinished(final Loader<Cursor> loader, final Cursor data) {
if (loader.getId() == R.id.schedules_loader) {
getLoaderManager().initLoader(R.id.new_lessons_loader, null, this);
} else if (loader.getId() == R.id.new_lessons_loader) {
final ContentValues emptyNew = new ContentValues();
emptyNew.putNull(SearchLesson.BadgeColumns.NEW);
getActivity().getContentResolver().update(SQLiteUtils.getBaseUri(SearchLesson.class), emptyNew, null, null);
final ContentValues isNew = new ContentValues();
isNew.put(SearchLesson.BadgeColumns.NEW, "1");
data.moveToFirst();
while (!data.isAfterLast()) {
getActivity().getContentResolver().update(SQLiteUtils.getBaseUri(SearchLesson.class),
isNew, BaseColumns._ID + "=?", new String[]{String.valueOf(data.getInt(0))});
data.moveToNext();
}
getLoaderManager().initLoader(R.id.saved_lessons_loader, null, this);
} else if (loader.getId() == R.id.saved_lessons_loader) {
final ContentValues emptyDownloaded = new ContentValues();
emptyDownloaded.putNull(SearchLesson.BadgeColumns.DOWNLOADED);
getActivity().getContentResolver().update(SQLiteUtils.getBaseUri(SearchLesson.class),
emptyDownloaded, null, null);
final ContentValues isDownloaded = new ContentValues();
isDownloaded.put(SearchLesson.BadgeColumns.DOWNLOADED, "1");
data.moveToFirst();
while (!data.isAfterLast()) {
getActivity().getContentResolver().update(SQLiteUtils.getBaseUri(SearchLesson.class),
isDownloaded, BaseColumns._ID + "=?", new String[]{String.valueOf(data.getInt(0))});
data.moveToNext();
}
changeCursor();
}
}
private void changeCursor() {
final Cursor data = getActivity().getContentResolver().query(
SQLiteUtils.getBaseUri(SearchSchedule.class), null, null, null, null
);
mLoader.setVisibility(View.GONE);
mPlaceholderNoConnection.setVisibility(View.GONE);
mSearchAdapter.changeCursor(data);
if (data.moveToFirst()) {
mLessonList.setVisibility(View.VISIBLE);
mPlaceholderNoData.setVisibility(View.GONE);
final int count = mSearchAdapter.getGroupCount();
for (int i = 0; i < count; i++) {
mLessonList.expandGroup(i);
}
} else {
mPlaceholderNoData.setVisibility(View.VISIBLE);
}
}
@Override
public void onLoaderReset(final Loader<Cursor> loader) {
mSearchAdapter.changeCursor(null);
}
private static class SearchAdapter extends CursorTreeAdapter {
private final ContentResolver mContentResolver;
private final SQLiteDAOFactory mDAOFactory;
private final int mColumnNumber;
private final View.OnClickListener mItemClickListener;
public SearchAdapter(final Context context, final int columnNumber, final View.OnClickListener l) {
super(null, context);
mContentResolver = context.getContentResolver();
mDAOFactory = new CachedSQLiteDAOFactory(mContentResolver);
mColumnNumber = columnNumber;
mItemClickListener = l;
}
@Override
protected Cursor getChildrenCursor(final Cursor groupCursor) {
final SearchSchedule schedule = mDAOFactory.getInstance(groupCursor, SearchSchedule.class);
return mContentResolver.query(
SQLiteUtils.getBaseUri(SearchLesson.class), null,
SearchLesson.ReferenceColumns.SCHEDULE_ID + "= ?",
new String[]{Integer.toString(schedule.getRowId())}, null
);
}
@Override
protected View newGroupView(final Context context, final Cursor cursor,
final boolean isExpanded, final ViewGroup parent) {
return new SectionListItem(context);
}
@Override
protected void bindGroupView(final View view, final Context context,
final Cursor cursor, final boolean isExpanded) {
((SectionListItem) view).setSchedule(mDAOFactory.getInstance(cursor, SearchSchedule.class));
}
@Override
public int getChildrenCount(final int groupPosition) {
final Cursor cursor = mContentResolver.query(
SQLiteUtils.getBaseUri(SearchLesson.class), new String[]{"COUNT(" + BaseColumns._ID + ")"},
SearchLesson.ReferenceColumns.SCHEDULE_ID + "= ?",
new String[]{Long.toString(getGroupId(groupPosition))}, null
);
try {
if (cursor.moveToFirst()) {
return (int) Math.ceil(cursor.getInt(0) / (double) mColumnNumber);
}
} finally {
cursor.close();
}
return 0;
}
@Override
protected View newChildView(final Context context, final Cursor cursor,
final boolean isLastChild, final ViewGroup parent) {
final ContainerItem item = new ContainerItem(context);
for (int i = 0; i < mColumnNumber; i++) {
final LessonFragment.LessonListItem subItem = new LessonFragment.LessonListItem(context, mColumnNumber);
item.append(subItem);
}
return item;
}
@Override
protected void bindChildView(final View view, final Context context,
final Cursor cursor, final boolean isLastChild) {
final ContainerItem listItem = (ContainerItem) view;
final int position = cursor.getPosition() * mColumnNumber;
for (int i = 0; i < mColumnNumber; i++) {
listItem.get(i).setVisibility(View.VISIBLE);
if (position + i > cursor.getCount() - 1) {
listItem.get(i).setVisibility(View.INVISIBLE);
break;
}
cursor.moveToPosition(position + i);
final LessonFragment.LessonListItem lessonListItem = (LessonFragment.LessonListItem) listItem.get(i);
final SearchLesson lesson = mDAOFactory.getInstance(cursor, SearchLesson.class);
lessonListItem.setLesson(lesson);
lessonListItem.setImageDrawable(null);
lessonListItem.setPosition(position + i, false);
lessonListItem.setOnClickListener(mItemClickListener);
lessonListItem.setImageUrl(ApiConfig.getSmallPreviewUrl(context, lesson.getUid()));
}
}
@Override
public long getGroupId(final int groupPosition) {
final Cursor cursor = getGroup(groupPosition);
if (cursor == null) {
return Consts.INVALID_ID;
}
return mDAOFactory.getInstance(cursor, SearchSchedule.class).getRowId();
}
}
public static class SectionListItem extends LinearLayout {
final private TextView mTitle;
public SectionListItem(final Context context) {
super(context);
LayoutInflater.from(context).inflate(R.layout.list_group_saved, this);
mTitle = (TextView) findViewById(R.id.title);
findViewById(R.id.drawable_left).setVisibility(View.GONE);
}
public void setSchedule(final Schedule schedule) {
mTitle.setText(schedule.getSubjectName() + ", " + schedule.getName());
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment