development
Revisão | adb2311abb6d33abc21c493a602467b0ee892e15 (tree) |
---|---|
Hora | 2011-02-08 06:51:57 |
Autor | Alexander Lucas <alexlucas@goog...> |
Commiter | Android Git Automerger |
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':
@@ -23,6 +23,7 @@ | ||
23 | 23 | <fragment class="com.example.android.hcgallery.TitlesFragment" |
24 | 24 | android:id="@+id/frag_title" |
25 | 25 | android:visibility="gone" |
26 | + android:layout_marginTop="?android:attr/actionBarSize" | |
26 | 27 | android:layout_width="match_parent" |
27 | 28 | android:layout_height="@dimen/titles_size"/> |
28 | 29 |
@@ -23,6 +23,7 @@ | ||
23 | 23 | <fragment class="com.example.android.hcgallery.TitlesFragment" |
24 | 24 | android:id="@+id/frag_title" |
25 | 25 | android:visibility="gone" |
26 | + android:layout_marginTop="?android:attr/actionBarSize" | |
26 | 27 | android:layout_width="@dimen/titles_size" |
27 | 28 | android:layout_height="match_parent" /> |
28 | 29 |
@@ -30,5 +31,5 @@ | ||
30 | 31 | android:id="@+id/frag_content" |
31 | 32 | android:layout_width="match_parent" |
32 | 33 | android:layout_height="match_parent" /> |
33 | - | |
34 | + | |
34 | 35 | </LinearLayout> |
@@ -27,4 +27,7 @@ | ||
27 | 27 | <item android:id="@+id/toggleTheme" |
28 | 28 | android:title="Day/Night" |
29 | 29 | android:showAsAction="ifRoom|withText" /> |
30 | + <item android:id="@+id/showDialog" | |
31 | + android:title="Show a dialog" | |
32 | + android:showAsAction="ifRoom|withText" /> | |
30 | 33 | </menu> |
@@ -0,0 +1,20 @@ | ||
1 | +<?xml version="1.0" encoding="utf-8"?> | |
2 | +<!-- | |
3 | + Copyright (C) 2011 The Android Open Source Project | |
4 | + | |
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | |
6 | + you may not use this file except in compliance with the License. | |
7 | + You may obtain a copy of the License at | |
8 | + | |
9 | + http://www.apache.org/licenses/LICENSE-2.0 | |
10 | + | |
11 | + Unless required by applicable law or agreed to in writing, software | |
12 | + distributed under the License is distributed on an "AS IS" BASIS, | |
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
14 | + See the License for the specific language governing permissions and | |
15 | + limitations under the License. | |
16 | + --> | |
17 | +<resources> | |
18 | + <color name="actionbar_background_light">#ccffffff</color> | |
19 | + <color name="actionbar_background_dark">#cc000000</color> | |
20 | +</resources> |
@@ -43,20 +43,15 @@ public class CameraFragment extends Fragment { | ||
43 | 43 | private Preview mPreview; |
44 | 44 | Camera mCamera; |
45 | 45 | int mNumberOfCameras; |
46 | - int cameraCurrentlyLocked; | |
46 | + int mCameraCurrentlyLocked; | |
47 | 47 | |
48 | 48 | // The first rear facing camera |
49 | - int defaultCameraId; | |
49 | + int mDefaultCameraId; | |
50 | 50 | |
51 | 51 | @Override |
52 | 52 | public void onCreate(Bundle savedInstanceState) { |
53 | 53 | super.onCreate(savedInstanceState); |
54 | 54 | |
55 | - // Add an up arrow to the "home" button, indicating that the button will go "up" | |
56 | - // one activity in the app's Activity heirarchy. | |
57 | - Activity activity = this.getActivity(); | |
58 | - ActionBar actionBar = activity.getActionBar(); | |
59 | - actionBar.setDisplayHomeAsUpEnabled(true); | |
60 | 55 | |
61 | 56 | // Create a RelativeLayout container that will hold a SurfaceView, |
62 | 57 | // and set it as the content of our activity. |
@@ -70,13 +65,27 @@ public class CameraFragment extends Fragment { | ||
70 | 65 | for (int i = 0; i < mNumberOfCameras; i++) { |
71 | 66 | Camera.getCameraInfo(i, cameraInfo); |
72 | 67 | if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) { |
73 | - defaultCameraId = i; | |
68 | + mDefaultCameraId = i; | |
74 | 69 | } |
75 | 70 | } |
76 | 71 | setHasOptionsMenu(mNumberOfCameras > 1); |
77 | 72 | } |
78 | 73 | |
79 | 74 | @Override |
75 | + public void onActivityCreated(Bundle savedInstanceState) { | |
76 | + super.onActivityCreated(savedInstanceState); | |
77 | + // Add an up arrow to the "home" button, indicating that the button will go "up" | |
78 | + // one activity in the app's Activity heirarchy. | |
79 | + // Calls to getActionBar() aren't guaranteed to return the ActionBar when called | |
80 | + // from within the Fragment's onCreate method, because the Window's decor hasn't been | |
81 | + // initialized yet. Either call for the ActionBar reference in Activity.onCreate() | |
82 | + // (after the setContentView(...) call), or in the Fragment's onActivityCreated method. | |
83 | + Activity activity = this.getActivity(); | |
84 | + ActionBar actionBar = activity.getActionBar(); | |
85 | + actionBar.setDisplayHomeAsUpEnabled(true); | |
86 | + } | |
87 | + | |
88 | + @Override | |
80 | 89 | public View onCreateView(LayoutInflater inflater, ViewGroup container, |
81 | 90 | Bundle savedInstanceState) { |
82 | 91 | return mPreview; |
@@ -87,8 +96,8 @@ public class CameraFragment extends Fragment { | ||
87 | 96 | super.onResume(); |
88 | 97 | |
89 | 98 | // Open the default i.e. the first rear facing camera. |
90 | - mCamera = Camera.open(defaultCameraId); | |
91 | - cameraCurrentlyLocked = defaultCameraId; | |
99 | + mCamera = Camera.open(mDefaultCameraId); | |
100 | + mCameraCurrentlyLocked = mDefaultCameraId; | |
92 | 101 | mPreview.setCamera(mCamera); |
93 | 102 | } |
94 | 103 |
@@ -120,7 +129,7 @@ public class CameraFragment extends Fragment { | ||
120 | 129 | // Handle item selection |
121 | 130 | switch (item.getItemId()) { |
122 | 131 | case R.id.switch_cam: |
123 | - // Release this camera -> cameraCurrentlyLocked | |
132 | + // Release this camera -> mCameraCurrentlyLocked | |
124 | 133 | if (mCamera != null) { |
125 | 134 | mCamera.stopPreview(); |
126 | 135 | mPreview.setCamera(null); |
@@ -131,8 +140,8 @@ public class CameraFragment extends Fragment { | ||
131 | 140 | // Acquire the next camera and request Preview to reconfigure |
132 | 141 | // parameters. |
133 | 142 | mCamera = Camera |
134 | - .open((cameraCurrentlyLocked + 1) % mNumberOfCameras); | |
135 | - cameraCurrentlyLocked = (cameraCurrentlyLocked + 1) | |
143 | + .open((mCameraCurrentlyLocked + 1) % mNumberOfCameras); | |
144 | + mCameraCurrentlyLocked = (mCameraCurrentlyLocked + 1) | |
136 | 145 | % mNumberOfCameras; |
137 | 146 | mPreview.switchCamera(mCamera); |
138 | 147 |
@@ -23,6 +23,8 @@ import android.app.Fragment; | ||
23 | 23 | import android.content.ClipData; |
24 | 24 | import android.content.ClipDescription; |
25 | 25 | import android.content.ClipData.Item; |
26 | +import android.graphics.Bitmap; | |
27 | +import android.graphics.Color; | |
26 | 28 | import android.os.Bundle; |
27 | 29 | import android.view.DragEvent; |
28 | 30 | import android.view.LayoutInflater; |
@@ -30,8 +32,12 @@ import android.view.View; | ||
30 | 32 | import android.view.ViewGroup; |
31 | 33 | import android.view.View.OnClickListener; |
32 | 34 | import android.widget.ImageView; |
35 | +import android.view.Window; | |
36 | +import android.view.WindowManager; | |
33 | 37 | |
34 | 38 | public class ContentFragment extends Fragment { |
39 | + // The bitmap currently used by ImageView | |
40 | + private Bitmap mBitmap = null; | |
35 | 41 | |
36 | 42 | @Override |
37 | 43 | public void onActivityCreated(Bundle savedInstanceState) { |
@@ -48,9 +54,16 @@ public class ContentFragment extends Fragment { | ||
48 | 54 | view.setOnDragListener(new View.OnDragListener() { |
49 | 55 | public boolean onDrag(View v, DragEvent event) { |
50 | 56 | switch (event.getAction()) { |
57 | + case DragEvent.ACTION_DRAG_ENTERED: | |
58 | + view.setBackgroundColor(Color.LTGRAY); | |
59 | + break; | |
60 | + case DragEvent.ACTION_DRAG_EXITED: | |
61 | + view.setBackgroundColor(Color.TRANSPARENT); | |
62 | + break; | |
51 | 63 | case DragEvent.ACTION_DRAG_STARTED: |
52 | 64 | return processDragStarted(event); |
53 | 65 | case DragEvent.ACTION_DROP: |
66 | + view.setBackgroundColor(Color.TRANSPARENT); | |
54 | 67 | return processDrop(event, imageView); |
55 | 68 | } |
56 | 69 | return false; |
@@ -59,10 +72,9 @@ public class ContentFragment extends Fragment { | ||
59 | 72 | |
60 | 73 | view.setOnClickListener(new OnClickListener() { |
61 | 74 | |
62 | - @Override | |
75 | + | |
63 | 76 | public void onClick(View v) { |
64 | - ActionBar bar = ContentFragment.this.getActivity() | |
65 | - .getActionBar(); | |
77 | + ActionBar bar = getActivity().getActionBar(); | |
66 | 78 | if (bar != null) { |
67 | 79 | if (bar.isShowing()) { |
68 | 80 | bar.hide(); |
@@ -85,7 +97,7 @@ public class ContentFragment extends Fragment { | ||
85 | 97 | return false; |
86 | 98 | } |
87 | 99 | |
88 | - boolean processDrop(DragEvent event, ImageView imageView) { | |
100 | + private boolean processDrop(DragEvent event, ImageView imageView) { | |
89 | 101 | // Attempt to parse clip data with expected format: category||entry_id. |
90 | 102 | // Ignore event if data does not conform to this format. |
91 | 103 | ClipData data = event.getClipData(); |
@@ -106,14 +118,28 @@ public class ContentFragment extends Fragment { | ||
106 | 118 | } catch (NumberFormatException exception) { |
107 | 119 | return false; |
108 | 120 | } |
109 | - imageView.setImageBitmap( | |
110 | - Directory.getCategory(category) | |
111 | - .getEntry(entryId) | |
112 | - .getBitmap(getResources())); | |
121 | + updateContentAndRecycleBitmap(category, entryId); | |
122 | + // Update list fragment with selected entry. | |
123 | + TitlesFragment titlesFrag = (TitlesFragment) | |
124 | + getFragmentManager().findFragmentById(R.id.frag_title); | |
125 | + titlesFrag.selectPosition(entryId); | |
113 | 126 | return true; |
114 | 127 | } |
115 | 128 | } |
116 | 129 | } |
117 | 130 | return false; |
118 | 131 | } |
132 | + | |
133 | + public void updateContentAndRecycleBitmap(int category, int position) { | |
134 | + // Get the bitmap that needs to be drawn and update the ImageView | |
135 | + Bitmap next = Directory.getCategory(category).getEntry(position) | |
136 | + .getBitmap(getResources()); | |
137 | + ((ImageView) getView().findViewById(R.id.image)).setImageBitmap(next); | |
138 | + if (mBitmap != null) { | |
139 | + // This is an advanced call and should be used if you | |
140 | + // are working with a lot of bitmaps. The bitmap is dead | |
141 | + // after this call. | |
142 | + mBitmap.recycle(); | |
143 | + } | |
144 | + } | |
119 | 145 | } |
@@ -17,13 +17,13 @@ | ||
17 | 17 | package com.example.android.hcgallery; |
18 | 18 | |
19 | 19 | public class Directory { |
20 | - private static DirectoryCategory[] categories; | |
20 | + private static DirectoryCategory[] mCategories; | |
21 | 21 | |
22 | 22 | public static void initializeDirectory() { |
23 | - categories = new DirectoryCategory[] { | |
23 | + mCategories = new DirectoryCategory[] { | |
24 | 24 | new DirectoryCategory("Balloons", new DirectoryEntry[] { |
25 | - new DirectoryEntry("Green Balloon", R.drawable.green_balloon), | |
26 | 25 | new DirectoryEntry("Red Balloon", R.drawable.red_balloon), |
26 | + new DirectoryEntry("Green Balloon", R.drawable.green_balloon), | |
27 | 27 | new DirectoryEntry("Blue Balloon", R.drawable.blue_balloon)}), |
28 | 28 | new DirectoryCategory("Bikes", new DirectoryEntry[] { |
29 | 29 | new DirectoryEntry("Old school huffy", R.drawable.blue_bike), |
@@ -42,10 +42,10 @@ public class Directory { | ||
42 | 42 | } |
43 | 43 | |
44 | 44 | public static int getCategoryCount() { |
45 | - return categories.length; | |
45 | + return mCategories.length; | |
46 | 46 | } |
47 | 47 | |
48 | 48 | public static DirectoryCategory getCategory(int i) { |
49 | - return categories[i]; | |
49 | + return mCategories[i]; | |
50 | 50 | } |
51 | 51 | } |
@@ -23,16 +23,22 @@ import android.animation.PropertyValuesHolder; | ||
23 | 23 | import android.animation.ValueAnimator; |
24 | 24 | import android.app.ActionBar; |
25 | 25 | import android.app.Activity; |
26 | +import android.app.AlertDialog; | |
27 | +import android.app.Dialog; | |
28 | +import android.app.DialogFragment; | |
26 | 29 | import android.app.FragmentManager; |
27 | 30 | import android.app.FragmentTransaction; |
31 | +import android.content.DialogInterface; | |
28 | 32 | import android.content.Intent; |
29 | 33 | import android.content.res.Configuration; |
34 | +import android.graphics.drawable.ColorDrawable; | |
30 | 35 | import android.os.Bundle; |
31 | 36 | import android.view.Menu; |
32 | 37 | import android.view.MenuInflater; |
33 | 38 | import android.view.MenuItem; |
34 | 39 | import android.view.View; |
35 | 40 | import android.view.ViewGroup; |
41 | +import android.view.Window; | |
36 | 42 | |
37 | 43 | public class MainActivity extends Activity implements ActionBar.TabListener { |
38 | 44 |
@@ -49,16 +55,27 @@ public class MainActivity extends Activity implements ActionBar.TabListener { | ||
49 | 55 | mThemeId = savedInstanceState.getInt("theme"); |
50 | 56 | this.setTheme(mThemeId); |
51 | 57 | } |
58 | + | |
59 | + requestWindowFeature(Window.FEATURE_ACTION_BAR_OVERLAY); | |
52 | 60 | setContentView(R.layout.main); |
53 | 61 | |
54 | 62 | Directory.initializeDirectory(); |
55 | 63 | |
56 | 64 | ActionBar bar = getActionBar(); |
57 | 65 | |
66 | + if (mThemeId == android.R.style.Theme_Holo_Light || mThemeId == -1) { | |
67 | + bar.setBackgroundDrawable( | |
68 | + new ColorDrawable(getResources().getColor(R.color.actionbar_background_light))); | |
69 | + } else { | |
70 | + bar.setBackgroundDrawable( | |
71 | + new ColorDrawable(getResources().getColor(R.color.actionbar_background_dark))); | |
72 | + } | |
73 | + | |
58 | 74 | int i; |
59 | - for (i = 0; i < Directory.getCategoryCount(); i++) | |
75 | + for (i = 0; i < Directory.getCategoryCount(); i++) { | |
60 | 76 | bar.addTab(bar.newTab().setText(Directory.getCategory(i).getName()) |
61 | 77 | .setTabListener(this)); |
78 | + } | |
62 | 79 | |
63 | 80 | mActionBarView = getLayoutInflater().inflate( |
64 | 81 | R.layout.action_bar_custom, null); |
@@ -108,6 +125,7 @@ public class MainActivity extends Activity implements ActionBar.TabListener { | ||
108 | 125 | case R.id.toggleTitles: |
109 | 126 | toggleVisibleTitles(); |
110 | 127 | return true; |
128 | + | |
111 | 129 | case R.id.toggleTheme: |
112 | 130 | if (mThemeId == android.R.style.Theme_Holo) { |
113 | 131 | mThemeId = android.R.style.Theme_Holo_Light; |
@@ -115,6 +133,12 @@ public class MainActivity extends Activity implements ActionBar.TabListener { | ||
115 | 133 | mThemeId = android.R.style.Theme_Holo; |
116 | 134 | } |
117 | 135 | this.recreate(); |
136 | + return true; | |
137 | + | |
138 | + case R.id.showDialog: | |
139 | + showDialog(); | |
140 | + return true; | |
141 | + | |
118 | 142 | default: |
119 | 143 | return super.onOptionsItemSelected(item); |
120 | 144 | } |
@@ -203,6 +227,19 @@ public class MainActivity extends Activity implements ActionBar.TabListener { | ||
203 | 227 | invalidateOptionsMenu(); |
204 | 228 | } |
205 | 229 | |
230 | + void showDialog() { | |
231 | + | |
232 | + // DialogFragment.show() will take care of adding the fragment | |
233 | + // in a transaction. We also want to remove any currently showing | |
234 | + // dialog, so make our own transaction and take care of that here. | |
235 | + FragmentTransaction ft = getFragmentManager().beginTransaction(); | |
236 | + | |
237 | + DialogFragment newFragment = MyDialogFragment.newInstance("The Dialog Of Awesome"); | |
238 | + | |
239 | + // Create and show the dialog. | |
240 | + newFragment.show(ft, "dialog"); | |
241 | + } | |
242 | + | |
206 | 243 | @Override |
207 | 244 | public boolean onPrepareOptionsMenu(Menu menu) { |
208 | 245 | menu.getItem(1).setTitle(mToggleLabels[mLabelIndex]); |
@@ -217,4 +254,37 @@ public class MainActivity extends Activity implements ActionBar.TabListener { | ||
217 | 254 | outState.putInt("category", category); |
218 | 255 | outState.putInt("theme", mThemeId); |
219 | 256 | } |
257 | + | |
258 | + | |
259 | + public static class MyDialogFragment extends DialogFragment { | |
260 | + | |
261 | + public static MyDialogFragment newInstance(String title) { | |
262 | + MyDialogFragment frag = new MyDialogFragment(); | |
263 | + Bundle args = new Bundle(); | |
264 | + args.putString("title", title); | |
265 | + frag.setArguments(args); | |
266 | + return frag; | |
267 | + } | |
268 | + | |
269 | + @Override | |
270 | + public Dialog onCreateDialog(Bundle savedInstanceState) { | |
271 | + String title = getArguments().getString("title"); | |
272 | + | |
273 | + return new AlertDialog.Builder(getActivity()) | |
274 | + .setTitle(title) | |
275 | + .setPositiveButton("OK", | |
276 | + new DialogInterface.OnClickListener() { | |
277 | + public void onClick(DialogInterface dialog, int whichButton) { | |
278 | + } | |
279 | + } | |
280 | + ) | |
281 | + .setNegativeButton("Cancel", | |
282 | + new DialogInterface.OnClickListener() { | |
283 | + public void onClick(DialogInterface dialog, int whichButton) { | |
284 | + } | |
285 | + } | |
286 | + ) | |
287 | + .create(); | |
288 | + } | |
289 | + } | |
220 | 290 | } |
@@ -16,14 +16,18 @@ | ||
16 | 16 | |
17 | 17 | package com.example.android.hcgallery; |
18 | 18 | |
19 | +import android.app.Fragment; | |
20 | +import android.app.FragmentManager; | |
19 | 21 | import android.app.ListFragment; |
20 | 22 | import android.content.ClipData; |
21 | -import android.graphics.BitmapFactory; | |
22 | 23 | import android.graphics.Canvas; |
23 | 24 | import android.graphics.Color; |
24 | 25 | import android.graphics.drawable.ColorDrawable; |
25 | 26 | import android.graphics.drawable.Drawable; |
27 | +import android.graphics.Paint; | |
28 | +import android.graphics.Typeface; | |
26 | 29 | import android.os.Bundle; |
30 | +import android.text.TextPaint; | |
27 | 31 | import android.view.View; |
28 | 32 | import android.widget.AdapterView; |
29 | 33 | import android.widget.ArrayAdapter; |
@@ -51,10 +55,8 @@ public class TitlesFragment extends ListFragment { | ||
51 | 55 | lv.setChoiceMode(ListView.CHOICE_MODE_SINGLE); |
52 | 56 | selectPosition(mCurPosition); |
53 | 57 | lv.setCacheColorHint(Color.WHITE); |
54 | - | |
55 | 58 | lv.setOnItemLongClickListener(new OnItemLongClickListener() { |
56 | 59 | |
57 | - @Override | |
58 | 60 | public boolean onItemLongClick(AdapterView<?> av, View v, int pos, |
59 | 61 | long id) { |
60 | 62 | final String title = (String) ((TextView) v).getText(); |
@@ -62,24 +64,36 @@ public class TitlesFragment extends ListFragment { | ||
62 | 64 | // Set up clip data with the category||entry_id format. |
63 | 65 | final String textData = String.format("%d||%d", mCategory, pos); |
64 | 66 | ClipData data = ClipData.newPlainText(title, textData); |
65 | - v.startDrag(data, new MyDragShadowBuilder(v), null, 0); | |
67 | + | |
68 | + v.startDrag(data, new MyDragShadowBuilder(v, title), null, 0); | |
66 | 69 | return true; |
67 | 70 | } |
68 | 71 | }); |
69 | 72 | } |
70 | 73 | |
71 | 74 | private static class MyDragShadowBuilder extends View.DragShadowBuilder { |
72 | - private static Drawable shadow; | |
73 | - | |
74 | - public MyDragShadowBuilder(View v) { | |
75 | + private static Drawable mShadow; | |
76 | + private static String mLabel; | |
77 | + private static int mViewHeight; | |
78 | + | |
79 | + public MyDragShadowBuilder(View v, String label) { | |
75 | 80 | super(v); |
76 | - shadow = new ColorDrawable(Color.BLUE); | |
77 | - shadow.setBounds(0, 0, v.getWidth(), v.getHeight()); | |
81 | + mShadow = new ColorDrawable(Color.BLUE); | |
82 | + mShadow.setBounds(0, 0, v.getWidth(), v.getHeight()); | |
83 | + mLabel = label; | |
84 | + mViewHeight = v.getHeight(); | |
78 | 85 | } |
79 | 86 | |
80 | 87 | @Override |
81 | 88 | public void onDrawShadow(Canvas canvas) { |
82 | - shadow.draw(canvas); | |
89 | + super.onDrawShadow(canvas); | |
90 | + mShadow.draw(canvas); | |
91 | + Paint paint = new TextPaint(); | |
92 | + paint.setTextSize(20); | |
93 | + paint.setColor(Color.LTGRAY); | |
94 | + paint.setTypeface(Typeface.DEFAULT_BOLD); | |
95 | + paint.setAntiAlias(true); | |
96 | + canvas.drawText(mLabel, 20, (float) (mViewHeight * .6), paint); | |
83 | 97 | } |
84 | 98 | } |
85 | 99 |
@@ -99,11 +113,9 @@ public class TitlesFragment extends ListFragment { | ||
99 | 113 | } |
100 | 114 | |
101 | 115 | private void updateImage(int position) { |
102 | - ImageView iv = (ImageView) getFragmentManager().findFragmentById( | |
103 | - R.id.frag_content).getView().findViewById(R.id.image); | |
104 | - iv.setImageDrawable(Directory.getCategory(mCategory).getEntry(position) | |
105 | - .getDrawable(getResources())); | |
106 | - mCurPosition = position; | |
116 | + ContentFragment frag = (ContentFragment) getFragmentManager() | |
117 | + .findFragmentById(R.id.frag_content); | |
118 | + frag.updateContentAndRecycleBitmap(mCategory, position); | |
107 | 119 | } |
108 | 120 | |
109 | 121 | public void selectPosition(int position) { |