am a51ef53c: am 821736e1: Added a dialog box, better drag/drop, transparent action bar. fixed crash on camera rotation, updated for new Honeycomb targets.

* commit 'a51ef53c02c3962eb0e060e7919922433eec33fc':
  Added a dialog box, better drag/drop, transparent action bar. fixed crash on camera rotation, updated for new Honeycomb targets.
This commit is contained in:
Alexander Lucas
2011-02-07 13:51:57 -08:00
committed by Android Git Automerger
9 changed files with 185 additions and 43 deletions

View File

@@ -23,6 +23,7 @@
<fragment class="com.example.android.hcgallery.TitlesFragment"
android:id="@+id/frag_title"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="match_parent"
android:layout_height="@dimen/titles_size"/>

View File

@@ -23,6 +23,7 @@
<fragment class="com.example.android.hcgallery.TitlesFragment"
android:id="@+id/frag_title"
android:visibility="gone"
android:layout_marginTop="?android:attr/actionBarSize"
android:layout_width="@dimen/titles_size"
android:layout_height="match_parent" />
@@ -30,5 +31,5 @@
android:id="@+id/frag_content"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>

View File

@@ -27,4 +27,7 @@
<item android:id="@+id/toggleTheme"
android:title="Day/Night"
android:showAsAction="ifRoom|withText" />
<item android:id="@+id/showDialog"
android:title="Show a dialog"
android:showAsAction="ifRoom|withText" />
</menu>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<resources>
<color name="actionbar_background_light">#ccffffff</color>
<color name="actionbar_background_dark">#cc000000</color>
</resources>

View File

