Wizard refactor: beginning

This commit is contained in:
serso 2015-01-28 22:46:39 +01:00
parent 070d0a12d1
commit 099d330f9d
28 changed files with 1217 additions and 319 deletions

View File

@ -85,12 +85,12 @@
<orderEntry type="library" exported="" scope="TEST" name="common-msg-1.0.5" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="common-listeners-1.0.7" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="guava-11.0.2" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="common-text-1.0.7" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="library-2.4.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="acra-4.5.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="common-core-1.0.7" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="_home_serso_projects_java_android_calculatorpp_android_app_build_intermediates_exploded_aar_org_solovyev_android_material_0_1_2_classes_jar" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="jscl-1.0.8" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
@ -98,6 +98,7 @@
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="_home_serso_projects_java_android_calculatorpp_android_app_build_intermediates_exploded_aar_org_solovyev_android_checkout_0_6_1_classes_jar" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="classes" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="_home_serso_projects_java_android_calculatorpp_android_app_build_intermediates_classes_debug" level="project" />

View File

@ -95,12 +95,13 @@
<orderEntry type="library" exported="" name="android-common-views-1.1.18" level="project" />
<orderEntry type="library" exported="" name="stax-1.2.0" level="project" />
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
<orderEntry type="library" exported="" name="material-0.1.2" level="project" />
<orderEntry type="library" exported="" name="android-common-menus-1.1.18" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-21.0.0" level="project" />
<orderEntry type="library" exported="" name="common-security-1.0.7" level="project" />
<orderEntry type="library" exported="" name="checkout-0.6.1" level="project" />
<orderEntry type="library" exported="" name="play-services-base-6.5.87" level="project" />
<orderEntry type="library" exported="" name="android-common-core-1.1.18" level="project" />
<orderEntry type="library" exported="" name="checkout-0.6.0" level="project" />
<orderEntry type="library" exported="" name="common-msg-1.0.5" level="project" />
<orderEntry type="library" exported="" name="android-common-other-1.1.18" level="project" />
<orderEntry type="library" exported="" name="floatingactionbutton-1.1.0" level="project" />

View File

