├── .gitignore
├── README.md
├── viewflow-example
├── .classpath
├── .project
├── AndroidManifest.xml
├── assets
│ └── fonts
│ │ └── Antic.ttf
├── default.properties
├── res
│ ├── drawable-hdpi
│ │ └── icon.png
│ ├── drawable-ldpi
│ │ └── icon.png
│ ├── drawable-mdpi
│ │ └── icon.png
│ ├── drawable
│ │ ├── android.jpg
│ │ ├── cupcake.jpg
│ │ ├── donut.jpg
│ │ ├── eclair.png
│ │ ├── froyo.png
│ │ ├── gingerbread.png
│ │ ├── honeycomb.png
│ │ └── icecream.png
│ ├── layout
│ │ ├── circle_layout.xml
│ │ ├── day_view.xml
│ │ ├── diff_view1.xml
│ │ ├── diff_view2.xml
│ │ ├── flow_item.xml
│ │ ├── image_item.xml
│ │ ├── main.xml
│ │ └── title_layout.xml
│ └── values
│ │ ├── color.xml
│ │ └── strings.xml
├── screen.png
├── screen2.png
└── src
│ └── org
│ └── taptwo
│ └── android
│ └── widget
│ └── viewflow
│ └── example
│ ├── AndroidVersionAdapter.java
│ ├── AsyncAdapter.java
│ ├── AsyncDataFlowExample.java
│ ├── CircleViewFlowExample.java
│ ├── DiffAdapter.java
│ ├── DiffViewFlowExample.java
│ ├── ImageAdapter.java
│ ├── TitleViewFlowExample.java
│ └── ViewFlowExample.java
└── viewflow
├── .classpath
├── .project
├── AndroidManifest.xml
├── build.xml
├── default.properties
├── res
├── drawable
│ └── icon.png
└── values
│ ├── attrs.xml
│ └── strings.xml
└── src
└── org
└── taptwo
└── android
└── widget
├── CircleFlowIndicator.java
├── FlowIndicator.java
├── TitleFlowIndicator.java
├── TitleProvider.java
└── ViewFlow.java
/.gitignore:
--------------------------------------------------------------------------------
1 | bin/
2 | .settings
3 | bin
4 | gen
5 | target
6 | local.properties
7 | proguard.cfg
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # View Flow for Android
2 |
3 | ViewFlow is an Android UI widget providing a horizontally scrollable [ViewGroup](http://developer.android.com/reference/android/view/ViewGroup.html) with items populated from an [Adapter](http://developer.android.com/reference/android/widget/Adapter.html). Scroll down to the bottom of the page for a screen shot.
4 |
5 | The component is a [Library Project](http://developer.android.com/guide/developing/eclipse-adt.html#libraryProject). This means that there's no need to copy-paste resources into your own project, simply add the viewflow component as a reference to any project.
6 |
7 | ## When to use
8 | This library might be suitable if you have an indeterminate number of views in your viewflow, if instead you have a static numbers of views you ought to look at Fragments and the ViewPager in the Compatibility Library instead.
9 |
10 | ## Usage
11 |
12 | ### In your layout
13 |
14 |
18 |
19 | The use of `app:sidebuffer` is optional. It defines the number of Views to buffer on each side of the currently shown View. The default sidebuffer is 3, making up a grand total of 7 (3 * 2 + 1) Views loaded at a time (at max).
20 | To be able to use the more convenient `app:sidebuffer` attribute, the application namespace must be included in the same manner as the android namespace is. Please refer to the layout main.xml in the example project for a full example. Again, note that it's the application namespace and *not* the viewflow namespace that must be referred like `xmlns:app="http://schemas.android.com/apk/res/your.application.package.here"`.
21 |
22 | ### In your activity
23 |
24 | ViewFlow viewFlow = (ViewFlow) findViewById(R.id.viewflow);
25 | viewFlow.setAdapter(myAdapter);
26 |
27 | Setting a different initial position (0 being default) is as easy as:
28 |
29 | viewFlow.setAdapter(myAdapter, 8);
30 |
31 | Although possible, you should not call `setSelection(...)` immediately after calling `setAdapter(myAdapter)` as that might load unnecessary views giving you a decrease in performance.
32 |
33 | ### Listen on screen change events
34 |
35 | If you need to listen to screen change events you would want to implement your own `ViewFlow.ViewSwitchListener` and pass it to the `setOnViewSwitchListener()` method.
36 |
37 | viewFlow.setOnViewSwitchListener(new ViewSwitchListener() {
38 | public void onSwitched(View v, int position) {
39 | // Your code here
40 | }
41 | });
42 |
43 | ### Listen on initialize view events
44 |
45 | If you need a lazy View initialization you would want to implement your own `ViewFlow.ViewLazyInitializeListener` and pass it to the `setOnViewLazyInitializeListener()` method.
46 |
47 | viewFlow.setOnViewLazyInitializeListener(new ViewLazyInitializeListener() {
48 | public void onViewLazyInitialize(View view, int position) {
49 | // Your code here e.g.
50 | ((MyAdapter)((AbsListView)view).getAdapter()).initializeData();
51 | }
52 | });
53 |
54 | ### Flow Indicator
55 | It is also possible to add a flow view indicator to your layout. The purpose of a `FlowIndicator` is to present a visual representation of where in the item list focus is at. You may either implement a `FlowIndicator` yourself or use an implementation provided by the View Flow library. The View Flow library currently supports the following indicators:
56 |
57 | #### Circle Flow Indicator ####
58 | This indicator shows a circle for each `View` in the adapter with a special circle representing the currently selected view (see screenshot below).
59 |
60 |
64 |
65 | And then you'll need to connect your `ViewFlow` with the `FlowIndicator`:
66 |
67 | CircleFlowIndicator indic = (CircleFlowIndicator) findViewById(R.id.viewflowindic);
68 | viewFlow.setFlowIndicator(indic);
69 |
70 | By default, the 'active' indicator moves smoothly from one 'inactive' indicator
71 | to the next, as the user scrolls. If you set the `snap` attribute to `true`, it
72 | will instead jump to the next position when the flow settles at the next page.
73 |
74 | The following attributes are supported: `activeColor`, `inactiveColor`,
75 | `activeType` (either fill or stroke), `inactiveType` (either fill or stroke),
76 | `fadeOut` (time in ms until indicator fades out, 0 = never), `radius`, `sync`
77 | (see above).
78 |
79 | #### Title Flow Indicator ####
80 | This indicator presents the title of the previous, current and next `View` in the adapter (see screenshot below).
81 |
82 |
90 |
91 | And then you'll need to connect your `ViewFlow` with the `FlowIndicator`:
92 |
93 | TitleFlowIndicator indicator = (TitleFlowIndicator) findViewById(R.id.viewflowindic);
94 | indicator.setTitleProvider(myTitleProvider);
95 | viewFlow.setFlowIndicator(indicator);
96 |
97 | ## Building a jar file
98 | If you rather want a jar file instead of a including the project as an android library, run `ant jar` in the `android-viewflow/viewflow` folder, to build a jar file.
99 |
100 | ## Caveats ##
101 | The manifest states a min sdk version of 4, which is true. But in any case you want to support an api level < 8 you will have to forward an `onConfigurationChanged` event to the `ViewFlow` from your `Activity`. I know this isn't a very nice solution, feel free to propose better ones!
102 |
103 | @Override
104 | public void onConfigurationChanged(Configuration newConfig) {
105 | super.onConfigurationChanged(newConfig);
106 | viewFlow.onConfigurationChanged(newConfig);
107 | }
108 |
109 | ## Contributions
110 | The following persons deserves a mention for their contributions:
111 |
112 | * Eric Taix
113 | * Marc Reichelt,
114 |
115 | ### Want to contribute?
116 |
117 | GitHub has some great articles on [how to get started with Git and GitHub](http://help.github.com/) and how to [fork a project](http://help.github.com/forking/).
118 |
119 | Contributers are recommended to fork the app on GitHub (but don't have too). Create a feature branch, push the branch to git hub, press Pull Request and write a simple explanation.
120 |
121 | One fix per commit. If let's say a commit closes the open issue 12. Just add `closes #12` in your commit message to close that issue automagically.
122 |
123 | If you still feel uncomfortable contributing the project github-wise, don't hesistate to send a regular patch.
124 |
125 | All code that is contributed must be compliant with [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0.html).
126 |
127 | ## License
128 | Copyright (c) 2011 [Patrik Åkerfeldt](http://about.me/pakerfeldt)
129 |
130 | Licensed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html)
131 |
132 |  
133 |
134 |
135 |
136 |
--------------------------------------------------------------------------------
/viewflow-example/.classpath:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/viewflow-example/.project:
--------------------------------------------------------------------------------
1 |
2 |
3 | viewflow-example
4 |
5 |
6 |
7 |
8 |
9 | com.android.ide.eclipse.adt.ResourceManagerBuilder
10 |
11 |
12 |
13 |
14 | com.android.ide.eclipse.adt.PreCompilerBuilder
15 |
16 |
17 |
18 |
19 | org.eclipse.jdt.core.javabuilder
20 |
21 |
22 |
23 |
24 | com.android.ide.eclipse.adt.ApkBuilder
25 |
26 |
27 |
28 |
29 |
30 | com.android.ide.eclipse.adt.AndroidNature
31 | org.eclipse.jdt.core.javanature
32 |
33 |
34 |
35 | org_taptwo_android_widget_viewflow_src
36 | 2
37 | _android_org_taptwo_android_widget_viewflow_7cfa4d63/src
38 |
39 |
40 | viewflow_src
41 | 2
42 | _android_viewflow_474f6153/src
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/viewflow-example/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
7 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/viewflow-example/assets/fonts/Antic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/assets/fonts/Antic.ttf
--------------------------------------------------------------------------------
/viewflow-example/default.properties:
--------------------------------------------------------------------------------
1 | # This file is automatically generated by Android Tools.
2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED!
3 | #
4 | # This file must be checked in Version Control Systems.
5 | #
6 | # To customize properties used by the Ant build system use,
7 | # "build.properties", and override values to adapt the script to your
8 | # project structure.
9 |
10 | # Project target.
11 | target=android-8
12 | android.library.reference.1=../viewflow/
13 |
--------------------------------------------------------------------------------
/viewflow-example/res/drawable-hdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable-hdpi/icon.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable-ldpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable-ldpi/icon.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable-mdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable-mdpi/icon.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/android.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/android.jpg
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/cupcake.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/cupcake.jpg
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/donut.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/donut.jpg
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/eclair.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/eclair.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/froyo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/froyo.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/gingerbread.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/gingerbread.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/honeycomb.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/honeycomb.png
--------------------------------------------------------------------------------
/viewflow-example/res/drawable/icecream.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/res/drawable/icecream.png
--------------------------------------------------------------------------------
/viewflow-example/res/layout/circle_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
15 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/day_view.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
8 |
9 |
12 |
13 |
15 |
16 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/diff_view1.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/diff_view2.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/flow_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/image_item.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/viewflow-example/res/layout/title_layout.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
9 |
15 |
16 |
17 |
20 |
21 |
--------------------------------------------------------------------------------
/viewflow-example/res/values/color.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #58567D
4 |
5 |
--------------------------------------------------------------------------------
/viewflow-example/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Hello World, ViewFlowExample!
4 | Viewflow examples
5 | TitleFlowIndicator
6 | CircleFlowIndicator
7 | DifferentViewFlow
8 | AsyncDataLoading
9 |
10 |
--------------------------------------------------------------------------------
/viewflow-example/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/screen.png
--------------------------------------------------------------------------------
/viewflow-example/screen2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/screen2.png
--------------------------------------------------------------------------------
/viewflow-example/src/org/taptwo/android/widget/viewflow/example/AndroidVersionAdapter.java:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/pakerfeldt/android-viewflow/3da74fa32a935bcbb37e5ebeb270477cde1985d4/viewflow-example/src/org/taptwo/android/widget/viewflow/example/AndroidVersionAdapter.java
--------------------------------------------------------------------------------
/viewflow-example/src/org/taptwo/android/widget/viewflow/example/AsyncAdapter.java:
--------------------------------------------------------------------------------
1 | package org.taptwo.android.widget.viewflow.example;
2 |
3 | import java.text.DateFormat;
4 | import java.text.SimpleDateFormat;
5 | import java.util.Calendar;
6 | import java.util.Date;
7 |
8 | import org.taptwo.android.widget.TitleProvider;
9 | import org.taptwo.android.widget.viewflow.example.R;
10 |
11 | import android.content.Context;
12 | import android.os.AsyncTask;
13 | import android.view.LayoutInflater;
14 | import android.view.View;
15 | import android.view.ViewGroup;
16 | import android.widget.BaseAdapter;
17 | import android.widget.ProgressBar;
18 | import android.widget.TextView;
19 |
20 |
21 | public class AsyncAdapter extends BaseAdapter implements TitleProvider {
22 |
23 | private LayoutInflater mInflater;
24 |
25 | private static final DateFormat dfTitle = new SimpleDateFormat("E, dd MMM");
26 |
27 | private static final int daysDepth = 10;
28 | private static final int daysSize = daysDepth * 2 + 1;
29 |
30 | private static Date[] dates = new Date[ daysSize ];
31 | private static String[] content = new String[ daysSize ];
32 |
33 |
34 | private class ViewHolder {
35 | ProgressBar mProgressBar;
36 | View mContent;
37 | TextView mDate;
38 | }
39 |
40 |
41 | public AsyncAdapter(Context context) {
42 | mInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
43 | prepareDates();
44 | }
45 |
46 | @Override
47 | public String getItem(int position) {
48 | return content[position];
49 | }
50 |
51 | @Override
52 | public long getItemId(int position) {
53 | return position;
54 | }
55 |
56 | @Override
57 | public View getView(int position, View convertView, ViewGroup parent) {
58 | return drawView(position, convertView);
59 | }
60 |
61 | private View drawView(int position, View view) {
62 | ViewHolder holder = null;
63 |
64 | if(view == null) {
65 | view = mInflater.inflate(R.layout.day_view, null);
66 |
67 | holder = new ViewHolder();
68 |
69 | holder.mProgressBar = (ProgressBar) view.findViewById(R.id.progress);
70 | holder.mDate = (TextView) view.findViewById(R.id.date);
71 | holder.mContent = (View) view.findViewById(R.id.content);
72 |
73 | view.setTag(holder);
74 | } else {
75 | holder = (ViewHolder) view.getTag();
76 | }
77 |
78 |
79 | final String o = getItem(position);
80 | if (o != null) {
81 | holder.mProgressBar.setVisibility(View.GONE);
82 | holder.mDate.setText(o);
83 | holder.mContent.setVisibility(View.VISIBLE);
84 | }
85 | else {
86 | new LoadContentTask().execute(position, view);
87 |
88 | holder.mContent.setVisibility(View.GONE);
89 | holder.mProgressBar.setVisibility(View.VISIBLE);
90 | }
91 |
92 | return view;
93 | }
94 |
95 | @Override
96 | public String getTitle(int position) {
97 | return dfTitle.format( dates[position] );
98 | }
99 |
100 | @Override
101 | public int getCount() {
102 | return dates.length;
103 | }
104 |
105 | public int getTodayId() {
106 | return daysDepth;
107 | }
108 |
109 | public Date getTodayDate() {
110 | return dates[daysDepth];
111 | }
112 |
113 | /**
114 | * Prepare dates for navigation, to past and to future
115 | */
116 | private void prepareDates() {
117 | Date today = new Date();
118 |
119 | Calendar calPast = Calendar.getInstance();
120 | Calendar calFuture = Calendar.getInstance();
121 |
122 | calPast.setTime(today);
123 | calFuture.setTime(today);
124 |
125 | dates[ daysDepth ] = calPast.getTime();
126 | for (int i = 1; i <= daysDepth; i++) {
127 | calPast.add( Calendar.DATE, -1 );
128 | dates[ daysDepth - i ] = calPast.getTime();
129 |
130 | calFuture.add( Calendar.DATE, 1 );
131 | dates[ daysDepth + i ] = calFuture.getTime();
132 | }
133 | }
134 |
135 |
136 | private class LoadContentTask extends AsyncTask