Add prebuilt browseable samples as static files.
Change-Id: Ifb5382223343400882834d2dd9c182c3df602e34
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.basicaccessibility;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.os.Build;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.view.accessibility.AccessibilityEvent;
|
||||
|
||||
/**
|
||||
* Custom view to demonstrate accessibility.
|
||||
*
|
||||
* <p>This view does not use any framework widgets, so does not get any accessibility features
|
||||
* automatically. Instead, we use {@link android.view.accessibility.AccessibilityEvent} to provide accessibility hints to
|
||||
* the OS.
|
||||
*
|
||||
* <p>For example, if TalkBack is enabled, users will be able to receive spoken feedback as they
|
||||
* interact with this view.
|
||||
*
|
||||
* <p>More generally, this view renders a multi-position "dial" that can be used to select a value
|
||||
* between 1 and 4. Each time the dial is clicked, the next position will be selected (modulo
|
||||
* the maximum number of positions).
|
||||
*/
|
||||
public class DialView extends View {
|
||||
private static int SELECTION_COUNT = 4;
|
||||
|
||||
private static float FONT_SIZE = 40f;
|
||||
private float mWidth;
|
||||
private float mHeight;
|
||||
private float mWidthPadded;
|
||||
private float mHeightPadded;
|
||||
private Paint mTextPaint;
|
||||
private Paint mDialPaint;
|
||||
private float mRadius;
|
||||
private int mActiveSelection;
|
||||
|
||||
/**
|
||||
* Constructor that is called when inflating a view from XML. This is called
|
||||
* when a view is being constructed from an XML file, supplying attributes
|
||||
* that were specified in the XML file.
|
||||
*
|
||||
* <p>In our case, this constructor just calls init().
|
||||
*
|
||||
* @param context The Context the view is running in, through which it can
|
||||
* access the current theme, resources, etc.
|
||||
* @param attrs The attributes of the XML tag that is inflating the view.
|
||||
* @see #View(android.content.Context, android.util.AttributeSet, int)
|
||||
*/
|
||||
public DialView(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to initialize instance variables. Called by constructor.
|
||||
*/
|
||||
private void init() {
|
||||
// Paint styles used for rendering are created here, rather than at render-time. This
|
||||
// is a performance optimization, since onDraw() will get called frequently.
|
||||
mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mTextPaint.setColor(Color.BLACK);
|
||||
mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);
|
||||
mTextPaint.setTextAlign(Paint.Align.CENTER);
|
||||
mTextPaint.setTextSize(FONT_SIZE);
|
||||
|
||||
mDialPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
mDialPaint.setColor(Color.GRAY);
|
||||
|
||||
// Initialize current selection. This will store where the dial's "indicator" is pointing.
|
||||
mActiveSelection = 0;
|
||||
|
||||
// Setup onClick listener for this view. Rotates between each of the different selection
|
||||
// states on each click.
|
||||
//
|
||||
// Notice that we call sendAccessibilityEvent here. Some AccessibilityEvents are generated
|
||||
// by the system. However, custom views will typically need to send events manually as the
|
||||
// user interacts with the view. The type of event sent will vary, depending on the nature
|
||||
// of the view and how the user interacts with it.
|
||||
//
|
||||
// In this case, we are sending TYPE_VIEW_SELECTED rather than TYPE_VIEW_CLICKED, because
|
||||
// clicking on this view selects a new value.
|
||||
//
|
||||
// We will give our AccessibilityEvent further information about the state of the view in
|
||||
// onPopulateAccessibilityEvent(), which will be called automatically by the system
|
||||
// for each AccessibilityEvent.
|
||||
setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
// Rotate selection to the next valid choice.
|
||||
mActiveSelection = (mActiveSelection + 1) % SELECTION_COUNT;
|
||||
// Send an AccessibilityEvent, since the user has interacted with the view.
|
||||
sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
|
||||
// Redraw the entire view. (Inefficient, but this is sufficient for demonstration
|
||||
// purposes.)
|
||||
invalidate();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where a View should populate outgoing accessibility events with its text content.
|
||||
* While this method is free to modify event attributes other than text content, doing so
|
||||
* should normally be performed in
|
||||
* {@link #onInitializeAccessibilityEvent(android.view.accessibility.AccessibilityEvent)}.
|
||||
* <p/>
|
||||
* <p>Note that the behavior of this method will typically vary, depending on the type of
|
||||
* accessibility event is passed into it. The allowed values also very, and are documented
|
||||
* in {@link android.view.accessibility.AccessibilityEvent}.
|
||||
* <p/>
|
||||
* <p>Typically, this is where you'll describe the state of your custom view. You may also
|
||||
* want to provide custom directions when the user has focused your view.
|
||||
*
|
||||
* @param event The accessibility event which to populate.
|
||||
*/
|
||||
// BEGIN_INCLUDE (on_populate_accessibility_event)
|
||||
@Override
|
||||
@TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
|
||||
public void onPopulateAccessibilityEvent(AccessibilityEvent event) {
|
||||
super.onPopulateAccessibilityEvent(event);
|
||||
|
||||
// Detect what type of accessibility event is being passed in.
|
||||
int eventType = event.getEventType();
|
||||
|
||||
// Common case: The user has interacted with our view in some way. State may or may not
|
||||
// have been changed. Read out the current status of the view.
|
||||
//
|
||||
// We also set some other metadata which is not used by TalkBack, but could be used by
|
||||
// other TTS engines.
|
||||
if (eventType == AccessibilityEvent.TYPE_VIEW_SELECTED ||
|
||||
eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
|
||||
event.getText().add("Mode selected: " + Integer.toString(mActiveSelection + 1) + ".");
|
||||
event.setItemCount(SELECTION_COUNT);
|
||||
event.setCurrentItemIndex(mActiveSelection);
|
||||
}
|
||||
|
||||
// When a user first focuses on our view, we'll also read out some simple instructions to
|
||||
// make it clear that this is an interactive element.
|
||||
if (eventType == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
|
||||
event.getText().add("Tap to change.");
|
||||
}
|
||||
}
|
||||
// END_INCLUDE (on_populate_accessibility_event)
|
||||
|
||||
/**
|
||||
* This is called during layout when the size of this view has changed. If
|
||||
* you were just added to the view hierarchy, you're called with the old
|
||||
* values of 0.
|
||||
*
|
||||
* <p>This is where we determine the drawing bounds for our custom view.
|
||||
*
|
||||
* @param w Current width of this view.
|
||||
* @param h Current height of this view.
|
||||
* @param oldw Old width of this view.
|
||||
* @param oldh Old height of this view.
|
||||
*/
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
// Account for padding
|
||||
float xPadding = (float) (getPaddingLeft() + getPaddingRight());
|
||||
float yPadding = (float) (getPaddingTop() + getPaddingBottom());
|
||||
|
||||
// Compute available width/height
|
||||
mWidth = w;
|
||||
mHeight = h;
|
||||
mWidthPadded = w - xPadding;
|
||||
mHeightPadded = h - yPadding;
|
||||
mRadius = (float) (Math.min(mWidth, mHeight) / 2 * 0.8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render view content.
|
||||
*
|
||||
* <p>We render an outer grey circle to serve as our "dial", and then render a smaller black
|
||||
* circle to server as our indicator. The position for the indicator is determined based
|
||||
* on mActiveSelection.
|
||||
*
|
||||
* @param canvas the canvas on which the background will be drawn
|
||||
*/
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
// Draw dial
|
||||
canvas.drawCircle(mWidth / 2, mHeight / 2, (float) mRadius, mDialPaint);
|
||||
|
||||
// Draw text labels
|
||||
final float labelRadius = mRadius + 10;
|
||||
for (int i = 0; i < SELECTION_COUNT; i++) {
|
||||
float[] xyData = computeXYForPosition(i, labelRadius);
|
||||
float x = xyData[0];
|
||||
float y = xyData[1];
|
||||
canvas.drawText(Integer.toString(i + 1), x, y, mTextPaint);
|
||||
}
|
||||
|
||||
// Draw indicator mark
|
||||
final float markerRadius = mRadius - 35;
|
||||
float[] xyData = computeXYForPosition(mActiveSelection, markerRadius);
|
||||
float x = xyData[0];
|
||||
float y = xyData[1];
|
||||
canvas.drawCircle(x, y, 20, mTextPaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compute the X/Y-coordinates for a label or indicator, given the position number and radius
|
||||
* where the label should be drawn.
|
||||
*
|
||||
* @param pos Zero based position index
|
||||
* @param radius Radius where label/indicator is to be drawn.
|
||||
* @return 2-element array. Element 0 is X-coordinate, element 1 is Y-coordinate.
|
||||
*/
|
||||
private float[] computeXYForPosition(final int pos, final float radius) {
|
||||
float[] result = new float[2];
|
||||
Double startAngle = Math.PI * (9 / 8d); // Angles are in radiansq
|
||||
Double angle = startAngle + (pos * (Math.PI / 4));
|
||||
result[0] = (float) (radius * Math.cos(angle)) + (mWidth / 2);
|
||||
result[1] = (float) (radius * Math.sin(angle)) + (mHeight / 2);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (C) 2013 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.basicaccessibility;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
||||
/**
|
||||
* Basic activity class.
|
||||
*
|
||||
* <p>Responsible for rendering layout, and displaying some toasts to give buttons feedback.
|
||||
* There's nothing terribly interesting in this class. All the interesting stuff is in
|
||||
* res/layout/activity_main.xml and {@link DialView}.
|
||||
*/
|
||||
public class MainActivity extends Activity {
|
||||
|
||||
/**
|
||||
* Standard onCreate() implementation. Sets R.layout.activity_main as the layout.
|
||||
*/
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.sample_main);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user