Java tutorial
/* * Copyright 2012 Google Inc. * * 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.conferenceengineer.android.iosched.ui; import android.app.Activity; import android.content.Context; import android.database.Cursor; import android.graphics.Rect; import android.provider.BaseColumns; import android.support.v4.app.FragmentActivity; import android.support.v4.widget.CursorAdapter; import android.view.View; import android.view.ViewGroup; import android.widget.ImageView; import android.widget.TextView; import com.conferenceengineer.android.iosched.conference686.R; import com.conferenceengineer.android.iosched.provider.ScheduleContract; import com.conferenceengineer.android.iosched.util.BitmapCache; import com.conferenceengineer.android.iosched.util.UIUtils; /** * A {@link android.widget.CursorAdapter} that renders a {@link TracksQuery}. */ public class TracksAdapter extends CursorAdapter { private static final int ALL_ITEM_ID = Integer.MAX_VALUE; private static final int LEVEL_2_SECTION_HEADER_ITEM_ID = ALL_ITEM_ID - 1; private Activity mActivity; private boolean mHasAllItem; private int mFirstLevel2CursorPosition = -1; private BitmapCache mBitmapCache; private boolean mIsDropDown; public TracksAdapter(FragmentActivity activity, boolean isDropDown) { super(activity, null, 0); mActivity = activity; mIsDropDown = isDropDown; // Fetch track icon size in pixels. int trackIconSize = activity.getResources().getDimensionPixelSize(R.dimen.track_icon_source_size); // Cache size is total pixels by 4 bytes (as format is ARGB_8888) by 20 (max icons to hold // in the cache) converted to KB. int cacheSize = trackIconSize * trackIconSize * 4 * 20 / 1024; // Create a BitmapCache to hold the track icons. mBitmapCache = BitmapCache.getInstance(activity.getSupportFragmentManager(), UIUtils.TRACK_ICONS_TAG, cacheSize); } @Override public void changeCursor(Cursor cursor) { updateSpecialItemPositions(cursor); super.changeCursor(cursor); } @Override public Cursor swapCursor(Cursor newCursor) { updateSpecialItemPositions(newCursor); return super.swapCursor(newCursor); } public void setHasAllItem(boolean hasAllItem) { mHasAllItem = hasAllItem; updateSpecialItemPositions(getCursor()); } private void updateSpecialItemPositions(Cursor cursor) { mFirstLevel2CursorPosition = -1; if (cursor != null && !cursor.isClosed()) { cursor.moveToFirst(); while (cursor.moveToNext()) { if (cursor.getInt(TracksQuery.TRACK_LEVEL) == 2) { mFirstLevel2CursorPosition = cursor.getPosition(); break; } } } } public boolean isAllTracksItem(int position) { return mHasAllItem && position == 0; } public boolean isLevel2Header(int position) { return mFirstLevel2CursorPosition >= 0 && position - (mHasAllItem ? 1 : 0) == mFirstLevel2CursorPosition; } public int adapterPositionToCursorPosition(int position) { position -= (mHasAllItem ? 1 : 0); if (mFirstLevel2CursorPosition >= 0 && position > mFirstLevel2CursorPosition) { --position; } return position; } @Override public int getCount() { int superCount = super.getCount(); if (superCount == 0) { return 0; } return superCount + (mFirstLevel2CursorPosition >= 0 ? 1 : 0) + (mHasAllItem ? 1 : 0); } @Override public View getView(int position, View convertView, ViewGroup parent) { if (isAllTracksItem(position)) { if (convertView == null) { convertView = mActivity.getLayoutInflater().inflate(R.layout.list_item_track, parent, false); } // Custom binding for the first item ((TextView) convertView.findViewById(android.R.id.text1)) .setText("(" + mActivity.getResources().getString(R.string.all_tracks) + ")"); convertView.findViewById(android.R.id.icon1).setVisibility(View.INVISIBLE); return convertView; } else if (isLevel2Header(position)) { TextView view = (TextView) convertView; if (view == null) { view = (TextView) mActivity.getLayoutInflater().inflate(R.layout.list_item_track_header, parent, false); if (mIsDropDown) { Rect r = new Rect(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(), view.getPaddingBottom()); view.setBackgroundResource(R.drawable.track_header_bottom_border); view.setPadding(r.left, r.top, r.right, r.bottom); } } view.setText(R.string.other_tracks); return view; } return super.getView(adapterPositionToCursorPosition(position), convertView, parent); } @Override public Object getItem(int position) { if (isAllTracksItem(position) || isLevel2Header(position)) { return null; } return super.getItem(adapterPositionToCursorPosition(position)); } @Override public long getItemId(int position) { if (isAllTracksItem(position)) { return ALL_ITEM_ID; } else if (isLevel2Header(position)) { return LEVEL_2_SECTION_HEADER_ITEM_ID; } return super.getItemId(adapterPositionToCursorPosition(position)); } @Override public boolean areAllItemsEnabled() { return false; } @Override public boolean isEnabled(int position) { return position < (mHasAllItem ? 1 : 0) || !isLevel2Header(position) && super.isEnabled(adapterPositionToCursorPosition(position)); } @Override public int getViewTypeCount() { // Add an item type for the "All" item and section header. return super.getViewTypeCount() + 2; } @Override public int getItemViewType(int position) { if (isAllTracksItem(position)) { return getViewTypeCount() - 1; } else if (isLevel2Header(position)) { return getViewTypeCount() - 2; } return super.getItemViewType(adapterPositionToCursorPosition(position)); } /** {@inheritDoc} */ @Override public View newView(Context context, Cursor cursor, ViewGroup parent) { return mActivity.getLayoutInflater().inflate(R.layout.list_item_track, parent, false); } /** {@inheritDoc} */ @Override public void bindView(View view, Context context, Cursor cursor) { String trackName = cursor.getString(TracksQuery.TRACK_NAME); final TextView textView = (TextView) view.findViewById(android.R.id.text1); textView.setText(trackName); // Assign track color and icon to visible block final ImageView iconView = (ImageView) view.findViewById(android.R.id.icon1); new UIUtils.TrackIconViewAsyncTask(iconView, trackName, cursor.getInt(TracksQuery.TRACK_COLOR), mBitmapCache).execute(context); } /** {@link com.conferenceengineer.android.iosched.provider.ScheduleContract.Tracks} query parameters. */ public interface TracksQuery { int _TOKEN = 0x1; String[] PROJECTION = { BaseColumns._ID, ScheduleContract.Tracks.TRACK_ID, ScheduleContract.Tracks.TRACK_NAME, ScheduleContract.Tracks.TRACK_ABSTRACT, ScheduleContract.Tracks.TRACK_COLOR, ScheduleContract.Tracks.TRACK_LEVEL, ScheduleContract.Tracks.TRACK_META, }; String[] PROJECTION_WITH_SESSIONS_COUNT = { BaseColumns._ID, ScheduleContract.Tracks.TRACK_ID, ScheduleContract.Tracks.TRACK_NAME, ScheduleContract.Tracks.TRACK_ABSTRACT, ScheduleContract.Tracks.TRACK_COLOR, ScheduleContract.Tracks.TRACK_LEVEL, ScheduleContract.Tracks.TRACK_META, ScheduleContract.Tracks.SESSIONS_COUNT, }; String[] PROJECTION_WITH_OFFICE_HOURS_COUNT = { BaseColumns._ID, ScheduleContract.Tracks.TRACK_ID, ScheduleContract.Tracks.TRACK_NAME, ScheduleContract.Tracks.TRACK_ABSTRACT, ScheduleContract.Tracks.TRACK_COLOR, ScheduleContract.Tracks.TRACK_LEVEL, ScheduleContract.Tracks.TRACK_META, ScheduleContract.Tracks.OFFICE_HOURS_COUNT, }; String[] PROJECTION_WITH_SANDBOX_COUNT = { BaseColumns._ID, ScheduleContract.Tracks.TRACK_ID, ScheduleContract.Tracks.TRACK_NAME, ScheduleContract.Tracks.TRACK_ABSTRACT, ScheduleContract.Tracks.TRACK_COLOR, ScheduleContract.Tracks.TRACK_LEVEL, ScheduleContract.Tracks.TRACK_META, ScheduleContract.Tracks.SANDBOX_COUNT, }; int _ID = 0; int TRACK_ID = 1; int TRACK_NAME = 2; int TRACK_ABSTRACT = 3; int TRACK_COLOR = 4; int TRACK_LEVEL = 5; int TRACK_META = 6; } }