├── .gitignore ├── FlipShare ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── wangyuwei │ │ └── flipshare │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── me │ │ └── wangyuwei │ │ └── flipshare │ │ ├── FlipShareView.java │ │ └── ShareItem.java │ └── test │ └── java │ └── me │ └── wangyuwei │ └── flipshare │ └── ExampleUnitTest.java ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── me │ │ └── wangyuwei │ │ └── flipshare │ │ └── ApplicationTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── me │ │ │ └── wangyuwei │ │ │ └── flipshare │ │ │ └── MainActivity.java │ └── res │ │ ├── layout │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ ├── ic_facebook.png │ │ ├── ic_google.png │ │ ├── ic_launcher.png │ │ └── ic_twitter.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ └── ic_launcher.png │ │ ├── values-w820dp │ │ └── dimens.xml │ │ └── values │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── me │ └── wangyuwei │ └── flipshare │ └── ExampleUnitTest.java ├── build.gradle ├── checkstyle.xml ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshots └── flipshare.gif └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea 5 | .DS_Store 6 | /build 7 | /captures 8 | -------------------------------------------------------------------------------- /FlipShare/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /FlipShare/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | apply plugin: 'com.jfrog.bintray' 3 | apply plugin: 'com.github.dcendents.android-maven' 4 | 5 | group = 'me.wangyuwei' // Change this to match your package name 6 | version = '1.0.2' // Change this to match your version number 7 | 8 | android { 9 | compileSdkVersion 23 10 | buildToolsVersion "23.0.1" 11 | 12 | defaultConfig { 13 | minSdkVersion 15 14 | targetSdkVersion 23 15 | versionCode 1 16 | versionName "1.0" 17 | } 18 | buildTypes { 19 | release { 20 | minifyEnabled false 21 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 22 | } 23 | } 24 | } 25 | 26 | dependencies { 27 | compile fileTree(dir: 'libs', include: ['*.jar']) 28 | testCompile 'junit:junit:4.12' 29 | compile 'com.android.support:appcompat-v7:23.1.1' 30 | } 31 | 32 | task generateSourcesJar(type: Jar) { 33 | from android.sourceSets.main.java.srcDirs 34 | classifier 'sources' 35 | } 36 | 37 | task generateJavadocs(type: Javadoc) { 38 | source = android.sourceSets.main.java.srcDirs 39 | classpath += project.files(android.getBootClasspath() 40 | .join(File.pathSeparator)) 41 | } 42 | 43 | task generateJavadocsJar(type: Jar) { 44 | from generateJavadocs.destinationDir 45 | classifier 'javadoc' 46 | } 47 | 48 | artifacts { 49 | // archives generateJavaDocsJar 50 | archives generateSourcesJar 51 | } 52 | 53 | Properties properties = new Properties() 54 | properties.load(project.rootProject.file('local.properties').newDataInputStream()) 55 | bintray { 56 | user = properties.getProperty("bintray.user") 57 | key = properties.getProperty("bintray.key") 58 | pkg { 59 | repo = 'maven' 60 | name = 'FlipShare' 61 | desc = "It's a cool way to show share widget." 62 | 63 | version { 64 | name = '1.0.2' 65 | desc = 'It is a cool way to show share widget.' 66 | vcsTag = 'android, animation, view, splash' 67 | } 68 | 69 | licenses = ['Apache-2.0'] 70 | vcsUrl = 'https://github.com/JeasonWong/FlipShare.git' 71 | websiteUrl = 'https://github.com/JeasonWong/FlipShare' 72 | 73 | labels = ['android'] 74 | publish = true 75 | publicDownloadNumbers = true 76 | } 77 | configurations = ['archives'] 78 | } -------------------------------------------------------------------------------- /FlipShare/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wscn/Documents/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /FlipShare/src/androidTest/java/me/wangyuwei/flipshare/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package me.wangyuwei.flipshare; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /FlipShare/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /FlipShare/src/main/java/me/wangyuwei/flipshare/FlipShareView.java: -------------------------------------------------------------------------------- 1 | package me.wangyuwei.flipshare; 2 | 3 | import android.animation.Animator; 4 | import android.animation.AnimatorSet; 5 | import android.animation.ObjectAnimator; 6 | import android.animation.ValueAnimator; 7 | import android.app.Activity; 8 | import android.content.Context; 9 | import android.graphics.Camera; 10 | import android.graphics.Canvas; 11 | import android.graphics.Color; 12 | import android.graphics.Matrix; 13 | import android.graphics.Paint; 14 | import android.graphics.Path; 15 | import android.graphics.PointF; 16 | import android.graphics.Rect; 17 | import android.graphics.RectF; 18 | import android.support.annotation.IntDef; 19 | import android.text.TextUtils; 20 | import android.view.MotionEvent; 21 | import android.view.View; 22 | import android.view.ViewGroup; 23 | import android.view.Window; 24 | import android.view.WindowManager; 25 | import android.view.animation.LinearInterpolator; 26 | 27 | import java.util.ArrayList; 28 | import java.util.Collection; 29 | import java.util.List; 30 | 31 | /** 32 | * 作者: 巴掌 on 16/9/1 21:38 33 | * Github: https://github.com/JeasonWong 34 | */ 35 | public class FlipShareView extends View { 36 | 37 | private static final int STATUS_NONE = 0; 38 | private static final int STATUS_DOWN = 1; 39 | private static final int STATUS_UP = 2; 40 | 41 | public static final int TYPE_VERTICLE = 0; 42 | public static final int TYPE_HORIZONTAL = 1; 43 | public static final int TYPE_SLIDE = 1 << 1; 44 | 45 | private int mStatus = STATUS_NONE; 46 | 47 | private Paint mPaint; 48 | private Path mPath; 49 | private Camera mCamera; 50 | private Matrix mMatrix; 51 | //item's flip degree 52 | private float mDegree; 53 | //item's shake degree 54 | private float mItemShakeDegree; 55 | //current item which is showing 56 | private int mCurrentItem = 0; 57 | //everyItem's animation duration 58 | private int mDuration = 300; 59 | //total window view's background color 60 | private int mBackgroundColor = 0x00FFFFFF; 61 | //separate line's color 62 | private int mSeparateLineColor = Color.TRANSPARENT; 63 | //separate line's height 64 | private int mSeparateLineHeight = dip2px(0.4f); 65 | //background color area 66 | private RectF mBgRect; 67 | //shareItem's width 68 | private int mItemWidth = dip2px(140); 69 | //shareItem's height 70 | private int mItemHeight = dip2px(50); 71 | //shareItem's left x position 72 | private int mItemLeft = dip2px(0); 73 | //shareItem's top y position 74 | private int mItemTop = dip2px(50); 75 | //item's corner 76 | private int mCorner = dip2px(6); 77 | //triangle's height 78 | private int mTriangleHeight = dip2px(4); 79 | //border's margin 80 | private int mBorderMargin = dip2px(5); 81 | //the first shown item's top y coordinate 82 | private int mFirstItemTop; 83 | //screen width 84 | private int mScreenWidth; 85 | //screen height 86 | private int mScreenHeight; 87 | //parent view is used to position 88 | private View mParentView; 89 | //shareItem lists 90 | private List mItemList = new ArrayList<>(); 91 | private List mItemRectList = new ArrayList<>(); 92 | 93 | private int mAnimType = TYPE_VERTICLE; 94 | private final List mTotalAnimList = new ArrayList<>(); 95 | private ObjectAnimator mAlphaAnim; 96 | 97 | private OnFlipClickListener onFlipClickListener; 98 | 99 | public FlipShareView(Context context, Window window, View parentView) { 100 | super(context); 101 | mParentView = parentView; 102 | mScreenWidth = getResources().getDisplayMetrics().widthPixels; 103 | mScreenHeight = getResources().getDisplayMetrics().heightPixels; 104 | mBgRect = new RectF(0, 0, mScreenWidth, mScreenHeight); 105 | addView(window); 106 | initView(); 107 | } 108 | 109 | private void addView(Window window) { 110 | WindowManager.LayoutParams params = new WindowManager.LayoutParams(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); 111 | window.addContentView(this, params); 112 | } 113 | 114 | private void initView() { 115 | mPath = new Path(); 116 | mPaint = new Paint(); 117 | mPaint.setAntiAlias(true); 118 | mPaint.setStyle(Paint.Style.FILL); 119 | mPaint.setTextSize(sp2px(14)); 120 | mCamera = new Camera(); 121 | mMatrix = new Matrix(); 122 | 123 | mAlphaAnim = ObjectAnimator.ofFloat(this, "alpha", 1.0f, 0f); 124 | mAlphaAnim.setDuration(200); 125 | mAlphaAnim.addListener(new MyAnimListener() { 126 | @Override 127 | public void onAnimationEnd(Animator animation) { 128 | removeView(); 129 | if (onFlipClickListener != null) { 130 | onFlipClickListener.dismiss(); 131 | } 132 | } 133 | }); 134 | 135 | int parentViewWidth = mParentView.getMeasuredWidth(); 136 | int parentViewHeight = mParentView.getMeasuredHeight(); 137 | int parentLeft = mParentView.getLeft(); 138 | int[] location = new int[2]; 139 | mParentView.getLocationInWindow(location); 140 | int parentTop = location[1] - parentViewHeight / 2; 141 | int parentBottom = location[1] + parentViewHeight / 2; 142 | int parentMiddleX = parentLeft + parentViewWidth / 2; 143 | 144 | if (location[1] < mScreenHeight / 2) { 145 | mStatus = STATUS_DOWN; 146 | mItemTop = parentBottom + dip2px(5); 147 | mFirstItemTop = mItemTop + dip2px(6); 148 | } else { 149 | mStatus = STATUS_UP; 150 | mItemTop = parentTop - dip2px(5); 151 | mFirstItemTop = mItemTop - dip2px(6); 152 | } 153 | 154 | if (parentMiddleX + mItemWidth / 2 > mScreenWidth) { 155 | mItemLeft = mScreenWidth - mItemWidth - mBorderMargin; 156 | } else if (parentMiddleX - mItemWidth / 2 < 0) { 157 | mItemLeft = mBorderMargin; 158 | } else { 159 | mItemLeft = parentMiddleX - mItemWidth / 2; 160 | } 161 | 162 | 163 | } 164 | 165 | @Override 166 | protected void onDraw(Canvas canvas) { 167 | super.onDraw(canvas); 168 | switch (mStatus) { 169 | case STATUS_NONE: 170 | 171 | break; 172 | case STATUS_DOWN: 173 | drawBackground(canvas); 174 | drawFlipDownItem(canvas); 175 | break; 176 | case STATUS_UP: 177 | drawBackground(canvas); 178 | drawFlipUpItem(canvas); 179 | break; 180 | } 181 | 182 | } 183 | 184 | private void drawBackground(Canvas canvas) { 185 | mPaint.setColor(mBackgroundColor); 186 | canvas.drawRect(mBgRect, mPaint); 187 | } 188 | 189 | private void drawFlipUpItem(Canvas canvas) { 190 | mItemRectList.clear(); 191 | 192 | for (int i = mItemList.size() - 1; i >= 0; i--) { 193 | canvas.save(); 194 | mCamera.save(); 195 | 196 | if (i < mItemList.size() - mCurrentItem - 1) { 197 | mCamera.restore(); 198 | canvas.restore(); 199 | continue; 200 | } else { 201 | if (i == mItemList.size() - mCurrentItem - 1) { 202 | if (mAnimType == TYPE_HORIZONTAL) { 203 | mCamera.rotateY(mDegree); 204 | } else if (mAnimType == TYPE_VERTICLE) { 205 | mCamera.rotateX(mDegree); 206 | } else if (mAnimType == TYPE_SLIDE) { 207 | mCamera.rotateZ(mDegree); 208 | } 209 | } else { 210 | if (mAnimType == TYPE_HORIZONTAL) { 211 | mCamera.rotateY(mItemShakeDegree / 2); 212 | } else if (mAnimType == TYPE_VERTICLE) { 213 | mCamera.rotateX(mItemShakeDegree); 214 | } else if (mAnimType == TYPE_SLIDE) { 215 | mCamera.rotateZ(mItemShakeDegree / 4); 216 | } 217 | } 218 | mCamera.getMatrix(mMatrix); 219 | if (mAnimType == TYPE_SLIDE) { 220 | mMatrix.preTranslate(-(mItemLeft + mItemWidth / 2), -mItemHeight / 2); 221 | mMatrix.postTranslate(mItemLeft + mItemWidth / 2, mItemHeight / 2); 222 | } else { 223 | mMatrix.preTranslate(-(mItemLeft + mItemWidth / 2), -(mItemTop - (mItemList.size() - i - 1) * mItemHeight)); 224 | mMatrix.postTranslate(mItemLeft + mItemWidth / 2, mItemTop - (mItemList.size() - i - 1) * mItemHeight); 225 | } 226 | 227 | canvas.concat(mMatrix); 228 | } 229 | 230 | mPaint.setColor(mItemList.get(i).bgColor); 231 | if (i == mItemList.size() - 1) { 232 | mPath.reset(); 233 | int parentMiddleX = mParentView.getLeft() + mParentView.getMeasuredWidth() / 2; 234 | mPath.moveTo(parentMiddleX, mItemTop); 235 | mPath.lineTo(parentMiddleX - mTriangleHeight, mFirstItemTop); 236 | mPath.lineTo(parentMiddleX + mTriangleHeight, mFirstItemTop); 237 | canvas.drawPath(mPath, mPaint); 238 | } 239 | 240 | if (i == 0) { 241 | mPath.reset(); 242 | mPath.moveTo(mItemLeft, mFirstItemTop - (mItemList.size() - 1) * mItemHeight); 243 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - 1) * mItemHeight); 244 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mItemHeight + mCorner); 245 | mPath.quadTo(mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mItemHeight 246 | , mItemLeft + mItemWidth - mCorner, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mItemHeight); 247 | mPath.lineTo(mItemLeft + mCorner, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mItemHeight); 248 | mPath.quadTo(mItemLeft, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mItemHeight 249 | , mItemLeft, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mItemHeight + mCorner); 250 | mPath.lineTo(mItemLeft, mFirstItemTop - (mItemList.size() - 1) * mItemHeight); 251 | canvas.drawPath(mPath, mPaint); 252 | mPaint.setColor(mSeparateLineColor); 253 | canvas.drawLine(mItemLeft, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mSeparateLineHeight 254 | , mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - 1) * mItemHeight - mSeparateLineHeight, mPaint); 255 | } else if (i == mItemList.size() - 1) { 256 | mPath.reset(); 257 | mPath.moveTo(mItemLeft, mFirstItemTop - (mItemList.size() - i) * mItemHeight); 258 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - i) * mItemHeight); 259 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - i) * mItemHeight + mItemHeight - mCorner); 260 | mPath.quadTo(mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - i) * mItemHeight + mItemHeight 261 | , mItemLeft + mItemWidth - mCorner, mFirstItemTop - (mItemList.size() - i) * mItemHeight + mItemHeight); 262 | mPath.lineTo(mItemLeft + mCorner, mFirstItemTop - (mItemList.size() - i) * mItemHeight + mItemHeight); 263 | mPath.quadTo(mItemLeft, mFirstItemTop - (mItemList.size() - i) * mItemHeight + mItemHeight 264 | , mItemLeft, mFirstItemTop - (mItemList.size() - i) * mItemHeight + mItemHeight - mCorner); 265 | mPath.lineTo(mItemLeft, mFirstItemTop - (mItemList.size() - i) * mItemHeight); 266 | canvas.drawPath(mPath, mPaint); 267 | } else { 268 | canvas.drawRect(mItemLeft, mFirstItemTop - mItemHeight - (mItemList.size() - i - 1) * mItemHeight 269 | , mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - i - 1) * mItemHeight, mPaint); 270 | mPaint.setColor(mSeparateLineColor); 271 | canvas.drawLine(mItemLeft, mFirstItemTop - (mItemList.size() - i - 1) * mItemHeight - mSeparateLineHeight 272 | , mItemLeft + mItemWidth, mFirstItemTop - (mItemList.size() - i - 1) * mItemHeight - mSeparateLineHeight, mPaint); 273 | } 274 | 275 | mItemRectList.add(new RectF(mItemLeft, (mFirstItemTop - mItemHeight) - i * mItemHeight, mItemLeft + mItemWidth,mFirstItemTop - i * mItemHeight)); 276 | 277 | drawTitle(canvas, i); 278 | drawIcon(canvas, i); 279 | 280 | mCamera.restore(); 281 | canvas.restore(); 282 | } 283 | 284 | } 285 | 286 | private void drawFlipDownItem(Canvas canvas) { 287 | 288 | mItemRectList.clear(); 289 | for (int i = 0; i < mItemList.size(); i++) { 290 | canvas.save(); 291 | mCamera.save(); 292 | 293 | if (i > mCurrentItem) { 294 | mCamera.restore(); 295 | canvas.restore(); 296 | continue; 297 | } else { 298 | if (i == mCurrentItem) { 299 | if (mAnimType == TYPE_HORIZONTAL) { 300 | mCamera.rotateY(mDegree); 301 | } else if (mAnimType == TYPE_VERTICLE) { 302 | mCamera.rotateX(mDegree); 303 | } else if (mAnimType == TYPE_SLIDE) { 304 | mCamera.rotateZ(mDegree); 305 | } 306 | } else { 307 | if (mAnimType == TYPE_HORIZONTAL) { 308 | mCamera.rotateY(mItemShakeDegree / 2); 309 | } else if (mAnimType == TYPE_VERTICLE) { 310 | mCamera.rotateX(mItemShakeDegree); 311 | } else if (mAnimType == TYPE_SLIDE) { 312 | mCamera.rotateZ(mItemShakeDegree); 313 | } 314 | } 315 | mCamera.getMatrix(mMatrix); 316 | if (mAnimType == TYPE_SLIDE) { 317 | mMatrix.preTranslate(-(mItemLeft + mItemWidth / 2), -mItemHeight / 2); 318 | mMatrix.postTranslate(mItemLeft + mItemWidth / 2, mItemHeight / 2); 319 | } else { 320 | mMatrix.preTranslate(-(mItemLeft + mItemWidth / 2), -(mItemTop + i * mItemHeight)); 321 | mMatrix.postTranslate(mItemLeft + mItemWidth / 2, mItemTop + i * mItemHeight); 322 | } 323 | canvas.concat(mMatrix); 324 | } 325 | 326 | mPaint.setColor(mItemList.get(i).bgColor); 327 | if (i == 0) { 328 | mPath.reset(); 329 | int parentMiddleX = mParentView.getLeft() + mParentView.getMeasuredWidth() / 2; 330 | mPath.moveTo(parentMiddleX, mItemTop); 331 | mPath.lineTo(parentMiddleX - mTriangleHeight, mFirstItemTop); 332 | mPath.lineTo(parentMiddleX + mTriangleHeight, mFirstItemTop); 333 | canvas.drawPath(mPath, mPaint); 334 | } 335 | 336 | if (i == 0) { 337 | mPath.reset(); 338 | mPath.moveTo(mItemLeft, mFirstItemTop + mItemHeight); 339 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop + mItemHeight); 340 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop + mCorner); 341 | mPath.quadTo(mItemLeft + mItemWidth, mFirstItemTop, mItemLeft + mItemWidth - mCorner, mFirstItemTop); 342 | mPath.lineTo(mItemLeft + mCorner, mFirstItemTop); 343 | mPath.quadTo(mItemLeft, mFirstItemTop, mItemLeft, mFirstItemTop + mCorner); 344 | mPath.lineTo(mItemLeft, mFirstItemTop + mItemHeight); 345 | canvas.drawPath(mPath, mPaint); 346 | } else if (i == mItemList.size() - 1) { 347 | mPath.reset(); 348 | mPath.moveTo(mItemLeft, mFirstItemTop + i * mItemHeight); 349 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop + i * mItemHeight); 350 | mPath.lineTo(mItemLeft + mItemWidth, mFirstItemTop + (i + 1) * mItemHeight - mCorner); 351 | mPath.quadTo(mItemLeft + mItemWidth, mFirstItemTop + (i + 1) * mItemHeight, mItemLeft + mItemWidth - mCorner, mFirstItemTop + (i + 1) * mItemHeight); 352 | mPath.lineTo(mItemLeft + mCorner, mFirstItemTop + (i + 1) * mItemHeight); 353 | mPath.quadTo(mItemLeft, mFirstItemTop + (i + 1) * mItemHeight, mItemLeft, mFirstItemTop + (i + 1) * mItemHeight - mCorner); 354 | mPath.lineTo(mItemLeft, mFirstItemTop + i * mItemHeight); 355 | canvas.drawPath(mPath, mPaint); 356 | } else { 357 | canvas.drawRect(mItemLeft, mFirstItemTop + i * mItemHeight, mItemLeft + mItemWidth, mFirstItemTop + mItemHeight + i * mItemHeight, mPaint); 358 | } 359 | 360 | mItemRectList.add(new RectF(mItemLeft, mFirstItemTop + i * mItemHeight, mItemLeft + mItemWidth, mFirstItemTop + mItemHeight + i * mItemHeight)); 361 | 362 | drawTitle(canvas, i); 363 | drawIcon(canvas, i); 364 | 365 | mCamera.restore(); 366 | canvas.restore(); 367 | } 368 | } 369 | 370 | private void drawTitle(Canvas canvas, int position) { 371 | ShareItem shareItem = mItemList.get(position); 372 | mPaint.setColor(shareItem.titleColor); 373 | if (mStatus == STATUS_DOWN) { 374 | canvas.drawText(shareItem.title, mItemLeft + dip2px(8) 375 | , mFirstItemTop + getTextHeight(shareItem.title, mPaint) / 2 + mItemHeight / 2 + position * mItemHeight, mPaint); 376 | } else if (mStatus == STATUS_UP) { 377 | canvas.drawText(shareItem.title, mItemLeft + dip2px(8) 378 | , mFirstItemTop + getTextHeight(shareItem.title, mPaint) / 2 - (mItemHeight / 2 + (mItemList.size() - position - 1) * mItemHeight), mPaint); 379 | } 380 | } 381 | 382 | private void drawIcon(Canvas canvas, int position) { 383 | ShareItem shareItem = mItemList.get(position); 384 | if (shareItem.icon != null) { 385 | float left = mItemLeft + mItemWidth - mItemHeight / 2 - dip2px(6); 386 | if (mStatus == STATUS_DOWN) { 387 | float top = mFirstItemTop + mItemHeight / 4 + position * mItemHeight; 388 | canvas.drawBitmap(shareItem.icon, null, new RectF(left, top, left + mItemHeight / 2, top + mItemHeight / 2), mPaint); 389 | } else if (mStatus == STATUS_UP) { 390 | float top = mFirstItemTop - (mItemHeight / 4 + (mItemList.size() - position - 1) * mItemHeight); 391 | canvas.drawBitmap(shareItem.icon, null, new RectF(left - mItemHeight / 2, top - mItemHeight / 2, left, top), mPaint); 392 | } 393 | 394 | } 395 | } 396 | 397 | public void startAnim() { 398 | 399 | if (mItemList.size() == 0) { 400 | throw new RuntimeException("At least set one shareItem"); 401 | } 402 | 403 | mTotalAnimList.clear(); 404 | 405 | for (int i = 0; i < mItemList.size(); i++) { 406 | final Collection animList = new ArrayList<>(); 407 | 408 | ValueAnimator itemShakeAnim; 409 | switch (mStatus) { 410 | case STATUS_DOWN: 411 | itemShakeAnim = ValueAnimator.ofFloat(0, 3, 0); 412 | break; 413 | case STATUS_UP: 414 | itemShakeAnim = ValueAnimator.ofFloat(0, -3, 0); 415 | break; 416 | default: 417 | itemShakeAnim = ValueAnimator.ofFloat(0); 418 | break; 419 | } 420 | itemShakeAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 421 | @Override 422 | public void onAnimationUpdate(ValueAnimator animation) { 423 | mItemShakeDegree = (float) animation.getAnimatedValue(); 424 | } 425 | }); 426 | 427 | ValueAnimator itemFlipAnim = ValueAnimator.ofFloat(-90, 8, 0); 428 | final int index = i; 429 | itemFlipAnim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { 430 | @Override 431 | public void onAnimationUpdate(ValueAnimator animation) { 432 | mDegree = (float) animation.getAnimatedValue(); 433 | mCurrentItem = index; 434 | invalidate(); 435 | } 436 | }); 437 | animList.add(itemFlipAnim); 438 | animList.add(itemShakeAnim); 439 | AnimatorSet set = new AnimatorSet(); 440 | set.setDuration(mDuration); 441 | set.setInterpolator(new LinearInterpolator()); 442 | set.playTogether(animList); 443 | mTotalAnimList.add(set); 444 | set.addListener(new MyAnimListener() { 445 | @Override 446 | public void onAnimationEnd(Animator animation) { 447 | if (index + 1 < mItemList.size()) { 448 | mTotalAnimList.get(index + 1).start(); 449 | } 450 | } 451 | }); 452 | 453 | } 454 | 455 | mTotalAnimList.get(0).start(); 456 | 457 | } 458 | 459 | public void setShareItemList(final List list) { 460 | mItemList.clear(); 461 | List items = list; 462 | for (ShareItem item : items) { 463 | if (!TextUtils.isEmpty(item.title)) { 464 | item.title = updateTitle(item.title, item.icon != null); 465 | } else { 466 | item.title = ""; 467 | } 468 | 469 | mItemList.add(item); 470 | } 471 | } 472 | 473 | private String updateTitle(String title, boolean hasIcon) { 474 | int textLength = title.length(); 475 | String suffix = ""; 476 | while (getTextWidth(title.substring(0, textLength) + "...", mPaint) > mItemWidth - dip2px(10) - (hasIcon ? (dip2px(6) + mItemHeight / 2) : 0)) { 477 | textLength--; 478 | suffix = "..."; 479 | } 480 | return title.substring(0, textLength) + suffix; 481 | } 482 | 483 | public void setItemDuration(int mils) { 484 | mDuration = mils; 485 | } 486 | 487 | public void setBackgroundColor(int color) { 488 | mBackgroundColor = color; 489 | } 490 | 491 | public void setSeparateLineColor(int separateLineColor) { 492 | mSeparateLineColor = separateLineColor; 493 | } 494 | 495 | private void dismiss() { 496 | for (Animator animator : mTotalAnimList) { 497 | animator.cancel(); 498 | } 499 | 500 | if (!mAlphaAnim.isRunning()) { 501 | mAlphaAnim.start(); 502 | } 503 | } 504 | 505 | private void removeView() { 506 | ViewGroup vg = (ViewGroup) this.getParent(); 507 | if (vg != null) { 508 | vg.removeView(this); 509 | } 510 | } 511 | 512 | @Override 513 | public boolean onTouchEvent(MotionEvent event) { 514 | switch (event.getAction()) { 515 | case MotionEvent.ACTION_DOWN: 516 | 517 | return true; 518 | case MotionEvent.ACTION_UP: 519 | for (int i = 0; i < mItemRectList.size(); i++) { 520 | if (onFlipClickListener != null && isPointInRect(new PointF(event.getX(), event.getY()), mItemRectList.get(i))) { 521 | onFlipClickListener.onItemClick(i); 522 | } 523 | } 524 | dismiss(); 525 | return true; 526 | } 527 | return true; 528 | } 529 | 530 | private boolean isPointInRect(PointF pointF, RectF targetRect) { 531 | if (pointF.x < targetRect.left) { 532 | return false; 533 | } 534 | if (pointF.x > targetRect.right) { 535 | return false; 536 | } 537 | if (pointF.y < targetRect.top) { 538 | return false; 539 | } 540 | if (pointF.y > targetRect.bottom) { 541 | return false; 542 | } 543 | return true; 544 | } 545 | 546 | private int dip2px(float dipValue) { 547 | final float scale = getContext().getResources().getDisplayMetrics().density; 548 | return (int) (dipValue * scale + 0.5f); 549 | } 550 | 551 | private int sp2px(float spValue) { 552 | final float fontScale = getContext().getResources().getDisplayMetrics().scaledDensity; 553 | return (int) (spValue * fontScale + 0.5f); 554 | } 555 | 556 | private float getTextHeight(String text, Paint paint) { 557 | Rect rect = new Rect(); 558 | paint.getTextBounds(text, 0, text.length(), rect); 559 | return rect.height() / 1.1f; 560 | } 561 | 562 | private float getTextWidth(String text, Paint paint) { 563 | return paint.measureText(text); 564 | } 565 | 566 | @IntDef(flag = true, value = {TYPE_VERTICLE, TYPE_HORIZONTAL, TYPE_SLIDE}) 567 | public @interface AnimType { 568 | } 569 | 570 | @AnimType 571 | public void setAnimType(@AnimType int animType) { 572 | mAnimType = animType; 573 | } 574 | 575 | public void setOnFlipClickListener(OnFlipClickListener onFlipClickListener) { 576 | this.onFlipClickListener = onFlipClickListener; 577 | } 578 | 579 | public interface OnFlipClickListener { 580 | void onItemClick(int position); 581 | 582 | void dismiss(); 583 | } 584 | 585 | private abstract class MyAnimListener implements Animator.AnimatorListener { 586 | @Override 587 | public void onAnimationStart(Animator animation) { 588 | 589 | } 590 | 591 | @Override 592 | public void onAnimationCancel(Animator animation) { 593 | 594 | } 595 | 596 | @Override 597 | public void onAnimationRepeat(Animator animation) { 598 | 599 | } 600 | } 601 | 602 | public static class Builder { 603 | 604 | private Activity mActivity; 605 | private View mParentView; 606 | private List mShareItemList = new ArrayList<>(); 607 | private int mMilliSecond = 300; 608 | private int mBgColor = 0x00FFFFFF; 609 | private int mAnimType = FlipShareView.TYPE_VERTICLE; 610 | private int mSeparateLineColor = Color.TRANSPARENT; 611 | 612 | public Builder(Activity activity, View parentView) { 613 | mActivity = activity; 614 | mParentView = parentView; 615 | } 616 | 617 | public Builder addItem(ShareItem shareItem) { 618 | mShareItemList.add(shareItem); 619 | return this; 620 | } 621 | 622 | public Builder addItems(List list) { 623 | mShareItemList.addAll(list); 624 | return this; 625 | } 626 | 627 | public Builder setItemDuration(int mils) { 628 | mMilliSecond = mils; 629 | return this; 630 | } 631 | 632 | public Builder setAnimType(@AnimType int animType) { 633 | mAnimType = animType; 634 | return this; 635 | } 636 | 637 | public Builder setBackgroundColor(int color) { 638 | mBgColor = color; 639 | return this; 640 | } 641 | 642 | public Builder setSeparateLineColor(int color) { 643 | mSeparateLineColor = color; 644 | return this; 645 | } 646 | 647 | public FlipShareView create() { 648 | FlipShareView flipShare = new FlipShareView(mActivity.getBaseContext(), mActivity.getWindow(), mParentView); 649 | flipShare.setShareItemList(mShareItemList); 650 | flipShare.setItemDuration(mMilliSecond); 651 | flipShare.setBackgroundColor(mBgColor); 652 | flipShare.setAnimType(mAnimType); 653 | flipShare.setSeparateLineColor(mSeparateLineColor); 654 | flipShare.startAnim(); 655 | return flipShare; 656 | } 657 | 658 | } 659 | 660 | } 661 | -------------------------------------------------------------------------------- /FlipShare/src/main/java/me/wangyuwei/flipshare/ShareItem.java: -------------------------------------------------------------------------------- 1 | package me.wangyuwei.flipshare; 2 | 3 | import android.graphics.Bitmap; 4 | import android.graphics.Color; 5 | 6 | /** 7 | * 作者: 巴掌 on 16/9/3 14:05 8 | * Github: https://github.com/JeasonWong 9 | */ 10 | public class ShareItem { 11 | 12 | public String title; 13 | public int titleColor = Color.BLACK; 14 | public int bgColor = Color.WHITE; 15 | public Bitmap icon; 16 | 17 | public ShareItem(String title) { 18 | this.title = title; 19 | } 20 | 21 | public ShareItem(String title, Bitmap icon) { 22 | this.title = title; 23 | this.icon = icon; 24 | } 25 | 26 | public ShareItem(String title, int bgColor) { 27 | this.title = title; 28 | this.bgColor = bgColor; 29 | } 30 | 31 | public ShareItem(String title, int titleColor, int bgColor) { 32 | this.title = title; 33 | this.titleColor = titleColor; 34 | this.bgColor = bgColor; 35 | } 36 | 37 | public ShareItem(String title, int bgColor, Bitmap icon) { 38 | this.title = title; 39 | this.bgColor = bgColor; 40 | this.icon = icon; 41 | } 42 | 43 | public ShareItem(String title, int titleColor, int bgColor, Bitmap icon) { 44 | this.title = title; 45 | this.titleColor = titleColor; 46 | this.bgColor = bgColor; 47 | this.icon = icon; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return "ShareItem{" 53 | + "title='" + title + '\'' 54 | + ", titleColor=" + titleColor 55 | + ", bgColor=" + bgColor 56 | + ", icon=" + icon 57 | + '}'; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /FlipShare/src/test/java/me/wangyuwei/flipshare/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package me.wangyuwei.flipshare; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * To work on unit tests, switch the Test Artifact in the Build Variants view. 9 | */ 10 | public class ExampleUnitTest { 11 | @Test 12 | public void addition_isCorrect() throws Exception { 13 | assertEquals(4, 2 + 2); 14 | } 15 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## What's FlipShare ? 2 | It's a cool way to show share widget. 3 | 4 | ## Demo 5 | 6 | ![Markdown](https://raw.githubusercontent.com/jeasonwong/FlipShare/master/screenshots/flipshare.gif) 7 | 8 | ## Usage 9 | 10 | step 1. Confirm your parentView to locate the share widget, and then you can custom by yourself. 11 | 12 | ```java 13 | FlipShareView share = new FlipShareView.Builder(this, mBtnLeftTop) 14 | .addItem(new ShareItem("Facebook", Color.WHITE, 0xff43549C, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_facebook))) 15 | .addItem(new ShareItem("Twitter", Color.WHITE, 0xff4999F0, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_twitter))) 16 | .addItem(new ShareItem("Google+", Color.WHITE, 0xffD9392D, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_google))) 17 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 18 | .setBackgroundColor(0x60000000) 19 | .setItemDuration(500) 20 | .setSeparateLineColor(0x30000000) 21 | .setAnimType(FlipShareView.TYPE_SLIDE) 22 | .create(); 23 | ``` 24 | step 2. Recognize some custom Attributes. 25 | 26 | **Animation type** 27 | 28 | ```java 29 | @IntDef(flag = true, value = {TYPE_VERTICLE, TYPE_HORIZONTAL, TYPE_SLIDE}) 30 | public @interface AnimType { 31 | } 32 | 33 | ``` 34 | 35 | **Builder** 36 | 37 | ```java 38 | public Builder addItem(ShareItem shareItem) { 39 | mShareItemList.add(shareItem); 40 | return this; 41 | } 42 | 43 | public Builder addItems(List list) { 44 | mShareItemList.addAll(list); 45 | return this; 46 | } 47 | 48 | public Builder setItemDuration(int mils) { 49 | mMilliSecond = mils; 50 | return this; 51 | } 52 | 53 | public Builder setAnimType(@AnimType int animType) { 54 | mAnimType = animType; 55 | return this; 56 | } 57 | 58 | public Builder setBackgroundColor(int color) { 59 | mBgColor = color; 60 | return this; 61 | } 62 | 63 | public Builder setSeparateLineColor(int color) { 64 | mSeparateLineColor = color; 65 | return this; 66 | } 67 | ``` 68 | 69 | step 3. Add OnFlipClickListener to get some callback. 70 | 71 | ```java 72 | share.setOnFlipClickListener(new FlipShareView.OnFlipClickListener() { 73 | @Override 74 | public void onItemClick(int position) { 75 | Toast.makeText(MainActivity.this, "position " + position + " is clicked.", Toast.LENGTH_SHORT).show(); 76 | } 77 | 78 | @Override 79 | public void dismiss() { 80 | } 81 | }); 82 | ``` 83 | 84 | ## Import 85 | 86 | Step 1. Add it in your project's build.gradle at the end of repositories: 87 | 88 | ```gradle 89 | repositories { 90 | maven { 91 | url 'https://dl.bintray.com/wangyuwei/maven' 92 | } 93 | } 94 | ``` 95 | 96 | Step 2. Add the dependency: 97 | 98 | ```gradle 99 | dependencies { 100 | compile 'me.wangyuwei:FlipShare:1.0.2' 101 | } 102 | ``` 103 | 104 | ### About Me 105 | 106 | [Weibo](http://weibo.com/WongYuwei) 107 | 108 | [Blog](http://www.wangyuwei.me) 109 | 110 | ### QQ Group 欢迎讨论 111 | 112 | **479729938** 113 | 114 | ##**License** 115 | 116 | ```license 117 | Copyright [2016] [JeasonWong of copyright owner] 118 | 119 | Licensed under the Apache License, Version 2.0 (the "License"); 120 | you may not use this file except in compliance with the License. 121 | You may obtain a copy of the License at 122 | 123 | http://www.apache.org/licenses/LICENSE-2.0 124 | 125 | Unless required by applicable law or agreed to in writing, software 126 | distributed under the License is distributed on an "AS IS" BASIS, 127 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 128 | See the License for the specific language governing permissions and 129 | limitations under the License. 130 | ``` -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 23 5 | buildToolsVersion "23.0.1" 6 | 7 | defaultConfig { 8 | applicationId "me.wangyuwei.coolshare" 9 | minSdkVersion 15 10 | targetSdkVersion 23 11 | versionCode 1 12 | versionName "1.0" 13 | } 14 | buildTypes { 15 | release { 16 | minifyEnabled false 17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 18 | } 19 | } 20 | } 21 | 22 | dependencies { 23 | compile fileTree(dir: 'libs', include: ['*.jar']) 24 | testCompile 'junit:junit:4.12' 25 | compile 'com.android.support:appcompat-v7:23.1.1' 26 | compile project(':FlipShare') 27 | } 28 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in /Users/wscn/Documents/android-sdk-macosx/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/androidTest/java/me/wangyuwei/flipshare/ApplicationTest.java: -------------------------------------------------------------------------------- 1 | package me.wangyuwei.flipshare; 2 | 3 | import android.app.Application; 4 | import android.test.ApplicationTestCase; 5 | 6 | /** 7 | * Testing Fundamentals 8 | */ 9 | public class ApplicationTest extends ApplicationTestCase { 10 | public ApplicationTest() { 11 | super(Application.class); 12 | } 13 | } -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/java/me/wangyuwei/flipshare/MainActivity.java: -------------------------------------------------------------------------------- 1 | package me.wangyuwei.flipshare; 2 | 3 | import android.graphics.BitmapFactory; 4 | import android.graphics.Color; 5 | import android.os.Bundle; 6 | import android.support.v7.app.AppCompatActivity; 7 | import android.view.View; 8 | import android.widget.Button; 9 | import android.widget.Toast; 10 | 11 | public class MainActivity extends AppCompatActivity implements View.OnClickListener { 12 | 13 | private Button mBtnLeftTop; 14 | private Button mBtnMiddleTop; 15 | private Button mBtnRightTop; 16 | private Button mBtnLeftBottom; 17 | private Button mBtnMiddleBottom; 18 | private Button mBtnRightBottom; 19 | 20 | @Override 21 | protected void onCreate(Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_main); 24 | 25 | mBtnLeftTop = (Button) findViewById(R.id.btn_left_top); 26 | mBtnMiddleTop = (Button) findViewById(R.id.btn_middle_top); 27 | mBtnRightTop = (Button) findViewById(R.id.btn_right_top); 28 | mBtnLeftBottom = (Button) findViewById(R.id.btn_left_bottom); 29 | mBtnMiddleBottom = (Button) findViewById(R.id.btn_middle_bottom); 30 | mBtnRightBottom = (Button) findViewById(R.id.btn_right_bottom); 31 | mBtnLeftTop.setOnClickListener(this); 32 | mBtnMiddleTop.setOnClickListener(this); 33 | mBtnRightTop.setOnClickListener(this); 34 | mBtnLeftBottom.setOnClickListener(this); 35 | mBtnMiddleBottom.setOnClickListener(this); 36 | mBtnRightBottom.setOnClickListener(this); 37 | 38 | } 39 | 40 | @Override 41 | public void onClick(View v) { 42 | switch (v.getId()) { 43 | case R.id.btn_left_top: 44 | FlipShareView share = new FlipShareView.Builder(this, mBtnLeftTop) 45 | .addItem(new ShareItem("Facebook", Color.WHITE, 0xff43549C, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_facebook))) 46 | .addItem(new ShareItem("Twitter", Color.WHITE, 0xff4999F0, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_twitter))) 47 | .addItem(new ShareItem("Google+", Color.WHITE, 0xffD9392D, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_google))) 48 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 49 | .setBackgroundColor(0x60000000) 50 | .create(); 51 | 52 | share.setOnFlipClickListener(new FlipShareView.OnFlipClickListener() { 53 | @Override 54 | public void onItemClick(int position) { 55 | Toast.makeText(MainActivity.this, "position " + position + " is clicked.", Toast.LENGTH_SHORT).show(); 56 | } 57 | 58 | @Override 59 | public void dismiss() { 60 | 61 | } 62 | }); 63 | 64 | break; 65 | case R.id.btn_middle_top: 66 | 67 | new FlipShareView.Builder(this, mBtnMiddleTop) 68 | .addItem(new ShareItem("Facebook", Color.WHITE, 0xff43549C, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_facebook))) 69 | .addItem(new ShareItem("Wangyuwei", Color.WHITE, 0xff4999F0)) 70 | .addItem(new ShareItem("Wangyuweiwangyuwei", Color.WHITE, 0xffD9392D)) 71 | .addItem(new ShareItem("纯文字也可以", Color.WHITE, 0xff57708A)) 72 | .setAnimType(FlipShareView.TYPE_HORIZONTAL) 73 | .create(); 74 | break; 75 | case R.id.btn_right_top: 76 | new FlipShareView.Builder(this, mBtnRightTop) 77 | .addItem(new ShareItem("Facebook", Color.WHITE, 0xff43549C, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_facebook))) 78 | .addItem(new ShareItem("Twitter", Color.WHITE, 0xff4999F0, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_twitter))) 79 | .addItem(new ShareItem("Google+", Color.WHITE, 0xffD9392D, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_google))) 80 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 81 | .setItemDuration(500) 82 | .setBackgroundColor(0x60000000) 83 | .setAnimType(FlipShareView.TYPE_SLIDE) 84 | .create(); 85 | break; 86 | case R.id.btn_left_bottom: 87 | new FlipShareView.Builder(this, mBtnLeftBottom) 88 | .addItem(new ShareItem("Facebook")) 89 | .addItem(new ShareItem("Twitter")) 90 | .addItem(new ShareItem("Google+")) 91 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 92 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 93 | .setSeparateLineColor(0x30000000) 94 | .setAnimType(FlipShareView.TYPE_HORIZONTAL) 95 | .create(); 96 | break; 97 | case R.id.btn_middle_bottom: 98 | FlipShareView shareBottom = new FlipShareView.Builder(this, mBtnMiddleBottom) 99 | .addItem(new ShareItem("Facebook")) 100 | .addItem(new ShareItem("Twitter")) 101 | .addItem(new ShareItem("Google+")) 102 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 103 | .setSeparateLineColor(0x30000000) 104 | .setBackgroundColor(0x60000000) 105 | .setAnimType(FlipShareView.TYPE_SLIDE) 106 | .create(); 107 | shareBottom.setOnFlipClickListener(new FlipShareView.OnFlipClickListener() { 108 | @Override 109 | public void onItemClick(int position) { 110 | Toast.makeText(MainActivity.this, "position " + position + " is clicked.", Toast.LENGTH_SHORT).show(); 111 | } 112 | 113 | @Override 114 | public void dismiss() { 115 | 116 | } 117 | }); 118 | break; 119 | case R.id.btn_right_bottom: 120 | new FlipShareView.Builder(this, mBtnRightBottom) 121 | .addItem(new ShareItem("Facebook", Color.WHITE, 0xff43549C, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_facebook))) 122 | .addItem(new ShareItem("Twitter", Color.WHITE, 0xff4999F0, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_twitter))) 123 | .addItem(new ShareItem("Google+", Color.WHITE, 0xffD9392D, BitmapFactory.decodeResource(getResources(), R.mipmap.ic_google))) 124 | .addItem(new ShareItem("http://www.wangyuwei.me", Color.WHITE, 0xff57708A)) 125 | .create(); 126 | break; 127 | } 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 |