/*
* Copyright 2014 Google Inc. All rights reserved.
*
* 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.google.samples.apps.iosched.ui;
import android.app.Fragment;
import android.app.LoaderManager;
import android.content.*;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.text.Html;
import android.text.Spanned;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.CursorAdapter;
import android.widget.ImageView;
import android.widget.TextView;
import com.google.samples.apps.iosched.BuildConfig;
import com.google.samples.apps.iosched.R;
import com.google.samples.apps.iosched.provider.ScheduleContract;
import com.google.samples.apps.iosched.ui.widget.CollectionView;
import com.google.samples.apps.iosched.ui.widget.CollectionViewCallbacks;
import com.google.samples.apps.iosched.ui.widget.MessageCardView;
import com.google.samples.apps.iosched.util.ImageLoader;
import com.google.samples.apps.iosched.util.UIUtils;
import java.util.ArrayList;
import java.util.Locale;
import static com.google.samples.apps.iosched.util.LogUtils.LOGD;
import static com.google.samples.apps.iosched.util.LogUtils.makeLogTag;
public class ExpertsDirectoryFragment extends Fragment implements
LoaderManager.LoaderCallbacks<Cursor>,
SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = makeLogTag(ExpertsDirectoryFragment.class);
/**
* Preference key for whether the explanation header should be shown
*/
private static final String PREF_SHOW_HEADER = "experts_directory_show_header";
private CollectionView mCollectionView;
private ExpertsAdapter mExpertsAdapter;
private int mDisplayCols;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDisplayCols = getResources().getInteger(R.integer.experts_directory_columns);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_experts_directory, container, false);
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
mCollectionView = (CollectionView) view.findViewById(R.id.collection_view);
((BaseActivity) getActivity()).enableActionBarAutoHide(mCollectionView);
}
@Override
public void onResume() {
super.onResume();
PreferenceManager.getDefaultSharedPreferences(getActivity())
.registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onPause() {
super.onPause();
PreferenceManager.getDefaultSharedPreferences(getActivity())
.unregisterOnSharedPreferenceChangeListener(this);
}
public void reload(String country, String city) {
Bundle args = new Bundle();
args.putString(ScheduleContract.Experts.EXPERT_COUNTRY, country);
if (null != city) {
args.putString(ScheduleContract.Experts.EXPERT_CITY, city);
}
getLoaderManager().restartLoader(ExpertsQuery.TOKEN, args, this);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch (id) {
case ExpertsQuery.TOKEN:
StringBuilder selection = new StringBuilder();
ArrayList<String> selectionArgs = new ArrayList<String>();
if (null != args) {
String country = args.getString(ScheduleContract.Experts.EXPERT_COUNTRY);
String city = args.getString(ScheduleContract.Experts.EXPERT_CITY);
if (null != country) {
selection.append(ScheduleContract.Experts.EXPERT_COUNTRY);
selection.append(" = ?");
selectionArgs.add(country);
if (null != city) {
selection.append(" AND ");
selection.append(ScheduleContract.Experts.EXPERT_CITY);
selection.append(" = ?");
selectionArgs.add(city);
}
}
}
String s = null;
String[] ss = null;
if (0 < selection.length()) {
s = selection.toString();
ss = selectionArgs.toArray(new String[selectionArgs.size()]);
}
return new CursorLoader(getActivity(), ScheduleContract.Experts.CONTENT_URI,
ExpertsQuery.PROJECTION, s, ss,
"-" + ScheduleContract.Experts.EXPERT_ATTENDING
+ "," + ScheduleContract.Experts.EXPERT_NAME);
}
return null;
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
switch (loader.getId()) {
case ExpertsQuery.TOKEN: {
LOGD(TAG, "Expert count: " + cursor.getCount());
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
mExpertsAdapter = new ExpertsAdapter(cursor);
mExpertsAdapter.setShowHeader(sp.getBoolean(PREF_SHOW_HEADER, true));
mCollectionView.setCollectionAdapter(mExpertsAdapter);
mCollectionView.updateInventory(mExpertsAdapter.getInventory());
break;
}
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
switch (loader.getId()) {
case ExpertsQuery.TOKEN: {
mCollectionView.updateInventory(new CollectionView.Inventory());
break;
}
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sp, String key) {
if (TextUtils.equals(key, PREF_SHOW_HEADER)) {
if (null != mExpertsAdapter) {
mExpertsAdapter.setShowHeader(sp.getBoolean(PREF_SHOW_HEADER, true));
mCollectionView.updateInventory(mExpertsAdapter.getInventory());
}
}
}
public void setContentTopClearance(int clearance) {
if (mCollectionView != null) {
mCollectionView.setContentTopClearance(clearance);
}
}
/**
* An adapter for experts. It can also be used with {@link CollectionView}. In that case, use
* {@link ExpertsAdapter#getInventory()} to get a {@link CollectionView.Inventory} and
* set it to the {@link CollectionView} by
* {@link CollectionView#updateInventory(CollectionView.Inventory)}.
*/
private class ExpertsAdapter extends CursorAdapter implements CollectionViewCallbacks {
private final ImageLoader mImageLoader;
private final Cursor mCursor;
private boolean mShowHeader = true;
public ExpertsAdapter(Cursor cursor) {
super(getActivity(), cursor, 0);
mCursor = cursor;
mImageLoader = new ImageLoader(getActivity(), R.drawable.person_image_empty);
}
private String getSummary(Cursor cursor) {
StringBuilder summary = new StringBuilder();
String city = cursor.getString(ExpertsQuery.EXPERT_CITY);
summary.append(city);
String countryName = getCountryName(cursor.getString(ExpertsQuery.EXPERT_COUNTRY));
if (!TextUtils.isEmpty(countryName)) {
if (!TextUtils.isEmpty(city)) {
summary.append(", ");
}
summary.append(countryName);
}
return summary.toString();
}
private CharSequence getBio(Cursor cursor) {
StringBuilder bio = new StringBuilder();
if (0 != cursor.getLong(ExpertsQuery.EXPERT_ATTENDING)) {
bio.append("<b>(");
bio.append(getString(R.string.experts_directory_attending));
bio.append(")</b> ");
}
bio.append(cursor.getString(ExpertsQuery.EXPERT_ABSTRACT));
return Html.fromHtml(bio.toString());
}
public void setShowHeader(boolean showHeader) {
mShowHeader = showHeader;
}
/**
* Returns a new instance of {@link CollectionView.Inventory}. It always contains only one
* {@link CollectionView.InventoryGroup}.
*
* @return A new instance of {@link CollectionView.Inventory}
*/
public CollectionView.Inventory getInventory() {
CollectionView.Inventory inventory = new CollectionView.Inventory();
inventory.addGroup(new CollectionView.InventoryGroup(ExpertsQuery.TOKEN)
.setDisplayCols(mDisplayCols)
.setItemCount(mCursor.getCount())
.setDataIndexStart(0)
.setShowHeader(mShowHeader)
.setHeaderLabel(getString(R.string.title_experts_directory)));
return inventory;
}
@Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
// The argument cursor is null when this adapter is used as a CollectionViewCallbacks.
View view = LayoutInflater.from(context).inflate(R.layout.list_item_expert, parent, false);
assert view != null;
ViewHolder holder = new ViewHolder();
holder.image = (ImageView) view.findViewById(R.id.image);
holder.name = (TextView) view.findViewById(R.id.name);
holder.summary = (TextView) view.findViewById(R.id.summary);
holder.bio = (TextView) view.findViewById(R.id.bio);
view.setTag(holder);
return view;
}
@Override
public void bindView(View view, Context context, Cursor cursor) {
final String url = mCursor.getString(ExpertsQuery.EXPERT_URL);
view.findViewById(R.id.expert_target).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!TextUtils.isEmpty(url)) {
Intent expertProfileIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
UIUtils.preferPackageForIntent(getActivity(), expertProfileIntent,
UIUtils.GOOGLE_PLUS_PACKAGE_NAME);
expertProfileIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
startActivity(expertProfileIntent);
}
}
});
ViewHolder holder = (ViewHolder) view.getTag();
mImageLoader.loadImage(cursor.getString(ExpertsQuery.EXPERT_IMAGE_URL), holder.image);
holder.name.setText(cursor.getString(ExpertsQuery.EXPERT_NAME));
holder.summary.setText(getSummary(cursor));
holder.bio.setText(getBio(cursor));
}
@Override
public View newCollectionHeaderView(Context context, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.header_experts_directory, parent, false);
}
@Override
public void bindCollectionHeaderView(Context context, View view, int groupId, String headerLabel) {
final MessageCardView messageCardView = (MessageCardView) view.findViewById(R.id.message_card);
messageCardView.setListener(new MessageCardView.OnMessageCardButtonClicked() {
@Override
public void onMessageCardButtonClicked(String tag) {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
sp.edit().putBoolean(PREF_SHOW_HEADER, false).commit();
messageCardView.dismiss(true);
}
});
}
/**
* {@inheritDoc}
* This implementation just delegates to {@link ExpertsAdapter#newView(Context, Cursor, ViewGroup)}.
*/
@Override
public View newCollectionItemView(Context context, int groupId, ViewGroup parent) {
return newView(context, null, parent);
}
/**
* {@inheritDoc}
* This implementation just delegates to {@link ExpertsAdapter#bindView(View, Context, Cursor)}
*/
@Override
public void bindCollectionItemView(Context context, View view, int groupId, int indexInGroup, int dataIndex, Object tag) {
setCursorPosition(indexInGroup);
bindView(view, context, mCursor);
}
private void setCursorPosition(int position) {
if (!mCursor.moveToPosition(position)) {
throw new IllegalStateException("couldn't move cursor to position " + position);
}
}
}
private static String getCountryName(String countryCode) {
return new Locale("", countryCode).getDisplayCountry();
}
private static class ViewHolder {
ImageView image;
TextView name;
TextView summary;
TextView bio;
}
private interface ExpertsQuery {
int TOKEN = 0x3;
String[] PROJECTION = {
ScheduleContract.Experts._ID,
ScheduleContract.Experts.EXPERT_NAME,
ScheduleContract.Experts.EXPERT_IMAGE_URL,
ScheduleContract.Experts.EXPERT_COUNTRY,
ScheduleContract.Experts.EXPERT_CITY,
ScheduleContract.Experts.EXPERT_ABSTRACT,
ScheduleContract.Experts.EXPERT_ATTENDING,
ScheduleContract.Experts.EXPERT_URL,
};
int EXPERT_NAME = 1;
int EXPERT_IMAGE_URL = 2;
int EXPERT_COUNTRY = 3;
int EXPERT_CITY = 4;
int EXPERT_ABSTRACT = 5;
int EXPERT_ATTENDING = 6;
int EXPERT_URL = 7;
}
}