/** * Copyright 2010 Mark Wyszomierski */ package com.joelapenna.foursquared; import com.joelapenna.foursquare.types.Category; import com.joelapenna.foursquare.types.Group; import com.joelapenna.foursquared.util.RemoteResourceManager; import com.joelapenna.foursquared.widget.CategoryPickerAdapter; import android.app.Dialog; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; import android.widget.ViewFlipper; import android.widget.AdapterView.OnItemClickListener; import java.io.IOException; /** * Presents the user with a list of all available categories from foursquare * that they can use to label a new venue. * * @date March 7, 2010 * @author Mark Wyszomierski (markww@gmail.com), foursquare. */ public class CategoryPickerDialog extends Dialog { private static final String TAG = "FriendRequestsActivity"; private static final boolean DEBUG = FoursquaredSettings.DEBUG; private Foursquared mApplication; private Group<Category> mCategories; private ViewFlipper mViewFlipper; private Category mChosenCategory; private int mFirstDialogHeight; public CategoryPickerDialog(Context context, Group<Category> categories, Foursquared application) { super(context); mApplication = application; mCategories = categories; mChosenCategory = null; } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.category_picker_dialog); setTitle(getContext().getResources().getString(R.string.category_picket_dialog_title)); mViewFlipper = (ViewFlipper) findViewById(R.id.categoryPickerViewFlipper); mFirstDialogHeight = -1; // By default we always have a top-level page. Category root = new Category(); root.setNodeName("root"); root.setChildCategories(mCategories); mViewFlipper.addView(makePage(root)); } private View makePage(Category category) { LayoutInflater inflater = LayoutInflater.from(getContext()); View view = inflater.inflate(R.layout.category_picker_page, null); CategoryPickerPage page = new CategoryPickerPage(); page.ensureUI(view, mPageListItemSelected, category, mApplication .getRemoteResourceManager()); view.setTag(page); if (mViewFlipper.getChildCount() == 1 && mFirstDialogHeight == -1) { mFirstDialogHeight = mViewFlipper.getChildAt(0).getHeight(); } if (mViewFlipper.getChildCount() > 0) { view.setLayoutParams(new LinearLayout.LayoutParams( LinearLayout.LayoutParams.FILL_PARENT, mFirstDialogHeight)); } return view; } @Override protected void onStop() { super.onStop(); cleanupPageAdapters(); } private void cleanupPageAdapters() { for (int i = 0; i < mViewFlipper.getChildCount(); i++) { CategoryPickerPage page = (CategoryPickerPage) mViewFlipper.getChildAt(i).getTag(); page.cleanup(); } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { case KeyEvent.KEYCODE_BACK: if (mViewFlipper.getChildCount() > 1) { mViewFlipper.removeViewAt(mViewFlipper.getChildCount() - 1); return true; } break; } return super.onKeyDown(keyCode, event); } /** * After the user has dismissed the dialog, the parent activity can use this * to see which category they picked, if any. Will return null if no * category was picked. */ public Category getChosenCategory() { return mChosenCategory; } private static class CategoryPickerPage { private CategoryPickerAdapter mListAdapter; private Category mCategory; private PageListItemSelected mClickListener; public void ensureUI(View view, PageListItemSelected clickListener, Category category, RemoteResourceManager rrm) { mCategory = category; mClickListener = clickListener; mListAdapter = new CategoryPickerAdapter(view.getContext(), rrm, category); ListView listview = (ListView) view.findViewById(R.id.categoryPickerListView); listview.setAdapter(mListAdapter); listview.setOnItemClickListener(mOnItemClickListener); LinearLayout llRootCategory = (LinearLayout) view .findViewById(R.id.categoryPickerRootCategoryButton); if (category.getNodeName().equals("root") == false) { ImageView iv = (ImageView) view.findViewById(R.id.categoryPickerIcon); try { Bitmap bitmap = BitmapFactory.decodeStream(rrm.getInputStream(Uri .parse(category.getIconUrl()))); iv.setImageBitmap(bitmap); } catch (IOException e) { if (DEBUG) Log.e(TAG, "Error loading category icon from disk.", e); } TextView tv = (TextView) view.findViewById(R.id.categoryPickerName); tv.setText(category.getNodeName()); llRootCategory.setClickable(true); llRootCategory.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mClickListener.onCategorySelected(mCategory); } }); } else { llRootCategory.setVisibility(View.GONE); } } public void cleanup() { mListAdapter.removeObserver(); } private OnItemClickListener mOnItemClickListener = new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapter, View view, int position, long id) { mClickListener.onPageListItemSelcected((Category) mListAdapter.getItem(position)); } }; } private PageListItemSelected mPageListItemSelected = new PageListItemSelected() { @Override public void onPageListItemSelcected(Category category) { // If the item has children, create a new page for it. if (category.getChildCategories() != null && category.getChildCategories().size() > 0) { mViewFlipper.addView(makePage(category)); mViewFlipper.showNext(); } else { // This is a leaf node, finally the user's selection. Record the // category // then cancel ourselves, parent activity should pick us up // after that. mChosenCategory = category; cancel(); } } @Override public void onCategorySelected(Category category) { // The user has chosen the category parent listed at the top of the // current page. mChosenCategory = category; cancel(); } }; private interface PageListItemSelected { public void onPageListItemSelcected(Category category); public void onCategorySelected(Category category); } }