@ -69,7 +69,8 @@ dependencies {
compile('org.solovyev:jscl:1.0.8') {
exclude(module: 'xercesImpl')
}
compile 'org.solovyev.android:checkout:0.6.0@aar'
compile 'org.solovyev.android:checkout:0.6.1@aar'
compile 'org.solovyev.android:material:0.1.2@aar'
compile 'com.google.android.gms:play-services-ads:6.5.87@aar'
compile 'com.google.android.gms:play-services-base:6.5.87@aar'
compile 'com.melnykov:floatingactionbutton:1.1.0'

View File

@ -60,7 +60,7 @@
<activity android:label="@string/c_vars_and_constants" android:name=".math.edit.CalculatorVarsActivity"/>
<activity android:name=".CalculatorWikiActivity"/>
<activity android:launchMode="singleTop" android:name=".wizard.CalculatorWizardActivity" android:theme="@style/cpp_metro_blue_dialog_theme">
<activity android:launchMode="singleTop" android:name=".wizard.WizardActivity" android:theme="@style/cpp_metro_blue_theme">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
</intent-filter>
@ -71,7 +71,7 @@
<activity android:label="@string/cpp_plot_function_settings" android:name=".plot.CalculatorPlotFunctionSettingsActivity" android:theme="@style/cpp_metro_blue_dialog_theme"/>
<activity android:label="@string/cpp_plot_range" android:name=".plot.CalculatorPlotRangeActivity" android:theme="@style/cpp_metro_blue_dialog_theme"/>
<activity android:label="@string/cpp_purchase_title" android:name=".preferences.PurchaseDialogActivity" android:theme="@style/cpp_metro_blue_dialog_theme"/>
<activity android:label="@string/cpp_purchase_title" android:name=".preferences.PurchaseDialogActivity" android:theme="@style/Theme.Wizard"/>
<activity android:name=".CalculatorDialogActivity" android:theme="@style/cpp_metro_blue_dialog_theme"/>

View File

@ -0,0 +1,556 @@
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* 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.viewpagerindicator;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.drawable.Drawable;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.view.MotionEventCompat;
import android.support.v4.view.ViewConfigurationCompat;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import org.solovyev.android.calculator.R;
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
import static android.widget.LinearLayout.HORIZONTAL;
import static android.widget.LinearLayout.VERTICAL;
/**
* Draws circles (one for each view). The current view position is filled and
* others are only stroked.
*/
public class CirclePageIndicator extends View implements PageIndicator {
private static final int INVALID_POINTER = -1;
private float mRadius;
private final Paint mPaintPageFill = new Paint(ANTI_ALIAS_FLAG);
private final Paint mPaintStroke = new Paint(ANTI_ALIAS_FLAG);
private final Paint mPaintFill = new Paint(ANTI_ALIAS_FLAG);
private ViewPager mViewPager;
private ViewPager.OnPageChangeListener mListener;
private int mCurrentPage;
private int mSnapPage;
private float mPageOffset;
private int mScrollState;
private int mOrientation;
private boolean mCentered;
private boolean mSnap;
private int mTouchSlop;
private float mLastMotionX = -1;
private int mActivePointerId = INVALID_POINTER;
private boolean mIsDragging;
public CirclePageIndicator(Context context) {
this(context, null);
}
public CirclePageIndicator(Context context, AttributeSet attrs) {
this(context, attrs, R.attr.vpiCirclePageIndicatorStyle);
}
public CirclePageIndicator(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
if (isInEditMode()) return;
//Load defaults from resources
final Resources res = getResources();
final int defaultPageColor = res.getColor(R.color.default_circle_indicator_page_color);
final int defaultFillColor = res.getColor(R.color.default_circle_indicator_fill_color);
final int defaultOrientation = res.getInteger(R.integer.default_circle_indicator_orientation);
final int defaultStrokeColor = res.getColor(R.color.default_circle_indicator_stroke_color);
final float defaultStrokeWidth = res.getDimension(R.dimen.default_circle_indicator_stroke_width);
final float defaultRadius = res.getDimension(R.dimen.default_circle_indicator_radius);
final boolean defaultCentered = res.getBoolean(R.bool.default_circle_indicator_centered);
final boolean defaultSnap = res.getBoolean(R.bool.default_circle_indicator_snap);
//Retrieve styles attributes
TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CirclePageIndicator, defStyle, 0);
mCentered = a.getBoolean(R.styleable.CirclePageIndicator_centered, defaultCentered);
mOrientation = a.getInt(R.styleable.CirclePageIndicator_android_orientation, defaultOrientation);
mPaintPageFill.setStyle(Style.FILL);
mPaintPageFill.setColor(a.getColor(R.styleable.CirclePageIndicator_pageColor, defaultPageColor));
mPaintStroke.setStyle(Style.STROKE);
mPaintStroke.setColor(a.getColor(R.styleable.CirclePageIndicator_strokeColor, defaultStrokeColor));
mPaintStroke.setStrokeWidth(a.getDimension(R.styleable.CirclePageIndicator_strokeWidth, defaultStrokeWidth));
mPaintFill.setStyle(Style.FILL);
mPaintFill.setColor(a.getColor(R.styleable.CirclePageIndicator_fillColor, defaultFillColor));
mRadius = a.getDimension(R.styleable.CirclePageIndicator_radius, defaultRadius);
mSnap = a.getBoolean(R.styleable.CirclePageIndicator_snap, defaultSnap);
Drawable background = a.getDrawable(R.styleable.CirclePageIndicator_android_background);
if (background != null) {
setBackgroundDrawable(background);
}
a.recycle();
final ViewConfiguration configuration = ViewConfiguration.get(context);
mTouchSlop = ViewConfigurationCompat.getScaledPagingTouchSlop(configuration);
}
public void setCentered(boolean centered) {
mCentered = centered;
invalidate();
}
public boolean isCentered() {
return mCentered;
}
public void setPageColor(int pageColor) {
mPaintPageFill.setColor(pageColor);
invalidate();
}
public int getPageColor() {
return mPaintPageFill.getColor();
}
public void setFillColor(int fillColor) {
mPaintFill.setColor(fillColor);
invalidate();
}
public int getFillColor() {
return mPaintFill.getColor();
}
public void setOrientation(int orientation) {
switch (orientation) {
case HORIZONTAL:
case VERTICAL:
mOrientation = orientation;
requestLayout();
break;
default:
throw new IllegalArgumentException("Orientation must be either HORIZONTAL or VERTICAL.");
}
}
public int getOrientation() {
return mOrientation;
}
public void setStrokeColor(int strokeColor) {
mPaintStroke.setColor(strokeColor);
invalidate();
}
public int getStrokeColor() {
return mPaintStroke.getColor();
}
public void setStrokeWidth(float strokeWidth) {
mPaintStroke.setStrokeWidth(strokeWidth);
invalidate();
}
public float getStrokeWidth() {
return mPaintStroke.getStrokeWidth();
}
public void setRadius(float radius) {
mRadius = radius;
invalidate();
}
public float getRadius() {
return mRadius;
}
public void setSnap(boolean snap) {
mSnap = snap;
invalidate();
}
public boolean isSnap() {
return mSnap;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mViewPager == null) {
return;
}
final int count = mViewPager.getAdapter().getCount();
if (count == 0) {
return;
}
if (mCurrentPage >= count) {
setCurrentItem(count - 1);
return;
}
int longSize;
int longPaddingBefore;
int longPaddingAfter;
int shortPaddingBefore;
if (mOrientation == HORIZONTAL) {
longSize = getWidth();
longPaddingBefore = getPaddingLeft();
longPaddingAfter = getPaddingRight();
shortPaddingBefore = getPaddingTop();
} else {
longSize = getHeight();
longPaddingBefore = getPaddingTop();
longPaddingAfter = getPaddingBottom();
shortPaddingBefore = getPaddingLeft();
}
final float threeRadius = mRadius * 3;
final float shortOffset = shortPaddingBefore + mRadius;
float longOffset = longPaddingBefore + mRadius;
if (mCentered) {
longOffset += ((longSize - longPaddingBefore - longPaddingAfter) / 2.0f) - ((count * threeRadius) / 2.0f);
}
float dX;
float dY;
float pageFillRadius = mRadius;
if (mPaintStroke.getStrokeWidth() > 0) {
pageFillRadius -= mPaintStroke.getStrokeWidth() / 2.0f;
}
//Draw stroked circles
for (int iLoop = 0; iLoop < count; iLoop++) {
float drawLong = longOffset + (iLoop * threeRadius);
if (mOrientation == HORIZONTAL) {
dX = drawLong;
dY = shortOffset;
} else {
dX = shortOffset;
dY = drawLong;
}
// Only paint fill if not completely transparent
if (mPaintPageFill.getAlpha() > 0) {
canvas.drawCircle(dX, dY, pageFillRadius, mPaintPageFill);
}
// Only paint stroke if a stroke width was non-zero
if (pageFillRadius != mRadius) {
canvas.drawCircle(dX, dY, mRadius, mPaintStroke);
}
}
//Draw the filled circle according to the current scroll
float cx = (mSnap ? mSnapPage : mCurrentPage) * threeRadius;
if (!mSnap) {
cx += mPageOffset * threeRadius;
}
if (mOrientation == HORIZONTAL) {
dX = longOffset + cx;
dY = shortOffset;
} else {
dX = shortOffset;
dY = longOffset + cx;
}
canvas.drawCircle(dX, dY, mRadius, mPaintFill);
}
public boolean onTouchEvent(MotionEvent ev) {
if (super.onTouchEvent(ev)) {
return true;
}
if ((mViewPager == null) || (mViewPager.getAdapter().getCount() == 0)) {
return false;
}
final int action = ev.getAction() & MotionEventCompat.ACTION_MASK;
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = MotionEventCompat.getPointerId(ev, 0);
mLastMotionX = ev.getX();
break;
case MotionEvent.ACTION_MOVE: {
final int activePointerIndex = MotionEventCompat.findPointerIndex(ev, mActivePointerId);
final float x = MotionEventCompat.getX(ev, activePointerIndex);
final float deltaX = x - mLastMotionX;
if (!mIsDragging) {
if (Math.abs(deltaX) > mTouchSlop) {
mIsDragging = true;
}
}
if (mIsDragging) {
mLastMotionX = x;
if (mViewPager.isFakeDragging() || mViewPager.beginFakeDrag()) {
mViewPager.fakeDragBy(deltaX);
}
}
break;
}
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
if (!mIsDragging) {
final int count = mViewPager.getAdapter().getCount();
final int width = getWidth();
final float halfWidth = width / 2f;
final float sixthWidth = width / 6f;
if ((mCurrentPage > 0) && (ev.getX() < halfWidth - sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage - 1);
}
return true;
} else if ((mCurrentPage < count - 1) && (ev.getX() > halfWidth + sixthWidth)) {
if (action != MotionEvent.ACTION_CANCEL) {
mViewPager.setCurrentItem(mCurrentPage + 1);
}
return true;
}
}
mIsDragging = false;
mActivePointerId = INVALID_POINTER;
if (mViewPager.isFakeDragging()) mViewPager.endFakeDrag();
break;
case MotionEventCompat.ACTION_POINTER_DOWN: {
final int index = MotionEventCompat.getActionIndex(ev);
mLastMotionX = MotionEventCompat.getX(ev, index);
mActivePointerId = MotionEventCompat.getPointerId(ev, index);
break;
}
case MotionEventCompat.ACTION_POINTER_UP:
final int pointerIndex = MotionEventCompat.getActionIndex(ev);
final int pointerId = MotionEventCompat.getPointerId(ev, pointerIndex);
if (pointerId == mActivePointerId) {
final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
mActivePointerId = MotionEventCompat.getPointerId(ev, newPointerIndex);
}
mLastMotionX = MotionEventCompat.getX(ev, MotionEventCompat.findPointerIndex(ev, mActivePointerId));
break;
}
return true;
}
@Override
public void setViewPager(ViewPager view) {
if (mViewPager == view) {
return;
}
if (mViewPager != null) {
mViewPager.setOnPageChangeListener(null);
}
if (view.getAdapter() == null) {
throw new IllegalStateException("ViewPager does not have adapter instance.");
}
mViewPager = view;
mViewPager.setOnPageChangeListener(this);
invalidate();
}
@Override
public void setViewPager(ViewPager view, int initialPosition) {
setViewPager(view);
setCurrentItem(initialPosition);
}
@Override
public void setCurrentItem(int item) {
if (mViewPager == null) {
throw new IllegalStateException("ViewPager has not been bound.");
}
mViewPager.setCurrentItem(item);
mCurrentPage = item;
invalidate();
}
@Override
public void notifyDataSetChanged() {
invalidate();
}
@Override
public void onPageScrollStateChanged(int state) {
mScrollState = state;
if (mListener != null) {
mListener.onPageScrollStateChanged(state);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
mCurrentPage = position;
mPageOffset = positionOffset;
invalidate();
if (mListener != null) {
mListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
}
}
@Override
public void onPageSelected(int position) {
if (mSnap || mScrollState == ViewPager.SCROLL_STATE_IDLE) {
mCurrentPage = position;
mSnapPage = position;
invalidate();
}
if (mListener != null) {
mListener.onPageSelected(position);
}
}
@Override
public void setOnPageChangeListener(ViewPager.OnPageChangeListener listener) {
mListener = listener;
}
/*
* (non-Javadoc)
*
* @see android.view.View#onMeasure(int, int)
*/
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
if (mOrientation == HORIZONTAL) {
setMeasuredDimension(measureLong(widthMeasureSpec), measureShort(heightMeasureSpec));
} else {
setMeasuredDimension(measureShort(widthMeasureSpec), measureLong(heightMeasureSpec));
}
}
/**
* Determines the width of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The width of the view, honoring constraints from measureSpec
*/
private int measureLong(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if ((specMode == MeasureSpec.EXACTLY) || (mViewPager == null)) {
//We were told how big to be
result = specSize;
} else {
//Calculate the width according the views count
final int count = mViewPager.getAdapter().getCount();
result = (int)(getPaddingLeft() + getPaddingRight()
+ (count * 2 * mRadius) + (count - 1) * mRadius + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
/**
* Determines the height of this view
*
* @param measureSpec
* A measureSpec packed into an int
* @return The height of the view, honoring constraints from measureSpec
*/
private int measureShort(int measureSpec) {
int result;
int specMode = MeasureSpec.getMode(measureSpec);
int specSize = MeasureSpec.getSize(measureSpec);
if (specMode == MeasureSpec.EXACTLY) {
//We were told how big to be
result = specSize;
} else {
//Measure the height
result = (int)(2 * mRadius + getPaddingTop() + getPaddingBottom() + 1);
//Respect AT_MOST value if that was what is called for by measureSpec
if (specMode == MeasureSpec.AT_MOST) {
result = Math.min(result, specSize);
}
}
return result;
}
@Override
public void onRestoreInstanceState(Parcelable state) {
SavedState savedState = (SavedState)state;
super.onRestoreInstanceState(savedState.getSuperState());
mCurrentPage = savedState.currentPage;
mSnapPage = savedState.currentPage;
requestLayout();
}
@Override
public Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
SavedState savedState = new SavedState(superState);
savedState.currentPage = mCurrentPage;
return savedState;
}
static class SavedState extends BaseSavedState {
int currentPage;
public SavedState(Parcelable superState) {
super(superState);
}
private SavedState(Parcel in) {
super(in);
currentPage = in.readInt();
}
@Override
public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags);
dest.writeInt(currentPage);
}
@SuppressWarnings("UnusedDeclaration")
public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2011 Patrik Akerfeldt
* Copyright (C) 2011 Jake Wharton
*
* 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.viewpagerindicator;
import android.support.v4.view.ViewPager;
/**
* A PageIndicator is responsible to show an visual indicator on the total views
* number and the current visible view.
*/
public interface PageIndicator extends ViewPager.OnPageChangeListener {
/**
* Bind the indicator to a ViewPager.
*
* @param view
*/
void setViewPager(ViewPager view);
/**
* Bind the indicator to a ViewPager.
*
* @param view
* @param initialPosition
*/
void setViewPager(ViewPager view, int initialPosition);
/**
* <p>Set the current page of both the ViewPager and indicator.</p>
*
* <p>This <strong>must</strong> be used if you need to set the page before
* the views are drawn on screen (e.g., default start page).</p>
*
* @param item
*/
void setCurrentItem(int item);
/**
* Set a page change listener which will receive forwarded events.
*
* @param listener
*/
void setOnPageChangeListener(ViewPager.OnPageChangeListener listener);
/**
* Notify the indicator that the fragment list has changed.
*/
void notifyDataSetChanged();
}

View File

@ -1,50 +0,0 @@
/*
* Copyright 2013 serso aka se.solovyev
*
* 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.
*
* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Contact details
*
* Email: se.solovyev@gmail.com
* Site: http://se.solovyev.org
*/
package org.solovyev.android.calculator.wizard;
import org.solovyev.android.calculator.CalculatorApplication;
import org.solovyev.android.calculator.R;
import org.solovyev.android.wizard.BaseWizardActivity;
import org.solovyev.android.wizard.Wizards;
import javax.annotation.Nonnull;
public final class CalculatorWizardActivity extends BaseWizardActivity {
@Nonnull
private Wizards wizards;
public CalculatorWizardActivity() {
super(R.layout.cpp_wizard);
this.wizards = CalculatorApplication.getInstance().getWizards();
}
@Nonnull
public Wizards getWizards() {
return wizards;
}
public void setWizards(@Nonnull Wizards wizards) {
this.wizards = wizards;
}
}

View File

@ -27,7 +27,7 @@ public class CalculatorWizards implements Wizards {
@Nonnull
@Override
public Class<? extends Activity> getActivityClassName() {
return CalculatorWizardActivity.class;
return WizardActivity.class;
}
@Nonnull

View File

@ -23,22 +23,23 @@
package org.solovyev.android.calculator.wizard;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import org.solovyev.android.calculator.R;
/**
* User: serso
* Date: 6/16/13
* Time: 9:44 PM
*/
public final class WelcomeWizardStep extends Fragment {
public final class WelcomeWizardStep extends WizardFragment {
@Override
protected int getViewResId() {
return R.layout.cpp_wizard_step_welcome;
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.cpp_wizard_step_welcome, null);
final View view = super.onCreateView(inflater, container, savedInstanceState);
setupNextButton(R.string.wizard_start);
setupPrevButton(R.string.wizard_skip);
return view;
}
}

View File

@ -0,0 +1,139 @@
package org.solovyev.android.calculator.wizard;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import com.viewpagerindicator.PageIndicator;
import org.solovyev.android.calculator.BaseActivity;
import org.solovyev.android.calculator.CalculatorApplication;
import org.solovyev.android.calculator.R;
import org.solovyev.android.wizard.*;
import javax.annotation.Nonnull;
public class WizardActivity extends BaseActivity implements WizardsAware {
@Nonnull
private final WizardUi<WizardActivity> wizardUi = new WizardUi<WizardActivity>(this, this, 0);
@Nonnull
private ViewPager pager;
@Nonnull
private PagerAdapter pagerAdapter;
public WizardActivity() {
super(R.layout.cpp_activity_wizard);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
wizardUi.onCreate(savedInstanceState);
getSupportActionBar().hide();
final ListWizardFlow flow = (ListWizardFlow) wizardUi.getFlow();
pager = (ViewPager) findViewById(R.id.pager);
pagerAdapter = new WizardPagerAdapter(flow, getSupportFragmentManager());
pager.setAdapter(pagerAdapter);
final PageIndicator titleIndicator = (PageIndicator) findViewById(R.id.pager_indicator);
titleIndicator.setViewPager(pager);
titleIndicator.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
@Override
public void onPageSelected(int position) {
wizardUi.setStep(flow.getStepAt(position));
}
});
if (savedInstanceState == null) {
final int position = flow.getPositionFor(wizardUi.getStep());
pager.setCurrentItem(position);
}
}
@Override
public void onBackPressed() {
if (pager.getCurrentItem() == 0) {
super.onBackPressed();
} else {
pager.setCurrentItem(pager.getCurrentItem() - 1);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
wizardUi.onSaveInstanceState(outState);
}
@Override
protected void onPause() {
super.onPause();
wizardUi.onPause();
}
@Nonnull
@Override
public Wizards getWizards() {
return CalculatorApplication.getInstance().getWizards();
}
public void finishWizardAbruptly() {
wizardUi.finishWizardAbruptly();
finish();
}
public void finishWizard() {
wizardUi.finishWizard();
finish();
}
public boolean canGoNext() {
final int position = pager.getCurrentItem();
return position != pagerAdapter.getCount() - 1;
}
public boolean canGoPrev() {
final int position = pager.getCurrentItem();
return position != 0;
}
public void goNext() {
final int position = pager.getCurrentItem();
if (position < pagerAdapter.getCount() - 1) {
pager.setCurrentItem(position + 1, true);
}
}
public void goPrev() {
final int position = pager.getCurrentItem();
if (position > 0) {
pager.setCurrentItem(position - 1, true);
}
}
private class WizardPagerAdapter extends FragmentStatePagerAdapter {
@Nonnull
private final ListWizardFlow flow;
public WizardPagerAdapter(@Nonnull ListWizardFlow flow, @Nonnull FragmentManager fm) {
super(fm);
this.flow = flow;
}
@Override
public Fragment getItem(int position) {
final WizardStep step = flow.getStepAt(position);
final String className = step.getFragmentClass().getName();
final Bundle args = step.getFragmentArgs();
return Fragment.instantiate(WizardActivity.this, className, args);
}
@Override
public int getCount() {
return flow.getCount();
}
}
}

View File

@ -0,0 +1,72 @@
package org.solovyev.android.calculator.wizard;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import org.solovyev.android.calculator.R;
import javax.annotation.Nullable;
public abstract class WizardFragment extends Fragment implements View.OnClickListener {
@Nullable
private TextView nextButton;
@Nullable
private TextView prevButton;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_wizard, container, false);
final ViewGroup content = (ViewGroup) view.findViewById(R.id.wizard_content);
inflater.inflate(getViewResId(), content, true);
nextButton = (TextView) view.findViewById(R.id.wizard_next);
if (nextButton != null) {
nextButton.setOnClickListener(this);
}
prevButton = (TextView) view.findViewById(R.id.wizard_prev);
if (prevButton != null) {
prevButton.setOnClickListener(this);
}
return view;
}
protected final void setupNextButton(int textResId) {
assert nextButton != null;
nextButton.setText(textResId);
}
protected final void setupPrevButton(int textResId) {
assert prevButton != null;
prevButton.setText(textResId);
}
@LayoutRes
protected abstract int getViewResId();
@Override
public void onClick(View v) {
final int id = v.getId();
final WizardActivity activity = (WizardActivity) getActivity();
if (id == R.id.wizard_next) {
if (activity.canGoNext()) {
activity.goNext();
} else {
activity.finishWizard();
}
} else if (id == R.id.wizard_prev) {
if (activity.canGoPrev()) {
activity.goPrev();
} else {
activity.finishWizardAbruptly();
}
}
}
}

