blob: 3cfaf6d15942c8fa9e1e28084e05c7af3b139967 [file] [log] [blame]
/*
* Copyright (C) 2011 The Android Open Source Project
*
* 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.example.android.hcgallery;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.app.ActionBar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.DialogFragment;
import android.app.FragmentManager;
import android.app.FragmentTransaction;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.RemoteViews;
public class MainActivity extends Activity implements ActionBar.TabListener {
private static final int NOTIFICATION_DEFAULT = 1;
private static final String ACTION_DIALOG = "com.example.android.hcgallery.action.DIALOG";
private View mActionBarView;
private Animator mCurrentTitlesAnimator;
private String[] mToggleLabels = {"Show Titles", "Hide Titles"};
private int mLabelIndex = 1;
private int mThemeId = -1;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null && savedInstanceState.getInt("theme", -1) != -1) {
mThemeId = savedInstanceState.getInt("theme");
this.setTheme(mThemeId);
}
setContentView(R.layout.main);
Directory.initializeDirectory();
ActionBar bar = getActionBar();
int i;
for (i = 0; i < Directory.getCategoryCount(); i++) {
bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName())
.setTabListener(this));
}
mActionBarView = getLayoutInflater().inflate(
R.layout.action_bar_custom, null);
bar.setCustomView(mActionBarView);
bar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_USE_LOGO);
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.setDisplayShowHomeEnabled(true);
// If category is not saved to the savedInstanceState,
// 0 is returned by default.
if(savedInstanceState != null) {
int category = savedInstanceState.getInt("category");
bar.selectTab(bar.getTabAt(category));
}
}
public void onTabSelected(ActionBar.Tab tab, FragmentTransaction ft) {
TitlesFragment titleFrag = (TitlesFragment) getFragmentManager()
.findFragmentById(R.id.frag_title);
titleFrag.populateTitles(tab.getPosition());
titleFrag.selectPosition(0);
}
public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(ActionBar.Tab tab, FragmentTransaction ft) {
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.camera:
Intent intent = new Intent(this, CameraSample.class);
intent.putExtra("theme", mThemeId);
startActivity(intent);
return true;
case R.id.toggleTitles:
toggleVisibleTitles();
return true;
case R.id.toggleTheme:
if (mThemeId == R.style.AppTheme_Dark) {
mThemeId = R.style.AppTheme_Light;
} else {
mThemeId = R.style.AppTheme_Dark;
}
this.recreate();
return true;
case R.id.showDialog:
showDialog("This is indeed an awesome dialog.");
return true;
case R.id.showStandardNotification:
showNotification(false);
return true;
case R.id.showCustomNotification:
showNotification(true);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
public void toggleVisibleTitles() {
// Use these for custom animations.
final FragmentManager fm = getFragmentManager();
final TitlesFragment f = (TitlesFragment) fm
.findFragmentById(R.id.frag_title);
final View titlesView = f.getView();
mLabelIndex = 1 - mLabelIndex;
// Determine if we're in portrait, and whether we're showing or hiding the titles
// with this toggle.
final boolean isPortrait = getResources().getConfiguration().orientation ==
Configuration.ORIENTATION_PORTRAIT;
final boolean shouldShow = f.isHidden() || mCurrentTitlesAnimator != null;
// Cancel the current titles animation if there is one.
if (mCurrentTitlesAnimator != null)
mCurrentTitlesAnimator.cancel();
// Begin setting up the object animator. We'll animate the bottom or right edge of the
// titles view, as well as its alpha for a fade effect.
ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(
titlesView,
PropertyValuesHolder.ofInt(
isPortrait ? "bottom" : "right",
shouldShow ? getResources().getDimensionPixelSize(R.dimen.titles_size)
: 0),
PropertyValuesHolder.ofFloat("alpha", shouldShow ? 1 : 0)
);
// At each step of the animation, we'll perform layout by calling setLayoutParams.
final ViewGroup.LayoutParams lp = titlesView.getLayoutParams();
objectAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
public void onAnimationUpdate(ValueAnimator valueAnimator) {
// *** WARNING ***: triggering layout at each animation frame highly impacts
// performance so you should only do this for simple layouts. More complicated
// layouts can be better served with individual animations on child views to
// avoid the performance penalty of layout.
if (isPortrait) {
lp.height = (Integer) valueAnimator.getAnimatedValue();
} else {
lp.width = (Integer) valueAnimator.getAnimatedValue();
}
titlesView.setLayoutParams(lp);
}
});
if (shouldShow) {
fm.beginTransaction().show(f).commit();
objectAnimator.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animator) {
mCurrentTitlesAnimator = null;
}
});
} else {
objectAnimator.addListener(new AnimatorListenerAdapter() {
boolean canceled;
@Override
public void onAnimationCancel(Animator animation) {
canceled = true;
super.onAnimationCancel(animation);
}
@Override
public void onAnimationEnd(Animator animator) {
if (canceled)
return;
mCurrentTitlesAnimator = null;
fm.beginTransaction().hide(f).commit();
}
});
}
// Start the animation.
objectAnimator.start();
mCurrentTitlesAnimator = objectAnimator;
invalidateOptionsMenu();
// Manually trigger onNewIntent to check for ACTION_DIALOG.
onNewIntent(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
if (ACTION_DIALOG.equals(intent.getAction())) {
showDialog(intent.getStringExtra(Intent.EXTRA_TEXT));
}
}
void showDialog(String text) {
// DialogFragment.show() will take care of adding the fragment
// in a transaction. We also want to remove any currently showing
// dialog, so make our own transaction and take care of that here.
FragmentTransaction ft = getFragmentManager().beginTransaction();
DialogFragment newFragment = MyDialogFragment.newInstance(text);
// Show the dialog.
newFragment.show(ft, "dialog");
}
void showNotification(boolean custom) {
final Resources res = getResources();
final NotificationManager notificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notify_example)
.setAutoCancel(true)
.setTicker(getString(R.string.notification_text))
.setContentIntent(getDialogPendingIntent("Tapped the notification entry."));
if (custom) {
// Sets a custom content view for the notification, including an image button.
RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
layout.setOnClickPendingIntent(R.id.notification_button,
getDialogPendingIntent("Tapped the 'dialog' button in the notification."));
builder.setContent(layout);
// Notifications in Android 3.0 now have a standard mechanism for displaying large
// bitmaps such as contact avatars. Here, we load an example image and resize it to the
// appropriate size for large bitmaps in notifications.
Bitmap largeIconTemp = BitmapFactory.decodeResource(res,
R.drawable.notification_default_largeicon);
Bitmap largeIcon = Bitmap.createScaledBitmap(
largeIconTemp,
res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height),
false);
largeIconTemp.recycle();
builder.setLargeIcon(largeIcon);
} else {
builder
.setNumber(7) // An example number.
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notification_text));
}
notificationManager.notify(NOTIFICATION_DEFAULT, builder.getNotification());
}
PendingIntent getDialogPendingIntent(String dialogText) {
return PendingIntent.getActivity(
this,
dialogText.hashCode(), // Otherwise previous PendingIntents with the same
// requestCode may be overwritten.
new Intent(ACTION_DIALOG)
.putExtra(Intent.EXTRA_TEXT, dialogText)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
0);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]);
return true;
}
@Override
public void onSaveInstanceState (Bundle outState) {
super.onSaveInstanceState(outState);
ActionBar bar = getActionBar();
int category = bar.getSelectedTab().getPosition();
outState.putInt("category", category);
outState.putInt("theme", mThemeId);
}
public static class MyDialogFragment extends DialogFragment {
public static MyDialogFragment newInstance(String title) {
MyDialogFragment frag = new MyDialogFragment();
Bundle args = new Bundle();
args.putString("text", title);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String text = getArguments().getString("text");
return new AlertDialog.Builder(getActivity())
.setTitle("A Dialog of Awesome")
.setMessage(text)
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.create();
}
}
}