Skip to content

Commit a624437

Browse files
committed
Merge remote-tracking branch 'remotes/origin/dev'
2 parents c18558c + 90b3957 commit a624437

6 files changed

Lines changed: 81 additions & 54 deletions

File tree

README.md

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
### Captures
77
![效果图](/pic/002.png)
88
![效果图](/pic/pic001.jpeg)
9-
![效果图](/pic/demo20.gif)
109

10+
![效果图](/pic/demo20.gif)
1111
![尺寸说明](/pic/biaozhu.png)
1212

1313
<li>注释:此图解释参数意义,展示效果不太精确,图片真实宽度为**上层橙色**
1414

1515
### Use
16-
implementation 'com.uis:stacklayout:0.2.1'
16+
implementation 'com.uis:stacklayout:0.3.0'
1717

1818
*Name*| *Descript*|*Value*
1919
-----|--------|---
@@ -27,7 +27,7 @@ stackLooper|自动轮播|false/true
2727
stackSize|层叠数量|3
2828
stackEdgeModel|层叠位置|left/right
2929

30-
```Xml
30+
```
3131
<?xml version="1.0" encoding="utf-8"?>
3232
<com.uis.stackview.StackLayout xmlns:android="http://schemas.android.com/apk/res/android"
3333
xmlns:stack="http://schemas.android.com/apk/res-auto"
@@ -44,7 +44,7 @@ stackEdgeModel|层叠位置|left/right
4444
</com.uis.stackview.StackLayout>
4545
```
4646

47-
```Java
47+
```
4848
stackViewLayout.setStackLooper(true);
4949
stackViewLayout.setAdapter(new StackLayout.StackAdapter() {
5050
@Override
@@ -93,10 +93,8 @@ stackEdgeModel|层叠位置|left/right
9393
0.1.2|增加动画、轮播时间设置,获取当前选中位置|新增方法
9494
0.2.0|只有一个元素,不支持轮播和滑动|新增功能
9595
0.2.1|减少child层级,见child.measure()|新增功能
96+
0.3.0|增加联动效果(缩放+平移)|新增功能
9697

97-
### Thanks
98-
99-
[AndroidPileLayout](https://github.com/xmuSistone/AndroidPileLayout)
10098
### License
10199

102100
Copyright 2018, uis

build.gradle

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22

33
buildscript {
4+
45
repositories {
56
maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }
67
jcenter()
78
google()
89
}
10+
911
dependencies {
10-
classpath 'com.android.tools.build:gradle:3.2.1'
12+
classpath 'com.android.tools.build:gradle:3.4.2'
1113
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
1214
classpath 'com.github.dcendents:android-maven-gradle-plugin:2.1'
1315
}
@@ -27,4 +29,7 @@ task clean(type: Delete) {
2729

2830
ext{
2931
androidx = '1.0.0'
32+
compileVer = 28
33+
minVer = 15
34+
buildVer = '28.0.3'
3035
}

demo/build.gradle

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 28
5-
buildToolsVersion "28.0.3"
4+
compileSdkVersion compileVer
5+
buildToolsVersion buildVer
66
defaultConfig {
77
applicationId "com.uis.stackview.demo"
8-
minSdkVersion 14
9-
targetSdkVersion 28
8+
minSdkVersion minVer
9+
targetSdkVersion compileVer
1010
versionCode 1
1111
versionName "1.0"
1212
manifestPlaceholders = [

gradle/wrapper/gradle-wrapper.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
33
distributionPath=wrapper/dists
44
zipStoreBase=GRADLE_USER_HOME
55
zipStorePath=wrapper/dists
6-
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
6+
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-all.zip

stacklayout/build.gradle

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
apply plugin: 'com.android.library'
22

33
android {
4-
compileSdkVersion 28
5-
buildToolsVersion "28.0.3"
4+
compileSdkVersion compileVer
5+
buildToolsVersion buildVer
66

77
defaultConfig {
8-
minSdkVersion 14
9-
targetSdkVersion 28
8+
minSdkVersion minVer
9+
targetSdkVersion compileVer
1010
versionCode 1
1111
versionName "1.0"
1212
consumerProguardFiles 'proguard-rules.pro'
1313
}
14+
1415
buildTypes {
1516
release {
1617
minifyEnabled false
@@ -19,8 +20,4 @@ android {
1920
}
2021
}
2122

22-
dependencies {
23-
implementation fileTree(dir: 'libs', include: ['*.jar'])
24-
}
25-
2623
//apply from: '../../bintray.gradle'

stacklayout/src/main/java/com/uis/stackview/StackHelper.java

Lines changed: 60 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@
22

33
import android.animation.ValueAnimator;
44
import android.content.res.Resources;
5-
import android.os.Handler;
6-
import android.os.Looper;
75
import android.util.Log;
86
import android.view.View;
97
import android.view.animation.DecelerateInterpolator;
@@ -46,7 +44,6 @@ final class StackHelper implements ValueAnimator.AnimatorUpdateListener{
4644
private int mDuration = 500;
4745
private int mDelay = 3000;
4846
private StackLayout layout;
49-
private boolean debug = true;
5047

5148
StackHelper(int touchSlop) {
5249
mTouchSlop = touchSlop;
@@ -70,10 +67,10 @@ int getItemCount(){
7067

7168
void unbindLayout() {
7269
setAutoPlay(false);
70+
mAnimator.cancelAnimator();
7371
}
7472

7573
void measureChild(int width,int height){
76-
//log("measue...");
7774
if(getItemCount() > 0 ){
7875
int size = layout.getRealStackSize();
7976
if(originX.isEmpty()) {
@@ -107,12 +104,11 @@ void measureChild(int width,int height){
107104
}
108105

109106
void layoutChild(){
110-
//log("layout..."+layout.getChildCount());
111107
if(needRelayout && layout != null) {
112108
needRelayout = false;
113109
int childSize = layout.getChildCount();
114110
int stackSize = layout.getRealStackSize();
115-
int realSize = layout.getRealStackSize();
111+
116112
for (int i = 0; i < childSize; i++) {
117113
int top, bottom, left, right, pivot;
118114
View view = layout.getChildAt(i);
@@ -130,16 +126,13 @@ void layoutChild(){
130126
pivot = layout.getWidth() - layout.stackEdge;
131127
}
132128
view.setPivotX(pivot);
133-
view.setPivotY(everyHeight / 2);
134-
view.layout(left, top, right, bottom);
135-
view.setScaleY((float) Math.pow(layout.stackZoomY,realSize-1-i));
136-
if(view.getTranslationX() != 0f){
137-
if(i+1 < stackSize){
138-
view.setTranslationX(0);
139-
}else if(i+1 == stackSize && childSize == stackSize){//恢复stackSize时,补偿距离
140-
float distance = layout.stackEdgeModel == MODEL_RIGHT ? -everyWidth : everyWidth;
141-
view.setTranslationX(view.getTranslationX()+distance);
142-
}
129+
view.setPivotY(everyHeight/2f);
130+
if(mAnimator.isRunning() && i > 0){
131+
132+
}else{
133+
view.layout(left, top, right, bottom);
134+
view.setScaleY((float) Math.pow(layout.stackZoomY,stackSize-1-i));
135+
view.setTranslationX(0);
143136
}
144137
}else if(!isTopRemove){//顶层加入
145138
if (layout.stackEdgeModel == MODEL_LEFT) {
@@ -263,6 +256,24 @@ void executeScroll(int dx) {
263256
view = mAnimator.mAnimatorView;
264257
}
265258
view.setTranslationX(view.getTranslationX() + 1.0f*everyWidth/layout.getWidth() * dx);
259+
scaleTransChild(dx);
260+
}
261+
}
262+
263+
void scaleTransChild(int dx){
264+
int first = layout.getChildCount()>layout.stackSize ? 1 : 0;
265+
int size = layout.getChildCount()-1;
266+
int stackSize = layout.stackSize;
267+
for(int i = first; i<size; i++){
268+
View v = layout.getChildAt(i);
269+
int sign = MODEL_LEFT == layout.stackEdgeModel ? 1 : -1;
270+
float rate = 1f*dx/layout.getWidth();
271+
int tx = originX.get(i-first+1)-originX.get(i-first);
272+
v.setTranslationX(v.getTranslationX() + rate*tx);
273+
274+
double scaley = Math.pow(layout.stackZoomY,stackSize-2-i);
275+
double scale = Math.pow(layout.stackZoomY,stackSize-1-i);
276+
v.setScaleY(v.getScaleY()+(float)(sign*rate*(scaley-scale)));
266277
}
267278
}
268279

@@ -307,7 +318,7 @@ void autoScroll(){
307318
void setAutoPlay(boolean looper){
308319
if(looper) {
309320
if(executor == null || executor.isShutdown()){
310-
executor = new ScheduledThreadPoolExecutor(2);
321+
executor = new ScheduledThreadPoolExecutor(1);
311322
}
312323
if(executor.getQueue().size() <= 0 && getItemCount() > 1) {
313324
executor.scheduleWithFixedDelay(new AutoRunnable(this), 2000, mDelay, TimeUnit.MILLISECONDS);
@@ -316,6 +327,7 @@ void setAutoPlay(boolean looper){
316327
if(executor != null && !executor.isShutdown()) {
317328
executor.shutdownNow();
318329
}
330+
319331
}
320332
}
321333

@@ -354,7 +366,7 @@ private void removeBottomView(){
354366
if(displayPosition < 0){
355367
displayPosition += cnt;
356368
}
357-
needRelayout = true;
369+
//needRelayout = true;
358370
View view = layout.getChildAt(0);
359371
removeStackView(view);
360372
layout.getAdapter().onItemDisplay(displayPosition);
@@ -363,10 +375,15 @@ private void removeBottomView(){
363375
@Override
364376
public void onAnimationUpdate(ValueAnimator animation) {
365377
float animateValue = (float) animation.getAnimatedValue();
378+
float lastValue = mAnimator.getTranslationX();
366379
float fraction = animation.getAnimatedFraction();
367380
mAnimator.setTranslationX(animateValue);
381+
scaleTransChild((int)(mAnimator.getTranslationX()-lastValue));
368382
if (fraction >= 1.0f) {
369383
mAnimator.endAnimator(this);
384+
needRelayout = true;
385+
layout.requestLayout();
386+
370387
} else if(fraction > 0.2 && mAnimator.needAddBottomView()){
371388
addBottomView();
372389
}
@@ -429,8 +446,16 @@ void startAnimator(boolean needRemoveTop,boolean needAddBottom,float transX, Val
429446
animator.start();
430447
}
431448

449+
void cancelAnimator(){
450+
if(animator != null){
451+
animator.removeAllUpdateListeners();
452+
animator.cancel();
453+
endAnimator(null);
454+
}
455+
}
456+
432457
void endAnimator(StackHelper helper){
433-
if(needRemoveTopView) {
458+
if(needRemoveTopView && helper != null) {
434459
helper.removeStackView(mAnimatorView);
435460
}
436461
animator.removeAllUpdateListeners();
@@ -442,22 +467,26 @@ void endAnimator(StackHelper helper){
442467
}
443468

444469
static class AutoRunnable implements Runnable{
445-
static Handler mHandler = new Handler(Looper.getMainLooper());
446-
StackHelper helper;
470+
WeakReference<StackHelper> weakHelper;
447471

448472
AutoRunnable(StackHelper stack) {
449-
this.helper = stack;
473+
weakHelper = new WeakReference<>(stack);
450474
}
451475

452476
@Override
453477
public void run() {
454-
if(helper.getItemCount() > 1 && helper.layout.getChildCount() > 0){
455-
final StackLayout stack = helper.layout;
456-
int[] points = new int[2];
457-
stack.getLocationInWindow(points);
458-
if(points[1] < Resources.getSystem().getDisplayMetrics().heightPixels){
459-
mHandler.post(new AutoScrollRunnable(helper));
478+
try {
479+
StackHelper helper = weakHelper.get();
480+
if (helper != null && helper.getItemCount() > 1 && helper.layout.getChildCount() > 0) {
481+
StackLayout stack = helper.layout;
482+
int[] points = new int[2];
483+
stack.getLocationInWindow(points);
484+
if (points[1] < Resources.getSystem().getDisplayMetrics().heightPixels) {
485+
stack.getHandler().post(new AutoScrollRunnable(helper));
486+
}
460487
}
488+
}catch (Throwable ex){
489+
ex.printStackTrace();
461490
}
462491
}
463492
}
@@ -488,10 +517,8 @@ boolean filterClick(){
488517
}
489518

490519
void log(String msg){
491-
if(debug) {
492-
StackTraceElement element = Thread.currentThread().getStackTrace()[3];
493-
Log.e("StackLayout", String.format("%1$s:%2$s(%3$s):%4$s", element.getClassName(),
494-
element.getMethodName(), element.getLineNumber(), msg));
495-
}
520+
StackTraceElement element = Thread.currentThread().getStackTrace()[3];
521+
Log.e("StackLayout", String.format("%1$s:%2$s(%3$s):%4$s", element.getClassName(),
522+
element.getMethodName(), element.getLineNumber(), msg));
496523
}
497524
}

0 commit comments

Comments
 (0)