Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small fixes to RoboDemo #8

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,5 @@ target/
#Maven release files
*.releaseBackup
*.versionsBackup
robodemo-lib/project.properties
robodemo-sample/project.properties
26 changes: 7 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@ RoboDemo
========

RoboDemo is a ShowCase library for Android to demonstrate to users how a given Activity works.

A sample is available in the [download area](https://github.com/stephanenicolas/RoboDemo/downloads) of the repository.
Additionally use RoboDemo to walk a user through a first time introduction to the app or show them how to use a new feature.

Screenshots
-----------
Expand All @@ -29,18 +28,18 @@ There are some cases where applications require more complex interactions from u
or new interactions not covered by Android UI Guidelines.

RoboDemo eases creating showcases / explaining / demonstrating of such activities to users.
It will display an overlay activity to illustrate the `Activity` under showcase. The explanations consist of a serie of
It will display an overlay to illustrate the `Activity` under showcase. The explanations consist of a series of
points to click on and their associated labels. The `Activity` under showcase is dimmed and the showcase highlights
transparent areas to point views or positions users have to click.

Creation of `DemoActivity` is straightforward, have a look at the sample to put in place RoboDemo in your own app :
Creation of `DemoFragment` is straightforward, have a look at the sample to put RoboDemo in your own app :

1. create a `DemoActivity`, using a custom `DrawAdapter`
1. create a `DemoFragment`, use a custom xml layout
2. in the `Activity` undershowcase, pass views or coordinates and their associated labels.

RoboDemo has been designed to be convinient.
RoboDemo can also walk a user through your own app. Great for first time use or explaining a feature that is not used often. Look in the sample to see how to switch from a showcase to a walkthrough.

To learn more, visit [RoboDemo Starter Guide](https://github.com/stephanenicolas/RoboDemo/wiki/RoboDemo-Starter-Guide) and [browse RoboDemo Javadocs online](http://stephanenicolas.github.com/RoboDemo/apidocs/index.html).
To learn more, visit [RoboDemo Fragment Starter Guide](https://github.com/ericharlow/RoboDemo/wiki/RoboDemo-FragmentStarterGuide) and [browse RoboDemo Javadocs online](http://stephanenicolas.github.com/RoboDemo/apidocs/index.html).

Customization
-------------
Expand All @@ -52,18 +51,7 @@ RoboDemo can be customized in different ways :
* using custom drawable and text locations
* and some more for sure...

To learn more, visit [RoboDemo Starter Guide](https://github.com/stephanenicolas/RoboDemo/wiki/RoboDemo-Starter-Guide) and [browse RoboDemo Javadocs online](http://stephanenicolas.github.com/RoboDemo/apidocs/index.html).


Know limitations
----------------

The base class for DemoActivity is based on `android.app.Activity`. Unfortunately, this can't cover all inheritance cases for projects
based on ActionBarSherlock or RoboGuice or a custom Activity base class per project.

In that case, we recommend using all classes from the library as well but rewrite your own `DemoActivity` changing only its super class.

In the case you use ActionBarSherlock, check the code comments, they will give you hints to support ActionBarSherlock themes.
To learn more, visit [RoboDemo Fragment Starter Guide](https://github.com/ericharlow/RoboDemo/wiki/RoboDemo-FragmentStarterGuide) and [browse RoboDemo Javadocs online](http://stephanenicolas.github.com/RoboDemo/apidocs/index.html).

Modules
-------
Expand Down
Binary file removed robodemo-lib-1.0.0.jar
Binary file not shown.
Binary file added robodemo-lib-2.2.0.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion robodemo-lib/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="7"
android:minSdkVersion="11"
android:targetSdkVersion="15" />


Expand Down
2 changes: 1 addition & 1 deletion robodemo-lib/project.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt

# Project target.
target=android-16
target=android-17
android.library=true
Binary file not shown.
Binary file not shown.
Binary file not shown.
10 changes: 10 additions & 0 deletions robodemo-lib/res/drawable/ic_lockscreen_handle.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="@dimen/image_width" android:height="@dimen/image_height"/>
<gradient android:type="radial"
android:gradientRadius="600"
android:startColor="@android:color/transparent"
android:endColor="#F0FFFFFF"/>
<stroke android:width="3dp" android:color="@android:color/white"/>
</shape>
65 changes: 65 additions & 0 deletions robodemo-lib/res/layout/fragment_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#77000000"
android:orientation="vertical" >

<com.octo.android.robodemo.DrawView
android:id="@+id/drawView_move_content_demo"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="@android:color/transparent"
app:drawable="@drawable/ic_lockscreen_handle"
app:handlerType="AnimationHandler"
app:isDrawingOnePointAtATime="true"
app:isShowingAllPointsAtTheEndOfAnimation="false"
app:shadowLayerBlurRadius="2.0"
app:shadowLayerColor="@android:color/black"
app:shadowLayerXOffset="0"
app:shadowLayerYOffset="2.0"
app:textAntiAlias="true"
app:textColor="@android:color/white"
app:textSize="22sp"
app:underTextPaintColor="@android:color/darker_gray" />

<RelativeLayout
android:id="@+id/layout_demo_buttons"
android:layout_width="fill_parent"
android:layout_height="40dp"
android:background="@android:color/black"
android:visibility="gone" >

<CheckBox
android:id="@+id/checkbox_demo_never_again"
style="@android:style/Widget.CompoundButton.CheckBox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button_demo_finish"
android:layout_alignParentLeft="true"
android:layout_marginLeft="7dp" />

<TextView
android:id="@+id/textview_demo_never_again"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@id/button_demo_finish"
android:layout_marginLeft="7dp"
android:layout_toRightOf="@id/checkbox_demo_never_again"
android:clickable="true"
android:text="@string/text_never_again"
android:textAppearance="@android:style/TextAppearance.Medium.Inverse" />

<Button
android:id="@id/button_demo_finish"
style="@android:style/Widget.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_marginRight="7dp"
android:text="@string/text_OK" />
</RelativeLayout>

</LinearLayout>
5 changes: 5 additions & 0 deletions robodemo-lib/res/values-hdpi/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="image_width">@dimen/width_hdpi</dimen>
<dimen name="image_height">@dimen/height_hdpi</dimen>
</resources>
5 changes: 5 additions & 0 deletions robodemo-lib/res/values-mdpi/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="image_width">@dimen/width_mdpi</dimen>
<dimen name="image_height">@dimen/height_mdpi</dimen>
</resources>
5 changes: 5 additions & 0 deletions robodemo-lib/res/values-xhdpi/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="image_width">@dimen/width_xhdpi</dimen>
<dimen name="image_height">@dimen/height_xhdpi</dimen>
</resources>
40 changes: 40 additions & 0 deletions robodemo-lib/res/values/attrs.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="DrawView">
<!-- Used by the DrawViewAdapter for each LabeledPoint -->
<attr name="drawable" format="reference"/>
<!-- Color of the text -->
<attr name="textColor" format="reference|color"/>
<!-- Whether the text should be anti-alias -->
<attr name="textAntiAlias" format="boolean"/>
<!-- Size of the text -->
<attr name="textSize" format="dimension"/>
<!-- Radius of the shadow -->
<attr name="shadowLayerBlurRadius" format="float" />
<!-- Horizontal offset of the shadow -->
<attr name="shadowLayerXOffset" format="float" />
<!-- Vertical offset of the shadow -->
<attr name="shadowLayerYOffset" format="float" />
<!-- Color of the shadow -->
<attr name="shadowLayerColor" format="reference|color" />
<!-- Color of the under text -->
<attr name="underTextPaintColor" format="reference|color" />
<!-- Alpha of the under text -->
<attr name="underTextPaintAlpha" format="integer" />
<!-- Whether LabeledPoints are drawn one at a time -->
<attr name="isDrawingOnePointAtATime" format="boolean" />
<!-- Whether to draw all LabeledPoints at end of animation -->
<attr name="isShowingAllPointsAtTheEndOfAnimation" format="boolean" />
<!-- Delay between points in animation in ms -->
<attr name="delayBetweenPoints" format="integer" />
<!-- Type of handler to use -->
<attr name="handlerType" format="enum">
<!-- Showcase -->
<enum name="AnimationHandler" value="1" />
<!-- Walkthrough -->
<enum name="TouchHandler" value="2" />
<!-- Touch Driven Showcase -->
<enum name="TouchAnimationHandler" value="3" />
</attr>
</declare-styleable>
</resources>
11 changes: 11 additions & 0 deletions robodemo-lib/res/values/dimens.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="width_mdpi">108dp</dimen>
<dimen name="height_mdpi">108dp</dimen>

<dimen name="width_hdpi">108dp</dimen>
<dimen name="height_hdpi">108dp</dimen>

<dimen name="width_xhdpi">162dp</dimen>
<dimen name="height_xhdpi">162dp</dimen>
</resources>
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
package com.octo.android.robodemo;

import java.util.ArrayList;
import java.util.List;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
import android.os.Build;
import android.text.Layout;
import android.text.Layout.Alignment;
import android.text.StaticLayout;
import android.text.TextPaint;
import android.text.style.DrawableMarginSpan;
import android.util.TypedValue;
import android.view.Display;
import android.view.WindowManager;
Expand Down Expand Up @@ -39,20 +43,17 @@ public class DefaultDrawViewAdapter implements DrawViewAdapter {
private Context context;

public DefaultDrawViewAdapter( Context context, List< LabeledPoint > listPoints ) {
this.context = context;
this.drawable = context.getResources().getDrawable( R.drawable.ic_lockscreen_handle_pressed );
this.textPaint = initializeDefaultTextPaint();
this.listPoints = listPoints;

initialize();

this(context,
initializeDefaultDrawable(context),
initializeDefaultTextPaint(context),
listPoints);
}

public DefaultDrawViewAdapter( Context context, Drawable drawable, TextPaint textPaint, List< LabeledPoint > listPoints ) {
this.context = context;
this.drawable = drawable;
this.textPaint = textPaint;
this.listPoints = listPoints;
this.listPoints = listPoints != null ? listPoints : new ArrayList< LabeledPoint >(0);

initialize();

Expand All @@ -62,16 +63,21 @@ public Context getContext() {
return context;
}

private TextPaint initializeDefaultTextPaint() {
private static TextPaint initializeDefaultTextPaint(Context context) {
TextPaint textPaint = new TextPaint();
textPaint.setColor( getContext().getResources().getColor( android.R.color.white ) );
textPaint.setColor( context.getResources().getColor( android.R.color.white ) );
textPaint.setShadowLayer( 2.0f, 0, 2.0f, android.R.color.black );
// http://stackoverflow.com/questions/3061930/how-to-set-unit-for-paint-settextsize
textPaint.setTextSize( TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, DEFAULT_FONT_SIZE, getContext().getResources().getDisplayMetrics() ) );
textPaint.setTextSize( TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, DEFAULT_FONT_SIZE, context.getResources().getDisplayMetrics() ) );
return textPaint;
}

private static Drawable initializeDefaultDrawable(Context context) {
return context.getResources().getDrawable( R.drawable.ic_lockscreen_handle );
}

@SuppressWarnings("deprecation")
@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR2)
@SuppressWarnings("deprecation")
private void initialize() {
WindowManager wm = (WindowManager) context.getSystemService( Context.WINDOW_SERVICE );
Display display = wm.getDefaultDisplay();
Expand All @@ -94,21 +100,43 @@ private void initialize() {

@Override
public int getPointsCount() {
return listPoints.size();
return listPoints == null ? 0 : listPoints.size();
}

@Override
public Drawable getDrawableAt( int position ) {
Point point = listPoints.get( position );
public Drawable getDrawableAt( int position ) {
LabeledPoint point = getListPoint(position);
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
drawable.setBounds( point.x - width / 2, point.y - height / 2, point.x + width / 2, point.y + height / 2 );
return drawable;
//experimental
Drawable localCopy = drawable;
if (point.doUsePreferredSize()) {
width = point.getPreferredWidth();
height = point.getPreferredHeight();
if (drawable instanceof GradientDrawable) {
localCopy = drawable.getConstantState().newDrawable().mutate();
((GradientDrawable) localCopy).setSize(width, height);
}
}

localCopy.setBounds( point.x - width / 2, point.y - height / 2, point.x + width / 2, point.y + height / 2 );
return localCopy;
}

public void setListPoints(List< LabeledPoint > listPoints) {
this.listPoints = listPoints;
}

private LabeledPoint getListPoint(int position) {
if (position < 0 || listPoints == null || position >= listPoints.size()) {
return new LabeledPoint();
}
return listPoints.get( position );
}

@Override
public Layout getTextLayoutAt( int position ) {
String text = listPoints.get( position ).getText();
String text = getListPoint(position).getText();
Rect bounds = new Rect();
textPaint.getTextBounds( text, 0, text.length(), bounds );

Expand All @@ -121,11 +149,16 @@ public Layout getTextLayoutAt( int position ) {
public Point getTextPointAt( int position ) {
Drawable drawable = getDrawableAt( position );
Layout textLayout = getTextLayoutAt( position );
Point point = listPoints.get( position );
final int marginX = drawable.getIntrinsicWidth() / 4 + margin;
final int marginY = drawable.getIntrinsicHeight() / 4 + margin;
Point point = getListPoint(position);
final int marginX = drawable.getIntrinsicWidth() / 3 + margin;
final int marginY = drawable.getIntrinsicHeight() / 3 + margin;
int textX = point.x > screenWidth / 2 ? point.x - marginX - textLayout.getWidth() : point.x + marginX;
int textY = point.y > screenHeight / 2 ? point.y - marginY - textLayout.getHeight() : point.y + marginY;
return new Point( textX, textY );
}

@Override
public String getTextAt(int position) {
return getListPoint(position).getText();
}
}
Loading