@@ -43,20 +43,15 @@ public class CameraFragment extends Fragment {
private Preview mPreview;
Camera mCamera;
int mNumberOfCameras;
int cameraCurrentlyLocked;
int mCameraCurrentlyLocked;
// The first rear facing camera
int defaultCameraId;
int mDefaultCameraId;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Add an up arrow to the "home" button, indicating that the button will go "up"
// one activity in the app's Activity heirarchy.
Activity activity = this.getActivity();
ActionBar actionBar = activity.getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
// Create a RelativeLayout container that will hold a SurfaceView,
// and set it as the content of our activity.
@@ -70,12 +65,26 @@ public class CameraFragment extends Fragment {
for (int i = 0; i < mNumberOfCameras; i++) {
Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
defaultCameraId = i;
mDefaultCameraId = i;
}
}
setHasOptionsMenu(mNumberOfCameras > 1);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// Add an up arrow to the "home" button, indicating that the button will go "up"
// one activity in the app's Activity heirarchy.
// Calls to getActionBar() aren't guaranteed to return the ActionBar when called
// from within the Fragment's onCreate method, because the Window's decor hasn't been
// initialized yet. Either call for the ActionBar reference in Activity.onCreate()
// (after the setContentView(...) call), or in the Fragment's onActivityCreated method.
Activity activity = this.getActivity();
ActionBar actionBar = activity.getActionBar();
actionBar.setDisplayHomeAsUpEnabled(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
@@ -87,8 +96,8 @@ public class CameraFragment extends Fragment {
super.onResume();
// Open the default i.e. the first rear facing camera.
mCamera = Camera.open(defaultCameraId);
cameraCurrentlyLocked = defaultCameraId;
mCamera = Camera.open(mDefaultCameraId);
mCameraCurrentlyLocked = mDefaultCameraId;
mPreview.setCamera(mCamera);
}
@@ -120,7 +129,7 @@ public class CameraFragment extends Fragment {
// Handle item selection
switch (item.getItemId()) {
case R.id.switch_cam:
// Release this camera -> cameraCurrentlyLocked
// Release this camera -> mCameraCurrentlyLocked
if (mCamera != null) {
mCamera.stopPreview();
mPreview.setCamera(null);
@@ -131,8 +140,8 @@ public class CameraFragment extends Fragment {
// Acquire the next camera and request Preview to reconfigure
// parameters.
mCamera = Camera
.open((cameraCurrentlyLocked + 1) % mNumberOfCameras);
cameraCurrentlyLocked = (cameraCurrentlyLocked + 1)
.open((mCameraCurrentlyLocked + 1) % mNumberOfCameras);
mCameraCurrentlyLocked = (mCameraCurrentlyLocked + 1)
% mNumberOfCameras;
mPreview.switchCamera(mCamera);

View File

@@ -23,6 +23,8 @@ import android.app.Fragment;
import android.content.ClipData;
import android.content.ClipDescription;
import android.content.ClipData.Item;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.os.Bundle;
import android.view.DragEvent;
import android.view.LayoutInflater;
@@ -30,8 +32,12 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ImageView;
import android.view.Window;
import android.view.WindowManager;
public class ContentFragment extends Fragment {
// The bitmap currently used by ImageView
private Bitmap mBitmap = null;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
@@ -48,9 +54,16 @@ public class ContentFragment extends Fragment {
view.setOnDragListener(new View.OnDragListener() {
public boolean onDrag(View v, DragEvent event) {
switch (event.getAction()) {
case DragEvent.ACTION_DRAG_ENTERED:
view.setBackgroundColor(Color.LTGRAY);
break;
case DragEvent.ACTION_DRAG_EXITED:
view.setBackgroundColor(Color.TRANSPARENT);
break;
case DragEvent.ACTION_DRAG_STARTED:
return processDragStarted(event);
case DragEvent.ACTION_DROP:
view.setBackgroundColor(Color.TRANSPARENT);
return processDrop(event, imageView);
}
return false;
@@ -59,10 +72,9 @@ public class ContentFragment extends Fragment {
view.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ActionBar bar = ContentFragment.this.getActivity()
.getActionBar();
ActionBar bar = getActivity().getActionBar();
if (bar != null) {
if (bar.isShowing()) {
bar.hide();
@@ -85,7 +97,7 @@ public class ContentFragment extends Fragment {
return false;
}
boolean processDrop(DragEvent event, ImageView imageView) {
private boolean processDrop(DragEvent event, ImageView imageView) {
// Attempt to parse clip data with expected format: category||entry_id.
// Ignore event if data does not conform to this format.
ClipData data = event.getClipData();
@@ -106,14 +118,28 @@ public class ContentFragment extends Fragment {
} catch (NumberFormatException exception) {
return false;
}
imageView.setImageBitmap(
Directory.getCategory(category)
.getEntry(entryId)
.getBitmap(getResources()));
updateContentAndRecycleBitmap(category, entryId);
// Update list fragment with selected entry.
TitlesFragment titlesFrag = (TitlesFragment)
getFragmentManager().findFragmentById(R.id.frag_title);
titlesFrag.selectPosition(entryId);
return true;
}
}
}
return false;
}
public void updateContentAndRecycleBitmap(int category, int position) {
// Get the bitmap that needs to be drawn and update the ImageView
Bitmap next = Directory.getCategory(category).getEntry(position)
.getBitmap(getResources());
((ImageView) getView().findViewById(R.id.image)).setImageBitmap(next);
if (mBitmap != null) {
// This is an advanced call and should be used if you
// are working with a lot of bitmaps. The bitmap is dead
// after this call.
mBitmap.recycle();
}
}
}

View File

@@ -17,13 +17,13 @@
package com.example.android.hcgallery;
public class Directory {
private static DirectoryCategory[] categories;
private static DirectoryCategory[] mCategories;
public static void initializeDirectory() {
categories = new DirectoryCategory[] {
mCategories = new DirectoryCategory[] {
new DirectoryCategory("Balloons", new DirectoryEntry[] {
new DirectoryEntry("Green Balloon", R.drawable.green_balloon),
new DirectoryEntry("Red Balloon", R.drawable.red_balloon),
new DirectoryEntry("Green Balloon", R.drawable.green_balloon),
new DirectoryEntry("Blue Balloon", R.drawable.blue_balloon)}),
new DirectoryCategory("Bikes", new DirectoryEntry[] {
new DirectoryEntry("Old school huffy", R.drawable.blue_bike),
@@ -42,10 +42,10 @@ public class Directory {
}
public static int getCategoryCount() {
return categories.length;
return mCategories.length;
}
public static DirectoryCategory getCategory(int i) {
return categories[i];
return mCategories[i];
}
}

View File

@@ -23,16 +23,22 @@ 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.content.DialogInterface;
import android.content.Intent;
import android.content.res.Configuration;
import android.graphics.drawable.ColorDrawable;
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;
public class MainActivity extends Activity implements ActionBar.TabListener {
@@ -49,16 +55,27 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
mThemeId = savedInstanceState.getInt("theme");
this.setTheme(mThemeId);
}
requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
setContentView(R.layout.main);
Directory.initializeDirectory();
ActionBar bar = getActionBar();
if (mThemeId == android.R.style.Theme_Holo_Light || mThemeId == -1) {
bar.setBackgroundDrawable(
new ColorDrawable(getResources().getColor(R.color.actionbar_background_light)));
} else {
bar.setBackgroundDrawable(
new ColorDrawable(getResources().getColor(R.color.actionbar_background_dark)));
}
int i;
for (i = 0; i < Directory.getCategoryCount(); 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);
@@ -108,6 +125,7 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
case R.id.toggleTitles:
toggleVisibleTitles();
return true;
case R.id.toggleTheme:
if (mThemeId == android.R.style.Theme_Holo) {
mThemeId = android.R.style.Theme_Holo_Light;
@@ -115,6 +133,12 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
mThemeId = android.R.style.Theme_Holo;
}
this.recreate();
return true;
case R.id.showDialog:
showDialog();
return true;
default:
return super.onOptionsItemSelected(item);
}
@@ -203,6 +227,19 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
invalidateOptionsMenu();
}
void showDialog() {
// 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("The Dialog Of Awesome");
// Create and show the dialog.
newFragment.show(ft, "dialog");
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]);
@@ -217,4 +254,37 @@ public class MainActivity extends Activity implements ActionBar.TabListener {
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("title", title);
frag.setArguments(args);
return frag;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
String title = getArguments().getString("title");
return new AlertDialog.Builder(getActivity())
.setTitle(title)
.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
}
}
)
.create();
}
}
}

View File

@@ -16,14 +16,18 @@
package com.example.android.hcgallery;
import android.app.Fragment;
import android.app.FragmentManager;
import android.app.ListFragment;
import android.content.ClipData;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.TextPaint;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
@@ -51,10 +55,8 @@ public class TitlesFragment extends ListFragment {
lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
selectPosition(mCurPosition);
lv.setCacheColorHint(Color.WHITE);
lv.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> av, View v, int pos,
long id) {
final String title = (String) ((TextView) v).getText();
@@ -62,24 +64,36 @@ public class TitlesFragment extends ListFragment {
// Set up clip data with the category||entry_id format.
final String textData = String.format("%d||%d", mCategory, pos);
ClipData data = ClipData.newPlainText(title, textData);
v.startDrag(data, new MyDragShadowBuilder(v), null, 0);
v.startDrag(data, new MyDragShadowBuilder(v, title), null, 0);
return true;
}
});
}
private static class MyDragShadowBuilder extends View.DragShadowBuilder {
private static Drawable shadow;
public MyDragShadowBuilder(View v) {
private static Drawable mShadow;
private static String mLabel;
private static int mViewHeight;
public MyDragShadowBuilder(View v, String label) {
super(v);
shadow = new ColorDrawable(Color.BLUE);
shadow.setBounds(0, 0, v.getWidth(), v.getHeight());
mShadow = new ColorDrawable(Color.BLUE);
mShadow.setBounds(0, 0, v.getWidth(), v.getHeight());
mLabel = label;
mViewHeight = v.getHeight();
}
@Override
public void onDrawShadow(Canvas canvas) {
shadow.draw(canvas);
super.onDrawShadow(canvas);
mShadow.draw(canvas);
Paint paint = new TextPaint();
paint.setTextSize(20);
paint.setColor(Color.LTGRAY);
paint.setTypeface(Typeface.DEFAULT_BOLD);
paint.setAntiAlias(true);
canvas.drawText(mLabel, 20, (float) (mViewHeight * .6), paint);
}
}
@@ -99,11 +113,9 @@ public class TitlesFragment extends ListFragment {
}
private void updateImage(int position) {
ImageView iv = (ImageView) getFragmentManager().findFragmentById(
R.id.frag_content).getView().findViewById(R.id.image);
iv.setImageDrawable(Directory.getCategory(mCategory).getEntry(position)
.getDrawable(getResources()));
mCurPosition = position;
ContentFragment frag = (ContentFragment) getFragmentManager()
.findFragmentById(R.id.frag_content);
frag.updateContentAndRecycleBitmap(mCategory, position);
}
public void selectPosition(int position) {