summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/FragmentManager.java93
-rw-r--r--docs/html/develop/index.jd1
-rw-r--r--docs/html/guide/topics/ui/declaring-layout.jd26
-rw-r--r--docs/html/guide/topics/ui/layout/gridview.jd5
-rw-r--r--docs/html/guide/topics/ui/layout/listview.jd6
-rw-r--r--libs/hwui/FontRenderer.cpp11
-rw-r--r--libs/hwui/OpenGLRenderer.cpp1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java20
9 files changed, 170 insertions, 39 deletions
diff --git a/core/java/android/app/FragmentManager.java b/core/java/android/app/FragmentManager.java
index c9e092c61352..c1e11bbec86c 100644
--- a/core/java/android/app/FragmentManager.java
+++ b/core/java/android/app/FragmentManager.java
@@ -20,6 +20,7 @@ import android.animation.Animator;
import android.animation.AnimatorInflater;
import android.animation.AnimatorListenerAdapter;
import android.content.res.Configuration;
+import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.os.Handler;
@@ -427,6 +428,94 @@ final class FragmentManagerImpl extends FragmentManager {
}
};
+ private void logViewHierarchy(String prefix, View view) {
+ StringBuilder builder = new StringBuilder(128);
+ builder.append(prefix);
+ DebugUtils.buildShortClassTag(view, builder);
+ int id = view.getId();
+ if (id != -1) {
+ builder.append(" #");
+ builder.append(Integer.toHexString(id));
+ if (id != 0 && id != -1) {
+ try {
+ String pkgname;
+ switch (id&0xff000000) {
+ case 0x7f000000:
+ pkgname="app";
+ break;
+ case 0x01000000:
+ pkgname="android";
+ break;
+ default:
+ pkgname = view.getResources().getResourcePackageName(id);
+ break;
+ }
+ String typename = view.getResources().getResourceTypeName(id);
+ String entryname = view.getResources().getResourceEntryName(id);
+ builder.append(" (");
+ builder.append(pkgname);
+ builder.append(":");
+ builder.append(typename);
+ builder.append("/");
+ builder.append(entryname);
+ builder.append(")");
+ } catch (Resources.NotFoundException e) {
+ }
+ }
+ }
+ Object tag = view.getTag();
+ if (tag != null) {
+ builder.append(" ");
+ builder.append(tag);
+ }
+ builder.append("}");
+ Log.e(TAG, builder.toString());
+
+ if (!(view instanceof ViewGroup)) {
+ return;
+ }
+ ViewGroup grp = (ViewGroup)view;
+ final int N = grp.getChildCount();
+ if (N <= 0) {
+ return;
+ }
+ prefix = prefix + " ";
+ for (int i=0; i<N; i++) {
+ logViewHierarchy(prefix, grp.getChildAt(i));
+ }
+ }
+
+ private void throwNoViewFound(Fragment f) {
+ String msg = "No view found for id 0x"
+ + Integer.toHexString(f.mContainerId) + " ("
+ + f.getResources().getResourceName(f.mContainerId)
+ + ") for fragment " + f;
+ Log.e(TAG, msg);
+ Log.e(TAG, "Activity state:");
+ if (f.getActivity() != null) {
+ try {
+ LogWriter logw = new LogWriter(Log.ERROR, TAG);
+ PrintWriter pw = new PrintWriter(logw);
+ f.getActivity().dump(" ", null, pw, new String[] { });
+ } catch (Exception e) {
+ Log.e(TAG, "Failed dumping state", e);
+ }
+ } else {
+ Log.e(TAG, " NULL ACTIVITY!");
+ }
+ Log.e(TAG, "View hierarchy:");
+ if (f.getActivity() != null) {
+ try {
+ logViewHierarchy(" ", f.getActivity().getWindow().getDecorView());
+ } catch (Exception e) {
+ Log.e(TAG, "Failed dumping view hierarchy", e);
+ }
+ } else {
+ Log.e(TAG, " NULL ACTIVITY!");
+ }
+ throw new IllegalArgumentException(msg);
+ }
+
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
@@ -824,9 +913,7 @@ final class FragmentManagerImpl extends FragmentManager {
if (f.mContainerId != 0) {
container = (ViewGroup)mActivity.findViewById(f.mContainerId);
if (container == null && !f.mRestored) {
- throw new IllegalArgumentException("No view found for id 0x"
- + Integer.toHexString(f.mContainerId)
- + " for fragment " + f);
+ throwNoViewFound(f);
}
}
f.mContainer = container;
diff --git a/docs/html/develop/index.jd b/docs/html/develop/index.jd
index eaa70e21dcae..14ab5d587534 100644
--- a/docs/html/develop/index.jd
+++ b/docs/html/develop/index.jd
@@ -180,7 +180,6 @@ a').click();return false;">Watch the latest review</a></p>
</div>
<br class="clearfix"/>
- </div>
diff --git a/docs/html/guide/topics/ui/declaring-layout.jd b/docs/html/guide/topics/ui/declaring-layout.jd
index e971a752c4e4..e229f237936b 100644
--- a/docs/html/guide/topics/ui/declaring-layout.jd
+++ b/docs/html/guide/topics/ui/declaring-layout.jd
@@ -32,12 +32,17 @@ parent.link=index.html
<li>{@link android.view.ViewGroup}</li>
<li>{@link android.view.ViewGroup.LayoutParams}</li>
</ol>
-</div>
+
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}training/basics/firstapp/building-ui.html">Building a Simple User
+Interface</a></li> </div>
</div>
-<p>Your layout is the architecture for the user interface in an Activity.
-It defines the layout structure and holds all the elements that appear to the user.
-You can declare your layout in two ways:</p>
+<p>A layout defines the visual structure for a user interface, such as the UI for an <a
+href="{@docRoot}guide/components/activities.html">activity</a> or <a
+href="{@docRoot}guide/topics/appwidgets/index.html">app widget</a>.
+You can declare a layout in two ways:</p>
<ul>
<li><strong>Declare UI elements in XML</strong>. Android provides a straightforward XML
vocabulary that corresponds to the View classes and subclasses, such as those for widgets and layouts.</li>
@@ -77,16 +82,6 @@ Layout Objects</a>. There are also a collection of tutorials on building various
<h2 id="write">Write the XML</h2>
-<div class="sidebox-wrapper">
-<div class="sidebox">
-<p>For your convenience, the API reference documentation for UI related classes
-lists the available XML attributes that correspond to the class methods, including inherited
-attributes.</p>
-<p>To learn more about the available XML elements and attributes, as well as the format of the XML file, see <a
-href="{@docRoot}guide/topics/resources/available-resources.html#layoutresources">Layout Resources</a>.</p>
-</div>
-</div>
-
<p>Using Android's XML vocabulary, you can quickly design UI layouts and the screen elements they contain, in the same way you create web pages in HTML &mdash; with a series of nested elements. </p>
<p>Each layout file must contain exactly one root element, which must be a View or ViewGroup object. Once you've defined the root element, you can add additional layout objects or widgets as child elements to gradually build a View hierarchy that defines your layout. For example, here's an XML layout that uses a vertical {@link android.widget.LinearLayout}
@@ -111,7 +106,8 @@ to hold a {@link android.widget.TextView} and a {@link android.widget.Button}:</
<p>After you've declared your layout in XML, save the file with the <code>.xml</code> extension,
in your Android project's <code>res/layout/</code> directory, so it will properly compile. </p>
-<p>We'll discuss each of the attributes shown here a little later.</p>
+<p>More information about the syntax for a layout XML file is available in the <a
+href="{@docRoot}guide/topics/resources/layout-resource.html">Layout Resources</a> document.</p>
<h2 id="load">Load the XML Resource</h2>
diff --git a/docs/html/guide/topics/ui/layout/gridview.jd b/docs/html/guide/topics/ui/layout/gridview.jd
index 11c54740d631..67bdd0f080cf 100644
--- a/docs/html/guide/topics/ui/layout/gridview.jd
+++ b/docs/html/guide/topics/ui/layout/gridview.jd
@@ -22,10 +22,15 @@ two-dimensional,
scrollable grid. The grid items are automatically inserted to the layout using a {@link
android.widget.ListAdapter}.</p>
+<p>For an introduction to how you can dynamically insert views using an adapter, read
+<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts with
+ an Adapter</a>.</p>
+
<img src="{@docRoot}images/ui/gridview.png" alt="" />
<h2 id="example">Example</h2>
+
<p>In this tutorial, you'll create a grid of image thumbnails. When an item is selected, a
toast message will display the position of the image.</p>
diff --git a/docs/html/guide/topics/ui/layout/listview.jd b/docs/html/guide/topics/ui/layout/listview.jd
index 26a75979988d..fee52927e846 100644
--- a/docs/html/guide/topics/ui/layout/listview.jd
+++ b/docs/html/guide/topics/ui/layout/listview.jd
@@ -28,6 +28,10 @@ scrollable items. The list items are automatically inserted to the list using an
android.widget.Adapter} that pulls content from a source such as an array or database query and
converts each item result into a view that's placed into the list.</p>
+<p>For an introduction to how you can dynamically insert views using an adapter, read
+<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Building Layouts with
+ an Adapter</a>.</p>
+
<img src="{@docRoot}images/ui/listview.png" alt="" />
<h2 id="Loader">Using a Loader</h2>
@@ -147,5 +151,5 @@ href="{@docRoot}guide/topics/providers/contacts-provider.html">Contacts
Provider</a>, if you want to
try this code, your app must request the {@link android.Manifest.permission#READ_CONTACTS}
permission in the manifest file:<br/>
-<code>&lt;uses-permission android:name="android.permission.READ_CONTACTS" /></p>
+<code>&lt;uses-permission android:name="android.permission.READ_CONTACTS" /></code></p>
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index a596fa946467..b352ffc538ae 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -699,7 +699,6 @@ void FontRenderer::flushAllAndInvalidate() {
}
#if DEBUG_FONT_RENDERER
- ALOGD("FontRenderer: flushAllAndInvalidatel");
// Erase caches, just as a debugging facility
if (mCacheTextureSmall && mCacheTextureSmall->mTexture) {
memset(mCacheTextureSmall->mTexture, 0,
@@ -792,14 +791,12 @@ void FontRenderer::allocateTextureMemory(CacheTexture* cacheTexture) {
void FontRenderer::cacheBitmap(const SkGlyph& glyph, CachedGlyphInfo* cachedGlyph,
uint32_t* retOriginX, uint32_t* retOriginY) {
+ checkInit();
cachedGlyph->mIsValid = false;
// If the glyph is too tall, don't cache it
- if (mCacheLines.size() == 0 ||
- glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
- if (mCacheLines.size() != 0) {
- ALOGE("Font size too large to fit in cache. width, height = %i, %i",
- (int) glyph.fWidth, (int) glyph.fHeight);
- }
+ if (glyph.fHeight + TEXTURE_BORDER_SIZE * 2 > mCacheLines[mCacheLines.size() - 1]->mMaxHeight) {
+ ALOGE("Font size too large to fit in cache. width, height = %i, %i",
+ (int) glyph.fWidth, (int) glyph.fHeight);
return;
}
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 663923197f84..849c5563c4da 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -250,6 +250,7 @@ void OpenGLRenderer::resume() {
glViewport(0, 0, snapshot->viewport.getWidth(), snapshot->viewport.getHeight());
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+ mCaches.scissorEnabled = glIsEnabled(GL_SCISSOR_TEST);
mCaches.enableScissor();
mCaches.resetScissor();
dirtyClip();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 83cabfb13d68..f44c5007425c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -19,6 +19,16 @@ public class PanelBar extends FrameLayout {
private PanelHolder mPanelHolder;
private ArrayList<PanelView> mPanels = new ArrayList<PanelView>();
protected PanelView mTouchingPanel;
+ private static final int STATE_CLOSED = 0;
+ private static final int STATE_TRANSITIONING = 1;
+ private static final int STATE_OPEN = 2;
+ private int mState = STATE_CLOSED;
+ private boolean mTracking;
+
+ private void go(int state) {
+ LOG("go state: %d -> %d", mState, state);
+ mState = state;
+ }
public PanelBar(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -62,8 +72,11 @@ public class PanelBar extends FrameLayout {
final int i = (int)(N * event.getX() / getMeasuredWidth());
mTouchingPanel = mPanels.get(i);
mPanelHolder.setSelectedPanel(mTouchingPanel);
- LOG("PanelBar.onTouch: ACTION_DOWN: panel %d", i);
- onPanelPeeked();
+ LOG("PanelBar.onTouch: state=%d ACTION_DOWN: panel %d", mState, i);
+ if (mState == STATE_CLOSED || mState == STATE_OPEN) {
+ go(STATE_TRANSITIONING);
+ onPanelPeeked();
+ }
}
final boolean result = mTouchingPanel.getHandle().dispatchTouchEvent(event);
return result;
@@ -72,11 +85,13 @@ public class PanelBar extends FrameLayout {
public void panelExpansionChanged(PanelView panel, float frac) {
boolean fullyClosed = true;
PanelView fullyOpenedPanel = null;
+ LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
for (PanelView pv : mPanels) {
+ // adjust any other panels that may be partially visible
if (pv.getExpandedHeight() > 0f) {
fullyClosed = false;
final float thisFrac = pv.getExpandedFraction();
- LOG("panel %s: f=%.1f", pv, thisFrac);
+ LOG("panelExpansionChanged: -> %s: f=%.1f", pv.getName(), thisFrac);
if (panel == pv) {
if (thisFrac == 1f) fullyOpenedPanel = panel;
} else {
@@ -84,11 +99,15 @@ public class PanelBar extends FrameLayout {
}
}
}
- if (fullyOpenedPanel != null) onPanelFullyOpened(fullyOpenedPanel);
- if (fullyClosed) onAllPanelsCollapsed();
- else onPanelPeeked();
+ if (fullyOpenedPanel != null && !mTracking) {
+ go(STATE_OPEN);
+ onPanelFullyOpened(fullyOpenedPanel);
+ } else if (fullyClosed && !mTracking) {
+ go(STATE_CLOSED);
+ onAllPanelsCollapsed();
+ }
- LOG("panelExpansionChanged: [%s%s ]",
+ LOG("panelExpansionChanged: end state=%d [%s%s ]", mState,
(fullyOpenedPanel!=null)?" fullyOpened":"", fullyClosed?" fullyClosed":"");
}
@@ -113,4 +132,17 @@ public class PanelBar extends FrameLayout {
public void onPanelFullyOpened(PanelView openPanel) {
LOG("onPanelFullyOpened");
}
+
+ public void onTrackingStarted(PanelView panel) {
+ mTracking = true;
+ if (panel != mTouchingPanel) {
+ LOG("shouldn't happen: onTrackingStarted(%s) != mTouchingPanel(%s)",
+ panel, mTouchingPanel);
+ }
+ }
+
+ public void onTrackingStopped(PanelView panel) {
+ mTracking = false;
+ panelExpansionChanged(panel, panel.getExpandedFraction());
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index fa97299f1798..b5a50c68ae0e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -16,9 +16,9 @@ import com.android.systemui.R;
public class PanelView extends FrameLayout {
public static final boolean DEBUG = false;
public static final String TAG = PanelView.class.getSimpleName();
- public static final void LOG(String fmt, Object... args) {
+ public final void LOG(String fmt, Object... args) {
if (!DEBUG) return;
- Log.v(TAG, String.format(fmt, args));
+ Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
}
public static final boolean BRAKES = false;
@@ -61,6 +61,7 @@ public class PanelView extends FrameLayout {
private float mVel, mAccel;
private int mFullHeight = 0;
+ private String mViewName;
private void animationTick(long dtms) {
if (!mTimeAnimator.isStarted()) {
@@ -69,7 +70,7 @@ public class PanelView extends FrameLayout {
mTimeAnimator.setTimeListener(mAnimationCallback);
mTimeAnimator.start();
- } else {
+ } else if (dtms > 0) {
final float dt = dtms * 0.001f; // ms -> s
LOG("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);
LOG("tick: before: h=%d", (int) mExpandedHeight);
@@ -170,13 +171,16 @@ public class PanelView extends FrameLayout {
public boolean onTouch(View v, MotionEvent event) {
final float y = event.getY();
final float rawY = event.getRawY();
- LOG("handle.onTouch: y=%.1f rawY=%.1f off=%.1f", y, rawY, mTouchOffset);
+ LOG("handle.onTouch: a=%s y=%.1f rawY=%.1f off=%.1f",
+ MotionEvent.actionToString(event.getAction()),
+ y, rawY, mTouchOffset);
PanelView.this.getLocationOnScreen(mAbsPos);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mVelocityTracker = VelocityTracker.obtain();
trackMovement(event);
+ mBar.onTrackingStarted(PanelView.this);
mTouchOffset = (rawY - mAbsPos[1]) - PanelView.this.getExpandedHeight();
break;
@@ -190,6 +194,7 @@ public class PanelView extends FrameLayout {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
+ mBar.onTrackingStopped(PanelView.this);
trackMovement(event);
mVelocityTracker.computeCurrentVelocity(1000);
@@ -241,6 +246,11 @@ public class PanelView extends FrameLayout {
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
+ mViewName = getResources().getResourceName(getId());
+ }
+
+ public String getName() {
+ return mViewName;
}
@Override
@@ -278,7 +288,7 @@ public class PanelView extends FrameLayout {
}
LOG("setExpansion: height=%.1f fh=%.1f", h, fh);
-
+
if (h < 0) h = 0;
else if (h > fh) h = fh;