View File

@ -1,44 +0,0 @@
package org.solovyev.android.wizard;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import javax.annotation.Nonnull;
public abstract class BaseWizardActivity extends ActionBarActivity implements WizardsAware, FinishWizardConfirmationDialog.Listener {
@Nonnull
private WizardUi ui;
protected BaseWizardActivity(int layoutResId) {
ui = new WizardUi<BaseWizardActivity>(this, this, layoutResId);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ui.onCreate(savedInstanceState);
}
@Override
protected void onSaveInstanceState(Bundle out) {
super.onSaveInstanceState(out);
ui.onSaveInstanceState(out);
}
@Override
public void onPause() {
super.onPause();
ui.onPause();
}
@Override
public void onBackPressed() {
ui.onBackPressed();
}
@Override
public void finishWizardAbruptly() {
ui.finishWizardAbruptly();
}
}

View File

@ -22,33 +22,28 @@
package org.solovyev.android.wizard;
import org.solovyev.common.JPredicate;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.List;
import static org.solovyev.common.collections.Collections.find;
public final class ListWizardFlow implements WizardFlow {
@Nonnull
private final List<WizardStep> steps;
private final List<? extends WizardStep> steps;
public ListWizardFlow(@Nonnull List<WizardStep> steps) {
public ListWizardFlow(@Nonnull List<? extends WizardStep> steps) {
this.steps = steps;
}
@Nullable
@Override
public WizardStep getStepByName(@Nonnull final String name) {
return find(steps, new JPredicate<WizardStep>() {
@Override
public boolean apply(@Nullable WizardStep step) {
assert step != null;
return step.getName().equals(name);
for (WizardStep step : steps) {
if (step.getName().equals(name)) {
return step;
}
});
}
return null;
}
@Nullable
@ -78,4 +73,24 @@ public final class ListWizardFlow implements WizardFlow {
public WizardStep getFirstStep() {
return steps.get(0);
}
@Nonnull
public WizardStep getStepAt(int position) {
return steps.get(position);
}
public int getPositionFor(@Nonnull WizardStep step) {
for (int i = 0; i < steps.size(); i++) {
if (steps.get(i).equals(step)) {
return i;
}
}
return -1;
}
public int getCount() {
return steps.size();
}
}

View File

@ -6,63 +6,25 @@ import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.View;
import android.widget.Button;
import org.solovyev.android.calculator.R;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import static android.view.View.GONE;
import static android.view.View.VISIBLE;
public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialog.Listener> {
/*
**********************************************************************
*
* CONSTANTS
*
**********************************************************************
*/
public class WizardUi<A extends FragmentActivity> {
private static final String FLOW = "flow";
private static final String STEP = "step";
/*
**********************************************************************
*
* FIELDS
*
**********************************************************************
*/
private WizardStep step;
private Wizard wizard;
/*
**********************************************************************
*
* VIEWS
*
**********************************************************************
*/
@Nullable
private View prevButton;
protected WizardStep step;
protected Wizard wizard;
@Nonnull
private Button nextButton;
protected final A activity;
@Nonnull
private final A activity;
protected final WizardsAware wizardsAware;
@Nonnull
private final WizardsAware wizardsAware;
private final int layoutResId;
protected final int layoutResId;
public WizardUi(@Nonnull A activity, @Nonnull WizardsAware wizardsAware, int layoutResId) {
this.activity = activity;
@ -70,22 +32,14 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
this.layoutResId = layoutResId;
}
/*
**********************************************************************
*
* LIFECYCLE
*
**********************************************************************
*/
public void onCreate(@Nullable Bundle savedInstanceState) {
if (layoutResId != 0) {
activity.setContentView(layoutResId);
}
prevButton = activity.findViewById(R.id.acl_wizard_prev_button);
nextButton = (Button) activity.findViewById(R.id.acl_wizard_next_button);
String wizardName = activity.getIntent().getStringExtra(FLOW);
String stepName = activity.getIntent().getStringExtra(STEP);
final Intent intent = activity.getIntent();
String wizardName = intent.getStringExtra(FLOW);
String stepName = intent.getStringExtra(STEP);
if (savedInstanceState != null) {
wizardName = savedInstanceState.getString(FLOW);
stepName = savedInstanceState.getString(STEP);
@ -93,7 +47,6 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
wizard = wizardsAware.getWizards().getWizard(wizardName);
WizardStep step = null;
if (stepName != null) {
step = wizard.getFlow().getStepByName(stepName);
}
@ -101,70 +54,10 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
if (step == null) {
step = wizard.getFlow().getFirstStep();
}
setStep(step);
}
public void setStep(@Nonnull WizardStep step) {
if (this.step == null || !this.step.equals(step)) {
hideFragment();
public void setStep(WizardStep step) {
this.step = step;
showFragment();
initTitle();
initNextButton();
initPrevButton();
}
}
private void initTitle() {
activity.setTitle(step.getTitleResId());
}
private void initPrevButton() {
if (prevButton != null) {
final WizardStep prevStep = wizard.getFlow().getPrevStep(step);
if (prevStep == null) {
prevButton.setVisibility(GONE);
prevButton.setOnClickListener(null);
} else {
prevButton.setVisibility(VISIBLE);
prevButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (tryGoPrev()) {
setStep(prevStep);
}
}
});
}
}
}
private void initNextButton() {
final WizardStep nextStep = wizard.getFlow().getNextStep(step);
if (nextStep == null) {
nextButton.setText(R.string.acl_wizard_finish);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (tryGoNext()) {
finishWizard();
}
}
});
} else {
nextButton.setText(step.getNextButtonTitleResId());
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (tryGoNext()) {
setStep(nextStep);
}
}
});
}
}
public void finishWizardAbruptly() {
@ -175,14 +68,14 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
finishWizard(false);
}
void finishWizard(boolean forceFinish) {
protected final void finishWizard(boolean forceFinish) {
if (wizard != null && step != null) {
wizard.saveFinished(step, forceFinish);
}
activity.finish();
}
private boolean tryGoPrev() {
protected final boolean tryGoPrev() {
if (step == null) {
return true;
} else {
@ -192,11 +85,11 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
}
@Nonnull
private FragmentManager getFragmentManager() {
protected final FragmentManager getFragmentManager() {
return activity.getSupportFragmentManager();
}
private boolean tryGoNext() {
protected final boolean tryGoNext() {
if (step == null) {
return true;
} else {
@ -205,43 +98,6 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
}
}
@Nonnull
private Fragment showFragment() {
final FragmentManager fm = getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
Fragment newFragment = fm.findFragmentByTag(step.getFragmentTag());
if (newFragment == null) {
newFragment = Fragment.instantiate(activity, step.getFragmentClass().getName(), step.getFragmentArgs());
ft.add(R.id.acl_wizard_content, newFragment, step.getFragmentTag());
}
ft.commit();
fm.executePendingTransactions();
return newFragment;
}
private void hideFragment() {
final FragmentManager fm = getFragmentManager();
final FragmentTransaction ft = fm.beginTransaction();
if (step != null) {
hideFragmentByTag(fm, ft, step.getFragmentTag());
}
ft.commit();
fm.executePendingTransactions();
}
private void hideFragmentByTag(@Nonnull FragmentManager fm, @Nonnull FragmentTransaction ft, @Nonnull String fragmentTag) {
final Fragment oldFragment = fm.findFragmentByTag(fragmentTag);
if (oldFragment != null) {
ft.remove(oldFragment);
}
}
public void onSaveInstanceState(@Nonnull Bundle out) {
out.putString(FLOW, wizard.getName());
out.putString(STEP, step.getName());
@ -253,18 +109,6 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
}
}
public void onBackPressed() {
FinishWizardConfirmationDialog.show(activity);
}
/*
**********************************************************************
*
* GETTERS
*
**********************************************************************
*/
public WizardStep getStep() {
return step;
}
@ -277,23 +121,6 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
return wizard;
}
@Nullable
public View getPrevButton() {
return prevButton;
}
public View getNextButton() {
return nextButton;
}
/*
**********************************************************************
*
* STATIC
*
**********************************************************************
*/
public static void startWizard(@Nonnull Wizards wizards, @Nonnull Context context) {
context.startActivity(createLaunchIntent(wizards, null, context));
}
@ -329,5 +156,4 @@ public class WizardUi<A extends FragmentActivity & FinishWizardConfirmationDialo
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
return intent;
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/cpp_metro_button_dark" android:state_enabled="true" android:state_pressed="true" />
<item android:color="@color/cpp_metro_button_dark" android:state_enabled="false" />
<item android:color="@color/cpp_metro_blue" />
</selector>

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:my="http://schemas.android.com/apk/res-auto"
style="@style/MaterialActivity"
android:orientation="vertical">
<android.support.v4.view.ViewPager
android:id="@+id/pager"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
<com.viewpagerindicator.CirclePageIndicator
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:id="@+id/pager_indicator"
android:layout_height="wrap_content"
android:layout_width="match_parent"
my:fillColor="@color/cpp_metro_blue"
my:radius="5dp" />
</LinearLayout>

View File

@ -22,9 +22,13 @@
~ Site: http://se.solovyev.org
-->
<TextView
xmlns:a="http://schemas.android.com/apk/res/android"
<TextView xmlns:a="http://schemas.android.com/apk/res/android"
a:drawableTop="@drawable/icon"
a:drawablePadding="5dp"
a:layout_width="match_parent"
a:layout_height="match_parent"
a:text="@string/c_first_start_text"
/>
a:layout_height="wrap_content"
a:gravity="center"
a:layout_gravity="center"
a:textColor="@color/material_text"
a:textAppearance="@android:style/TextAppearance.Medium"
a:text="@string/c_first_start_text" />

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:a="http://schemas.android.com/apk/res/android"
style="@style/WizardFragment"
a:orientation="vertical">
<ScrollView
a:id="@+id/wizard_content"
a:layout_width="match_parent"
a:layout_height="0dp"
a:layout_weight="1"
a:fillViewport="true"
a:layout_marginBottom="@dimen/control_margin"
a:layout_marginTop="@dimen/control_margin" />
<include layout="@layout/fragment_wizard_buttons" />
</LinearLayout>

View File

@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
style="@style/WizardButtons"
xmlns:a="http://schemas.android.com/apk/res/android"
a:layout_gravity="center_horizontal|bottom"
a:gravity="center">
<Button
a:id="@+id/wizard_prev"
a:layout_width="0dp"
a:layout_height="wrap_content"
a:layout_weight="1" />
<Button
a:id="@+id/wizard_next"
a:layout_width="0dp"
a:layout_height="wrap_content"
a:layout_weight="1" />
</LinearLayout>

View File

@ -8,4 +8,10 @@
<string name="cpp_clear_history">Отчистить</string>
<string name="cpp_clear_history_message">Вся история будет отчищена</string>
<string name="cpp_clear_history_title">Отчистить историю?</string>
<string name="wizard_start">Начать визард</string>
<string name="wizard_skip">Пропустить</string>
<string name="wizard_finish">Закончить</string>
<string name="wizard_next">Далее</string>
<string name="wizard_prev">Назад</string>
<string name="wizard_final">Приложение настроено и готово к использованию.</string>
</resources>

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>

View File

@ -41,4 +41,6 @@
<color name="cpp_text_primary">#ddffffff</color>
<color name="cpp_text_secondary">#89ffffff</color>
<color name="cpp_widget_ripple">#40ffffff</color>
<color name="cpp_wizard_text">#707070</color>
</resources>

View File

@ -35,4 +35,8 @@
<dimen name="cpp_display_padding">3dp</dimen>
<dimen name="cpp_widget_keyboard_button_text_size">20dp</dimen>
<dimen name="activity_horizontal_margin">5dp</dimen>
<dimen name="activity_vertical_margin">5dp</dimen>
<dimen name="control_margin">5dp</dimen>
</resources>

View File

@ -8,4 +8,9 @@
<string name="cpp_clear_history_title">Clear history?</string>
<string name="cpp_clear_history_message">All history will be cleared.</string>
<string name="cpp_clear_history">Clear</string>
<string name="wizard_start">Start wizard</string>
<string name="wizard_next">Next</string>
<string name="wizard_prev">Back</string>
<string name="wizard_final">The app is set up and ready to use.</string>
<string name="wizard_skip">Skip</string>
</resources>

View File

@ -145,4 +145,41 @@
<item name="android:padding">1dp</item>
</style>
<style name="BaseWizardButtons">
<item name="android:background">@null</item>
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:layout_marginTop">@dimen/control_margin</item>
<item name="android:layout_gravity">top|center_horizontal</item>
<item name="android:orientation">horizontal</item>
</style>
<style name="WizardButton" parent="MaterialButton">
<item name="android:singleLine">true</item>
<item name="android:maxLines">1</item>
<item name="android:lines">1</item>
<item name="android:ellipsize">end</item>
<item name="android:textAppearance">@android:style/TextAppearance.Medium</item>
</style>
<style name="WizardPrimaryButton" parent="PrimaryButton">
<item name="android:singleLine">true</item>
<item name="android:maxLines">1</item>
<item name="android:lines">1</item>
<item name="android:ellipsize">end</item>
<item name="android:textAppearance">@android:style/TextAppearance.Medium</item>
</style>
<style name="WizardButtons" parent="BaseWizardButtons"/>
<style name="PrimaryButton" parent="MaterialButton">
</style>
<style name="WizardFragment">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">match_parent</item>
<item name="android:orientation">vertical</item>
<item name="android:paddingLeft">10dp</item>
<item name="android:paddingRight">10dp</item>
<item name="android:gravity">center</item>
</style>
</resources>

View File

@ -48,6 +48,11 @@
<item name="android:padding">6dp</item>
</style>
<style name="Theme.Wizard" parent="cpp_metro_blue_theme">
<item name="android:windowNoTitle">true</item>
<item name="android:background">@color/cpp_metro_button_light</item>
</style>
<style name="cpp_metro_blue_theme" parent="cpp_gray_theme">
<item name="cpp_digit_button_style">@style/metro_digit_button_style</item>
<item name="cpp_control_button_style">@style/metro_control_button_style</item>

View File

@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
Copyright (C) 2011 Patrik Åkerfeldt
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>
<declare-styleable name="ViewPagerIndicator">
<!-- Style of the circle indicator. -->
<attr name="vpiCirclePageIndicatorStyle" format="reference"/>
<!-- Style of the icon indicator's views. -->
<attr name="vpiIconPageIndicatorStyle" format="reference"/>
<!-- Style of the line indicator. -->
<attr name="vpiLinePageIndicatorStyle" format="reference"/>
<!-- Style of the title indicator. -->
<attr name="vpiTitlePageIndicatorStyle" format="reference"/>
<!-- Style of the tab indicator's tabs. -->
<attr name="vpiTabPageIndicatorStyle" format="reference"/>
<!-- Style of the underline indicator. -->
<attr name="vpiUnderlinePageIndicatorStyle" format="reference"/>
</declare-styleable>
<attr name="centered" format="boolean" />
<attr name="selectedColor" format="color" />
<attr name="strokeWidth" format="dimension" />
<attr name="unselectedColor" format="color" />
<declare-styleable name="CirclePageIndicator">
<!-- Whether or not the indicators should be centered. -->
<attr name="centered" />
<!-- Color of the filled circle that represents the current page. -->
<attr name="fillColor" format="color" />
<!-- Color of the filled circles that represents pages. -->
<attr name="pageColor" format="color" />
<!-- Orientation of the indicator. -->
<attr name="android:orientation"/>
<!-- Radius of the circles. This is also the spacing between circles. -->
<attr name="radius" format="dimension" />
<!-- Whether or not the selected indicator snaps to the circles. -->
<attr name="snap" format="boolean" />
<!-- Color of the open circles. -->
<attr name="strokeColor" format="color" />
<!-- Width of the stroke used to draw the circles. -->
<attr name="strokeWidth" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
<declare-styleable name="LinePageIndicator">
<!-- Whether or not the indicators should be centered. -->
<attr name="centered" />
<!-- Color of the unselected lines that represent the pages. -->
<attr name="unselectedColor" />
<!-- Color of the selected line that represents the current page. -->
<attr name="selectedColor" />
<!-- Width of each indicator line. -->
<attr name="lineWidth" format="dimension" />
<!-- Width of each indicator line's stroke. -->
<attr name="strokeWidth" />
<!-- Width of the gap between each indicator line. -->
<attr name="gapWidth" format="dimension" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
<declare-styleable name="TitlePageIndicator">
<!-- Screen edge padding. -->
<attr name="clipPadding" format="dimension" />
<!-- Color of the footer line and indicator. -->
<attr name="footerColor" format="color" />
<!-- Height of the footer line. -->
<attr name="footerLineHeight" format="dimension" />
<!-- Style of the indicator. Default is triangle. -->
<attr name="footerIndicatorStyle">
<enum name="none" value="0" />
<enum name="triangle" value="1" />
<enum name="underline" value="2" />
</attr>
<!-- Height of the indicator above the footer line. -->
<attr name="footerIndicatorHeight" format="dimension" />
<!-- Left and right padding of the underline indicator. -->
<attr name="footerIndicatorUnderlinePadding" format="dimension" />
<!-- Padding between the bottom of the title and the footer. -->
<attr name="footerPadding" format="dimension" />
<!-- Position of the line. -->
<attr name="linePosition">
<enum name="bottom" value="0"/>
<enum name="top" value="1"/>
</attr>
<!-- Color of the selected title. -->
<attr name="selectedColor" />
<!-- Whether or not the selected item is displayed as bold. -->
<attr name="selectedBold" format="boolean" />
<!-- Color of regular titles. -->
<attr name="android:textColor" />
<!-- Size of title text. -->
<attr name="android:textSize" />
<!-- Padding between titles when bumping into each other. -->
<attr name="titlePadding" format="dimension" />
<!-- Padding between titles and the top of the View. -->
<attr name="topPadding" format="dimension" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
<declare-styleable name="UnderlinePageIndicator">
<!-- Whether or not the selected indicator fades. -->
<attr name="fades" format="boolean" />
<!-- Length of the delay to fade the indicator. -->
<attr name="fadeDelay" format="integer" />
<!-- Length of the indicator fade to transparent. -->
<attr name="fadeLength" format="integer" />
<!-- Color of the selected line that represents the current page. -->
<attr name="selectedColor" />
<!-- View background -->
<attr name="android:background"/>
</declare-styleable>
</resources>

View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 Jake Wharton
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>
<bool name="default_circle_indicator_centered">true</bool>
<color name="default_circle_indicator_fill_color">#FFFFFFFF</color>
<color name="default_circle_indicator_page_color">#00000000</color>
<integer name="default_circle_indicator_orientation">0</integer>
<dimen name="default_circle_indicator_radius">3dp</dimen>
<bool name="default_circle_indicator_snap">false</bool>
<color name="default_circle_indicator_stroke_color">@color/cpp_metro_button_light</color>
<dimen name="default_circle_indicator_stroke_width">1px</dimen>
<dimen name="default_line_indicator_line_width">12dp</dimen>
<dimen name="default_line_indicator_gap_width">4dp</dimen>
<dimen name="default_line_indicator_stroke_width">1dp</dimen>
<color name="default_line_indicator_selected_color">#FF33B5E5</color>
<color name="default_line_indicator_unselected_color">#FFBBBBBB</color>
<bool name="default_line_indicator_centered">true</bool>
<dimen name="default_title_indicator_clip_padding">4dp</dimen>
<color name="default_title_indicator_footer_color">#FF33B5E5</color>
<dimen name="default_title_indicator_footer_line_height">2dp</dimen>
<integer name="default_title_indicator_footer_indicator_style">2</integer>
<dimen name="default_title_indicator_footer_indicator_height">4dp</dimen>
<dimen name="default_title_indicator_footer_indicator_underline_padding">20dp</dimen>
<dimen name="default_title_indicator_footer_padding">7dp</dimen>
<integer name="default_title_indicator_line_position">0</integer>
<color name="default_title_indicator_selected_color">#FFFFFFFF</color>
<bool name="default_title_indicator_selected_bold">true</bool>
<color name="default_title_indicator_text_color">#BBFFFFFF</color>
<dimen name="default_title_indicator_text_size">15dp</dimen>
<dimen name="default_title_indicator_title_padding">5dp</dimen>
<dimen name="default_title_indicator_top_padding">7dp</dimen>
<bool name="default_underline_indicator_fades">true</bool>
<integer name="default_underline_indicator_fade_delay">300</integer>
<integer name="default_underline_indicator_fade_length">400</integer>
<color name="default_underline_indicator_selected_color">#FF33B5E5</color>
</resources>